Chinaunix首页 | 论坛 | 博客
  • 博客访问: 109309
  • 博文数量: 16
  • 博客积分: 55
  • 博客等级: 民兵
  • 技术积分: 235
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-25 21:49
个人简介

我的观点,您的建议!如有问题,敬请留言!

文章存档

2013年(12)

2012年(4)

我的朋友

分类: C/C++

2012-11-28 21:14:19

点击(此处)折叠或打开

  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. }



阅读(1459) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~