关于阈值分割前面已经写过一篇但是最重要的部分阈值的求取没有说明,本文主要讲怎么求取最佳分割门限,此处讲的是全局门限,复杂的图像只需把图像分成若干小块然后对每一块求取最佳分割门限然后分割即可。
步骤讲解:
代码实现如下:
int picProcessBasics::IMGthresholdSeg(IplImage* pImg,int T0)
{
if(NULL == pImg)
return -1;
if(pImg->nChannels != 1)
{
cout<<"param error"<<endl;
return -1;
}
uchar* old_data = (uchar*)pImg->imageData;
int numG1 = 0;//记录大于T值得像素个数
int numG2 = 0;
long int sumG1 = 0;//记录大于T值的像素灰度级之和
long int sumG2 = 0;
int valueG1 = 0;//记录大于T值得像素平均灰度值
int valueG2 = 0;
long int sum = 0;
int resT=0;
//1.求图像灰度级平均值
for(int i = 0;i < pImg->height;i++){
for(int j = 0; j < pImg->width; j++){
sum += old_data[pImg->widthStep * i + j ];
}
}
int tempT=sum/(pImg->height*pImg->width);//将整幅图像灰度级的平均值作为门限T的初始值
resT=tempT;
do
{
tempT=resT;
for(int i = 0;i < pImg->height;i++){
for(int j = 0; j < pImg->width; j++){
if(old_data[pImg->widthStep * i + j ] > tempT)
{
sumG1 += old_data[pImg->widthStep * i + j ];
numG1++;
}
else
{
sumG2 += old_data[pImg->widthStep * i + j ];
numG2++;
}
}
}
valueG1=sumG1/numG1;
valueG2=sumG2/numG2;
resT=(valueG1+valueG2)/2;
}while(abs(resT-tempT) > T0);
for(int i = 0;i < pImg->height;i++){
for(int j = 0; j < pImg->width; j++){
if(old_data[pImg->widthStep * i + j ] > resT)
{
old_data[pImg->widthStep * i + j ]=255;
}
else
{
old_data[pImg->widthStep * i + j ]=0;
}
}
}
return 0;
}
原图像:
分割后图像: