验证码识别部分代码(三)

来源:互联网 发布:京东怎么做淘宝客 编辑:程序博客网 时间:2024/06/05 14:51

点击(此处)折叠或打开

  1. int tagBITM::dajin( uint8_t pe[],int t,long *pg1)//大津法取阈值,pe为传入的保存有像素值的数组,pg1用来记录直方图分布曲线
  2. {
  3.     int i, j, p;
  4.     long pg[257];//保存每种像素的点数
  5.     double A = 0.0, An= 0.0 ,B = 0.0, Bn= 0.0, u= 0.0, v= 0.0, qqq[256], max = 0.0, min= 0.0;

  6.     for(i= 0; i < t - 1; i++)
  7.     {
  8.         pg[pe[i]]++;//计算每个像素点的个数
  9.     }


  10.     An = Bn = 0;
  11.     for( i= 1; i < 256; i++)
  12.     {
  13.         An += pg[i];
  14.         Bn +=(pg[i]* i);
  15.     }
  16.     

  17.     for(j= 0; j < 256; j++)
  18.     {

  19.         A = B = 0;
  20.         for( i= 0 ; i <= j ; i++)
  21.         {
  22.             A += pg[i];
  23.             B +=(pg[i]* i);
  24.         }
  25.         if( A)
  26.             u = B / A;
  27.         else
  28.             u = 0;
  29.         if((An - A))
  30.             v = ( Bn - B)/ ( An - A );
  31.         else
  32.             v = 0;
  33.         qqq[j]= A * ( An -A )* ( u - v ) *( u - v ); //计算类间方差
  34.     }

  35.     max = min = qqq[0];
  36.     p = 0;
  37.     for( i= 1; i < 256; i++)//寻找判别函数最大值
  38.     {
  39.         if( qqq[i]> max )
  40.         {
  41.             max = qqq[i];
  42.             p = i;
  43.         }
  44.         else if( qqq[i]< min)
  45.         {
  46.             min = qqq[i];
  47.         }
  48.     }
  49.         cout<<"**** p"<<p<<endl;
  50.     if( pg1!= 0)
  51.     {
  52.         for(i= 0 ; i < 256; i++)
  53.         {
  54.             pg1[i]= (long)(120*(qqq[i]- min)/(max- min));//判别函数坐标度转换
  55.         }
  56.     }
  57.         
  58.     return p; //取判别函数最大值的灰度为器阈值
  59. }
  60. 大津法所算的阈值不一定准确,所以说,算法有时也是不灵的..........

  61. //中值滤波求中值函数
  62. uint8_t medvalue(uint8_t buf[],int n, int m)
  63. {
  64.     int i,j, k, f;

  65.     for( i= 1; i < n; i++)
  66.     {
  67.         for(j= n-1, f= 0; j >= i; j--)
  68.         {
  69.             if( buf[j]> buf[j-1])
  70.             {
  71.                 k = buf[i];
  72.                 buf[j]= buf[j-1];
  73.                 buf[j-1]= k;
  74.                 f = 1;
  75.             }
  76.         }
  77.         if( f== 0 )
  78.             break;
  79.     }

  80.     return (buf[m]);
  81. }
  82. //中值滤波去噪点
  83. int tagBITM::median( char image_name[])//传入的是图片的名字
  84. {
  85.     FILE *fp;
  86.     int i, j, flag= 9, n;
  87.     uint8_t list1[30][72],list0[30][72];//30,70是图片的高度和宽度,70+2是因为,bmp图像每行字节数是4的倍数,不足会补零,
  88.     uint8_t a[2], buff1[9];

  89.     fp = fopen(image_name,"rb+");
  90.     if( fp== NULL )
  91.     {
  92.         cout<<"图片打开失败!\n";
  93.         return 1;
  94.     }


  95.     fseek(fp, 54, 0);
  96.     for( i= 0; i < biheight; i++)
  97.     {
  98.         for(j= 0; j < biwidth; j++)
  99.         {
  100.             fread(&list1[i][j],1,1,fp);
  101.             fseek(fp,2,SEEK_CUR);
  102.         }
  103.             if((biwidth * 3% 4) != 0)
  104.             {
  105.                 fread(&a, 1, 2, fp);
  106.                 list1[i][j++]= a[0];
  107.                 list1[i][j]= a[1];
  108.             }
  109.     }

  110.     for( i= 1; i < biheight-1; i++)
  111.     {
  112.         for(j= 1; j < biwidth-1;j++)
  113.         {
  114.             buff1[0]= list1[i-1][j];
  115.             buff1[1]= list1[i][j];
  116.             buff1[2]= list1[i+1][j];
  117.             buff1[3]= list1[i][j-1];
  118.             buff1[4]= list1[i][j+1];
  119.             buff1[5]= list1[i-1][j-1];
  120.             buff1[6]= list1[i-1][j+1];
  121.             buff1[7]= list1[i+1][j-1];
  122.             buff1[8]= list1[i+1][j+1];
  123.         
  124.         list0[i][j]= (uint8_t)medvalue(buff1, flag, flag/2);//函数调用
  125.         }
  126.     }
  127.     for(i= 0; i < biwidth; i++)
  128.     {
  129.         list0[0][i]= list1[0][i];
  130.         list0[biheight-1][i]= list1[biheight-1][i];
  131.     }
  132.     for(i= 0; i < biheight; i++)
  133.     {
  134.         list0[i][0]= list1[i][0];
  135.         list0[i][biwidth-1]= list1[i][biwidth-1];
  136.         list0[i][biwidth]= list1[i][biwidth];
  137.         list0[i][biwidth+1]= list1[i][biwidth+1];
  138.     }
  139.     
  140.     fseek(fp , 54, 0);
  141.     for( i= 0; i < biheight; i++)
  142.     {
  143.         for( j= 0; j < biwidth; j++)
  144.         {
  145.             for(n= 0; n < 3; n++)
  146.             {
  147.                 fwrite(&list0[i][j],1,1,fp);
  148.             }
  149.             //    printf("i %d j %d %x **", i,j ,list0[i][j]);
  150.         }
  151.         fwrite(&list0[i][j++], 1, 1, fp);
  152.         fwrite(&list0[i][j], 1, 1, fp);
  153.     }
  154.     
  155.     fclose(fp);

  156.         return 0;

  157. }
  158. 中值滤波算法可不是盖的。。。。。

  159. //二值化
  160. int tagBITM::binary( char image_name[],int p , uint8_t list[][weight]) //传入图片名,阈值,空的数组,用来带回二值化后的像素值
  161. {    
  162.     FILE *fp;
  163.     int i, j, k= 0, n = 0;
  164.     int num = 0;
  165.      
  166.     uint8_t a[2],*pext;

  167.     fp = fopen(image_name,"rb+");
  168.     
  169.     if( fp== NULL )
  170.     {
  171.         cout<<"图片二值化失败!\n";
  172.         return 1;
  173.     }

  174.     num = biwidth * biheight * 3 + 60;
  175.     cout<<"num** = "<<num<<endl;
  176.     pext = new uint8_t [num];//记录各像素转化后的灰度值    
  177.     
  178.     fseek(fp, 54,0);

  179.     for( i= 0 ; i < biheight; i++)//二值化过程
  180.     {
  181.         for(j= 0; j < biwidth; j++)
  182.         {
  183.             fread(&b,1,1,fp);//读把b像素单元
  184.             fseek(fp, 2, SEEK_CUR);//跳过g,r像素
  185.             for( n= 0; n < 3; n++)//循环3遍是因为灰度化后,每个像素的b,g,r相等。
  186.             {
  187.                 if( b>= p )
  188.                     pext[k++]= 255 ;
  189.                 else
  190.                 {
  191.                     pext[k++]= 0;
  192.                 }
  193.             }
  194.             list[i][j]= pext[k-1];
  195.         }
  196.         if( biwidth* 3 % 4 != 0)
  197.         {
  198.             fread(&a, 1, 2, fp);
  199.             pext[k++]= a[0];
  200.             list[i][j++]= a[0];
  201.             pext[k++]= a[1];
  202.             list[i][j]= a[1];
  203.         }
  204.     }

  205.     fseek( fp, 54, 0);
  206.     for(i= 0; i < biheight; i++)
  207.         fwrite( pext,1,k-1,fp);                        
  208.             fclose(fp);
  209.             
  210.             delete [] pext;
  211.             return 0;
  212. }

  213. //线条细化
  214. int tagBITM::hildich(char image_name[],uint8_t list0[][72])//传入图片名,二值化带出的像素矩阵
  215. {
  216.     int i, k, j, m, n, flag;
  217.     FILE *fp;
  218.     int sum = 0, f[10];
  219.     uint8_t list[30][70], b;


  220.     fp = fopen(image_name,"rb+");
  221.     if( fp== NULL)
  222.     {
  223.         cout<<"图片打开失败!\n";
  224.         exit(1);
  225.     }
  226.     for( i= 0; i < biheight; i++)
  227.         for( j= 0; j < biwidth; j++)
  228.         {
  229.             fread(&b, 1,1,fp);
  230.             fseek(fp, 2, SEEK_CUR);
  231.             if( b== 0 )
  232.             {
  233.                 list[i][j]= 1;
  234.             }
  235.             else
  236.                 list[i][j]= 0;
  237.         }

  238.     i = 1;
  239.     do
  240.     {
  241.         flag = 0;
  242.         for( k= 1; k < biheight - 1; k++)
  243.         {
  244.             for(j= 1; j < biwidth - 1; j++)
  245.             {
  246.                 if( list[k][j]!= 1 )
  247.                     continue;
  248.                 f[1]= list[k][j+1];
  249.                 f[2]= list[k-1][j+1];
  250.                 f[3]= list[k-1][j];
  251.                 f[4]= list[k-1][j-1];
  252.                 f[5]= list[k][j-1];
  253.                 f[6]= list[k+1][j-1];
  254.                 f[7]= list[k+1][j];
  255.                 f[8]= list[k+1][j+1];
  256.                 
  257.                 for(m= 1, n = 0; m <= 8; m++)
  258.                 {
  259.                     if( f[m]== -i ) //此点是在同一大循环中清除的
  260.                     {
  261.                         f[m]= 1; //计算中恢复原值
  262.                         n++;//记下此类点的点数
  263.                     }
  264.                     else if( f[m]< 0 )
  265.                         f[m]= 0; //此点已在前面处理中清除
  266.                 }
  267.                 sum = f[1]+ f[3]+ f[5]+ f[7]; //计算4邻点中的1的点数
  268.                 if( sum>= 4)
  269.                     continue; //4邻点全为1是不能去除

  270.                 f[9]= f[1];
  271.                 for( m= 1,sum = 0; m <= 8; m++)
  272.                     if( f[m]== 1)
  273.                         sum++;
  274.                 if((sum <= 1)|| (sum-n == 0))
  275.                     continue; //是孤立点,不能去除

  276.                 sum = cross( f);
  277.                 if( sum!= 1)
  278.                     continue;
  279.                 if( list[k-1][j]== -i)
  280.                 {
  281.                     f[3]= 0;
  282.                     sum = cross(f);
  283.                     if( sum!= 1)
  284.                         continue;
  285.                 }
  286.                 if( list[k][j-1]== -i)
  287.                 {
  288.                     f[5]= 0;
  289.                     sum = cross(f);
  290.                     if( sum!= 1)
  291.                         continue;
  292.                 }
  293.                 list0[j][k]= 255;
  294.                 list[k][j]= -i;
  295.                 flag = 1;
  296.             }
  297.         }
  298.         i++;
  299.     }while( flag== 1);

  300.     fseek(fp, 54, 0);
  301.     for(i= 0; i < biheight; i++)
  302.     {
  303.         for( j= 0; j < biwidth; j++)
  304.         {    
  305.             for(n= 0; n < 3; n++)
  306.             {
  307.                 fwrite(&list0[i][j],1,1,fp);
  308.             }
  309.         }
  310.         fwrite(&list0[i][j++], 1, 1, fp);
  311.         fwrite(&list0[i][j], 1, 1, fp);
  312.     }
  313.     
  314.     fclose(fp);

  315.     return 0;
  316. }



阅读(218) | 评论(0) | 转发(0) |
0

上一篇:验证码识别过程

下一篇:java用RandomAccessFile实现多线程下载

相关热门文章
  • 修改hostname后,db2 无法启动...
  • linux_3.0.1分析1--模块加载...
  • kthreadd 分析
  • 扩展easyui 的表单验证
  • 自动创建WordPress管理员账号...
  • test123
  • 编写安全代码——小心有符号数...
  • 使用openssl api进行加密解密...
  • 一段自己打印自己的c程序...
  • sql relay的c++接口
  • 那一台服务器也没5T的存储空间...
  • 公司有5T的数据用于下载,数据...
  • CACTI监控ESXI中的虚拟机,监...
  • 如何挂载一块以前做过LVM的硬...
  • 做主主同步,只同步个别的几张...
评论热议
原创粉丝点击