标签:
void CopencvDlg::threshold(IplImage *src,IplImage*temp_src){ int thresol[8];//图像分成8部分,各部分的阈值 int height=src->height; int width=src->width; int ceil_height=height/4; int ceil_width=width/2; IplImage*srcdst=cvCreateImage(cvSize(ceil_width,ceil_height),IPL_DEPTH_8U,src->nChannels); for (int i=0;i<2;i++) { for (int j=0;j<4;j++) { cvSetImageROI(src ,cvRect(i*ceil_width,j*ceil_height,ceil_width,ceil_height));//选定各个区域 cvCopy(src,srcdst,0); cvResetImageROI(src); thresol[i*4+j]=Otsu(srcdst);//otsu阈值分割,返回值为各部分的阈值 } } cvSet(temp_src,cvScalarAll(0),0); int step=src->widthStep; uchar* data_src=(uchar *)src->imageData; uchar* data_dst=(uchar *)temp_src->imageData; //根据计算的阈值对图像进行二值化 for (int t=0;t<4;t++) { for (int i=0;i<ceil_width;i++) { for (int j=0;j<ceil_height;j++) { if (data_src[j*step+t*ceil_height*step+i]>thresol[t]) { data_dst[j*step+t*ceil_height*step+i]=255; } else data_dst[j*step+t*ceil_height*step+i]=0; } } } for (int t=0;t<4;t++) { for (int i=0;i<ceil_width;i++) { for (int j=0;j<ceil_height;j++) { if (data_src[j*step+t*ceil_height*step+i+ceil_width]>thresol[t+4]) { data_dst[j*step+t*ceil_height*step+i+ceil_width]=255; } else data_dst[j*step+t*ceil_height*step+i+ceil_width]=0; } } }}int CopencvDlg::Otsu(IplImage *src){ int width=src->width; int height=src->height; int step=src->widthStep; float histogram[256]={0}; unsigned char* p=(unsigned char*)src->imageData; for(int i=0;i<height;i++) { for(int j=0;j<width;j++) { histogram[p[i*step+j]]++; } } //normalize histogram int size=height*width; for(int i=0;i<256;i++) { histogram[i]=histogram[i]/size; } //average pixel value float avgValue=0; for(int i=0;i<256;i++) { avgValue+=i*histogram[i]; } int threshold; float sum0=0, sum1=0; //存储前景的灰度总和和背景灰度总和 float cnt0= 0, cnt1=0; //前景的总个数和背景的总个数 float w0=0, w1=0; //前景和背景所占整幅图像的比例 float u0=0, u1=0; //前景和背景的平均灰度 float variance = 0; //最大类间方差 int i,j; float u=0; float maxVariance = 0; for(i =1;i<256;i++) //一次遍历每个像素 { sum0=0; sum1=0; cnt0=0; cnt1=0; w0=0; w1=0; for(j=0;j<i;j++) { cnt0+=histogram[j]; sum0+=j*histogram[j]; } u0=sum0/cnt0; //w0=cnt0/size; w0=cnt0; for(j =i;j<=255;j++) { cnt1+=histogram[j]; sum1+=j*histogram[j]; } u1=sum1/cnt1; w1=cnt1; //w1=1-w0; // (double)cnt1 / size; u=u0*w0+u1*w1; //图像的平均灰度 variance=float(w0*w1*(u0-u1)*(u0 - u1)); if(variance > maxVariance) //类间方差最大时为所求阈值 { maxVariance = variance; threshold = i; } } return threshold;}标签:
原文地址:http://www.cnblogs.com/skyhuangdan/p/5486689.html