点击(此处)折叠或打开
- int tagBITM::dajin( uint8_t pe[],int t,long *pg1 )//大津法取阈值,pe为传入的保存有像素值的数组,pg1用来记录直方图分布曲线
- {
- int i, j, p ;
- long pg[257]; //保存每种像素的点数
- 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;
- for(i = 0; i < t - 1; i++)
- {
- pg[pe[i]]++; //计算每个像素点的个数
- }
- An = Bn = 0;
- for( i = 1; i < 256; i++)
- {
- An += pg[i];
- Bn += (pg[i] * i);
- }
-
- for(j = 0; j < 256; j++)
- {
- A = B = 0;
- for( i = 0 ; i <= j ; i++)
- {
- A += pg[i];
- B += (pg[i] * i);
- }
- if( A )
- u = B / A;
- else
- u = 0;
- if( (An - A) )
- v = ( Bn - B) / ( An - A );
- else
- v = 0;
- qqq[j] = A * ( An -A ) * ( u - v ) * ( u - v ); //计算类间方差
- }
- max = min = qqq[0];
- p = 0;
- for( i = 1; i < 256; i++) //寻找判别函数最大值
- {
- if( qqq[i] > max )
- {
- max = qqq[i];
- p = i;
- }
- else if( qqq[i] < min)
- {
- min = qqq[i] ;
- }
- }
- cout<<"**** p"<<p<<endl;
- if( pg1 != 0)
- {
- for(i = 0 ; i < 256; i++)
- {
- pg1[i] = (long)(120 *(qqq[i] - min)/(max - min)); //判别函数坐标度转换
- }
- }
-
- return p; //取判别函数最大值的灰度为器阈值
- }
- 大津法所算的阈值不一定准确,所以说,算法有时也是不灵的..........
- //中值滤波求中值函数
- uint8_t medvalue(uint8_t buf[], int n, int m)
- {
- int i,j, k, f;
- for( i = 1; i < n; i++)
- {
- for(j = n-1, f = 0; j >= i; j--)
- {
- if( buf[j] > buf[j-1])
- {
- k = buf[i];
- buf[j] = buf[j-1];
- buf[j-1] = k;
- f = 1;
- }
- }
- if( f == 0 )
- break;
- }
- return (buf[m]);
- }
- //中值滤波去噪点
- int tagBITM::median( char image_name[]) //传入的是图片的名字
- {
- FILE *fp;
- int i, j, flag = 9, n;
- uint8_t list1[30][72] ,list0[30][72]; //30,70是图片的高度和宽度,70+2是因为,bmp图像每行字节数是4的倍数,不足会补零,
- uint8_t a[2], buff1[9];
- fp = fopen(image_name,"rb+");
- if( fp == NULL )
- {
- cout<<"图片打开失败!\n";
- return 1;
- }
- fseek(fp, 54, 0);
- for( i = 0; i < biheight; i++)
- {
- for(j = 0; j < biwidth; j++)
- {
- fread(&list1[i][j],1,1,fp);
- fseek(fp,2,SEEK_CUR);
- }
- if( (biwidth * 3 % 4) != 0)
- {
- fread(&a, 1, 2, fp);
- list1[i][j++] = a[0];
- list1[i][j] = a[1];
- }
- }
- for( i = 1; i < biheight-1; i++)
- {
- for(j = 1; j < biwidth-1;j++)
- {
- buff1[0] = list1[i-1][j];
- buff1[1] = list1[i][j];
- buff1[2] = list1[i+1][j];
- buff1[3] = list1[i][j-1];
- buff1[4] = list1[i][j+1];
- buff1[5] = list1[i-1][j-1];
- buff1[6] = list1[i-1][j+1];
- buff1[7] = list1[i+1][j-1];
- buff1[8] = list1[i+1][j+1];
-
- list0[i][j] = (uint8_t)medvalue(buff1, flag, flag/2); //函数调用
- }
- }
- for(i = 0; i < biwidth; i++)
- {
- list0[0][i] = list1[0][i];
- list0[biheight-1][i] = list1[biheight-1][i];
- }
- for(i = 0; i < biheight; i++)
- {
- list0[i][0] = list1[i][0];
- list0[i][biwidth-1] = list1[i][biwidth-1];
- list0[i][biwidth] = list1[i][biwidth];
- list0[i][biwidth+1] = list1[i][biwidth+1];
- }
-
- fseek(fp , 54, 0);
- for( i = 0; i < biheight; i++)
- {
- for( j = 0; j < biwidth; j++)
- {
- for(n = 0; n < 3; n++)
- {
- fwrite(&list0[i][j],1,1,fp);
- }
- // printf("i %d j %d %x **", i ,j ,list0[i][j] );
- }
- fwrite(&list0[i][j++], 1, 1, fp);
- fwrite(&list0[i][j], 1, 1, fp);
- }
-
- fclose(fp);
- return 0;
- }
- 中值滤波算法可不是盖的。。。。。
- //二值化
- int tagBITM::binary( char image_name[], int p , uint8_t list[][weight] ) //传入图片名,阈值,空的数组,用来带回二值化后的像素值
- {
- FILE *fp;
- int i, j, k = 0, n = 0;
- int num = 0 ;
-
- uint8_t a[2], *pext;
- fp = fopen(image_name, "rb+");
-
- if( fp == NULL )
- {
- cout<<"图片二值化失败!\n";
- return 1;
- }
- num = biwidth * biheight * 3 + 60;
- cout<<"num** = "<<num<<endl;
- pext = new uint8_t [num]; //记录各像素转化后的灰度值
-
- fseek(fp, 54 ,0);
- for( i = 0 ; i < biheight; i++) //二值化过程
- {
- for(j = 0; j < biwidth; j++ )
- {
- fread(&b,1,1,fp); //读把b像素单元
- fseek(fp, 2, SEEK_CUR); //跳过g,r像素
- for( n = 0; n < 3; n++) //循环3遍是因为灰度化后,每个像素的b,g,r相等。
- {
- if( b >= p )
- pext[k++] = 255 ;
- else
- {
- pext[k++] = 0;
- }
- }
- list[i][j] = pext[k-1];
- }
- if( biwidth * 3 % 4 != 0)
- {
- fread(&a, 1, 2, fp);
- pext[k++] = a[0];
- list[i][j++] = a[0];
- pext[k++] = a[1];
- list[i][j] = a[1];
- }
- }
- fseek( fp, 54, 0);
- for(i = 0; i < biheight; i++)
- fwrite( pext,1,k-1,fp);
- fclose(fp);
-
- delete [] pext;
- return 0;
- }
- //线条细化
- int tagBITM::hildich(char image_name[],uint8_t list0[][72]) //传入图片名,二值化带出的像素矩阵
- {
- int i, k , j, m, n, flag;
- FILE *fp;
- int sum = 0, f[10];
- uint8_t list[30][70], b;
- fp = fopen(image_name, "rb+");
- if( fp == NULL)
- {
- cout<<"图片打开失败!\n";
- exit(1);
- }
- for( i = 0; i < biheight; i++)
- for( j = 0; j < biwidth; j++)
- {
- fread(&b, 1,1,fp);
- fseek(fp, 2, SEEK_CUR);
- if( b == 0 )
- {
- list[i][j] = 1;
- }
- else
- list[i][j] = 0;
- }
- i = 1;
- do
- {
- flag = 0;
- for( k = 1; k < biheight - 1; k++)
- {
- for(j = 1; j < biwidth - 1; j++)
- {
- if( list[k][j] != 1 )
- continue;
- f[1] = list[k][j+1];
- f[2] = list[k-1][j+1];
- f[3] = list[k-1][j];
- f[4] = list[k-1][j-1];
- f[5] = list[k][j-1];
- f[6] = list[k+1][j-1];
- f[7] = list[k+1][j];
- f[8] = list[k+1][j+1];
-
- for(m = 1, n = 0; m <= 8; m++)
- {
- if( f[m] == -i ) //此点是在同一大循环中清除的
- {
- f[m] = 1; //计算中恢复原值
- n++; //记下此类点的点数
- }
- else if( f[m] < 0 )
- f[m] = 0; //此点已在前面处理中清除
- }
- sum = f[1] + f[3] + f[5] + f[7] ; //计算4邻点中的1的点数
- if( sum >= 4)
- continue; //4邻点全为1是不能去除
- f[9] = f[1];
- for( m = 1,sum = 0; m <= 8; m++)
- if( f[m] == 1)
- sum++;
- if( (sum <= 1) || (sum-n == 0))
- continue; //是孤立点,不能去除
- sum = cross( f );
- if( sum != 1)
- continue;
- if( list[k-1][j] == -i)
- {
- f[3] = 0;
- sum = cross(f);
- if( sum != 1)
- continue;
- }
- if( list[k][j-1] == -i)
- {
- f[5] = 0;
- sum = cross(f);
- if( sum != 1)
- continue;
- }
- list0[j][k] = 255;
- list[k][j] = -i;
- flag = 1;
- }
- }
- i++;
- }while( flag == 1);
- fseek(fp, 54, 0);
- for(i = 0; i < biheight; i++)
- {
- for( j = 0; j < biwidth; j++)
- {
- for(n = 0; n < 3; n++)
- {
- fwrite(&list0[i][j],1,1,fp);
- }
- }
- fwrite(&list0[i][j++], 1, 1, fp);
- fwrite(&list0[i][j], 1, 1, fp);
- }
-
- fclose(fp);
- return 0;
- }
相关热门文章
评论热议