网站验证码破解之阈值分割改进算法,此分割算法非常有用

 

#include"stdio.h"
#include"stdlib.h"
#include"time.h"
#include"math.h"

/*宏定义*/
#define height 301     //矩阵的行
#define wide   301      //矩阵的列
#define L      256     //灰度级



/*全局变量*/
int graymatrix[height][wide];
double grayrate[L];
int    index[height*wide];    //记录分割后的索引
//int    aopt;
//int    copt;      //记录最优的模糊参数
double Topt;      //记录最优阈值
/*子函数部分*/

/*读入图像的灰度值*/
void readgray()
{
    int i,j;
    FILE *fp1=fopen("mydata.txt","r");       //读入文件中要处理的数据
    if(fp1==NULL)
    {
        printf("can not open file\n");
        exit(0);
    }
    for(i=0;i<height;i++)
    {    for(j=0;j<wide;j++)
        {
            fscanf(fp1,"%d",&graymatrix[i][j]);
        //    printf("%d  ",graymatrix[i][j]);
        }
    }
    fclose(fp1);
}

/*图像的灰度直方图*/
void grayzhifang()
{
    int i,j,p;
    double sum=0;
    int num[L]={0};
    //double grayrate[L]={0};
    for(i=0;i<height;i++)
    {
        for(j=0;j<wide;j++)
        {
            for(p=0;p<L;p++)
            {
                if(graymatrix[i][j]==p)
                    num[p]++;
            }
        }
    }
    for(i=0;i<L;i++)
    {    grayrate[i]=num[i]/double(height*wide);    //求出每个灰度的比例及灰度直方图
        sum+=grayrate[i];
        //printf("%lf  ",grayrate[i]);
    }
    printf("sum=%lf \n",sum);       //判断一下概率和是否为1
}

/*大津法求出最佳阈值*/
void Ostu()
{
    int i,j,k;
    double w0=0,w1=0,p0=0,p1=0,p=0;
    double T=0;    //记录阈值
    double Tmax=-100;
    for(k=0;k<L;k++)
    {
        w0=0,w1=0,p0=0,p1=0,p=0;
        for(i=0;i<k;i++)
            w0+=grayrate[i];       //目标区域比例
        for(j=k;j<L;j++)
            w1+=grayrate[j];       //背景区域比例
        for(i=0;i<k;i++)
            p0+=i*grayrate[i];
        if(w0==0)
            p0=0;
        else
            p0=p0/w0;                  //目标均值
        for(j=k;j<L;j++)
            p1+=j*grayrate[j];
        if(w1==0)
            p1=0;
        else
           p1=p1/w1;                  //背景均值
        p=w0*p0+w1*p1;             //总均值
        T=w0*(p0-p)*(p0-p)+w1*(p1-p)*(p1-p);     //计算阈值
        if(Tmax<T)
        {
            Tmax=T;
            Topt=k;
        }

    }
}

/*刘忠良改进的大津法*/
void liuzhongliang()
{
    int i,j,k;
    double w0=0,w1=0,p0=0,p1=0,p=0,q0=0,q1=0,q=0;
    double T=0;    //记录阈值
    double Tmax=-100;
    for(k=0;k<L;k++)
    {
        w0=0,w1=0,p0=0,p1=0,p=0,q0=0,q1=0,q=0;
        for(i=0;i<k;i++)
            w0+=grayrate[i];       //目标区域比例
        for(j=k;j<L;j++)
            w1+=grayrate[j];       //背景区域比例
        for(i=0;i<k;i++)
            p0+=i*grayrate[i];
        if(w0==0)
            p0=0;
        else
            p0=p0/w0;                  //目标均值
        for(j=k;j<L;j++)
            p1+=j*grayrate[j];
        if(w1==0)
            p1=0;
        else
           p1=p1/w1;                  //背景均值
        p=w0*p0+w1*p1;             //总均值
        for(i=0;i<k+1;i++)
            q0+=(i-p0)*(i-p0)*grayrate[i];
        if(w0==0)
            q0=0;
        else
            q0=q0/w0;
        for(j=k+1;j<L;j++)
            q1+=(j-p1)*(j-p1)*grayrate[j];
        if(w1==0)
            q1=0;
        else
            q1=q1/w1;
        for(i=0;i<L;i++)
            q+=(i-p)*(i-p)*grayrate[i];

        T=(q0-q)*(q0-q)*(q1-q)*(q1-q)/(w0*q0+w1*q1);     //计算阈值
        if(Tmax<T)
        {
            Tmax=T;
            Topt=k;
        }
    }
}
/*根据最优阈值对图像进行分割,并记录分割结果*/
void segmentationres()
{
    int i,j;
    for(i=0;i<height;i++)
        for(j=0;j<wide;j++)
        {
            if(graymatrix[i][j]<=Topt)
                index[i*wide+j]=0;
            else
                index[i*wide+j]=1;
        }
}

/*将最终结果存放到文件中*/
void result()
{
    int i,j;
    FILE* fp2=fopen("outdata.txt","w");

    if(fp2==NULL)
    {
        printf("can not open file\n");
        exit(0);
    }
    for(i=0;i<height;i++)
    {   
        for(j=0;j<wide;j++)
        fprintf(fp2,"%d  ",index[i*wide+j]);
        fprintf(fp2,"\n");
    }
   
    fclose(fp2);
}

/*主函数,使用Ostu阈值法对图像进行分割*/
void main()
{
    clock_t begin,end;    //计算程序运行的时间
    double cost;
    begin=clock();      //开始计时
    readgray();               /*读入图像的灰度值*/
    grayzhifang();            /*图像的灰度直方图*/
    //Ostu();                   /*大津法求出最佳阈值*/
    liuzhongliang();          /*刘忠良改进的大津法*/
    segmentationres();        /*根据最优阈值对图像进行分割,并记录分割结果*/
    result();                 /*将最终结果存放到文件中*/
    end=clock();
    cost=(double)(end-begin);       //程序所运行的时间
    printf("该程序一共运行了%lf毫秒\n",cost);
}

 

您的回应...