图像阈值分割---迭代算法
1.处理流程:
1.为全局阈值选择一个初始估计值T(图像的平均灰度)。
2.用T分割图像。产生两组像素:G1有灰度值大于T的像素组成,G2有小于等于T像素组成。
3.计算G1和G2像素的平均灰度值m1和m2;
4.计算一个新的阈值:T = (m1 + m2) / 2;
5.重复步骤2和4,直到连续迭代中的T值间的差小于一个预定义参数为止。
适合图像直方图有明显波谷
2.源代码
/*******************************************************************************
函数名称 : IterativeAlgorithm
函数描述 : 图像算法:图像阈值分割---迭代算法(适合图像直方图有明显波谷)
输入参数 : IplImage *pImage---------------------------图像指针(灰度图)
int nMaxIter----------------------------------最大迭代次数
int& iDiffRec---------------------------------使用给定阀值确定的亮区与暗区平均灰度差异值
输出参数 : N/A
返 回 值 : int iThrehold---------------------------------迭代得到的阈值
作 者 : N/A 2013-01-22
处理流程:1.为全局阈值选择一个初始估计值T(图像的平均灰度)。
2.用T分割图像。产生两组像素:G1有灰度值大于T的像素组成,G2有小于等于T像素组成。
3.计算G1和G2像素的平均灰度值m1和m2;
4.计算一个新的阈值:T = (m1 + m2) / 2;
5.重复步骤2和4,直到连续迭代中的T值间的差小于一个预定义参数为止。
*******************************************************************************/
int CThreasholdProcess::DetectThreshold(const IplImage *img, int nMaxIter, int& iDiffRec)
{
//图像信息
int iHeight = img->height;
int iWidth = img->width;
int iStep = img->widthStep/sizeof(uchar);
uchar *pData = (uchar*)img->imageData;
iDiffRec =0;
int F[256]={ 0 }; //直方图数组
int iTotalGray=0;//灰度值和
int iTotalPixel =0;//像素数和
byte bt;//某点的像素值
uchar iThrehold = 0; //阀值
uchar iNewThrehold = 0; //新阀值
uchar iMaxGrayValue=0,iMinGrayValue=255;//原图像中的最大灰度值和最小灰度值
uchar iMeanGrayValue1,iMeanGrayValue2;
//获取(i,j)的值,存于直方图数组F
for(int i=0;i<iWidth;i++)
{
for(int j=0;j<iHeight;j++)
{
bt = pData[i*iStep+j];
if(bt<iMinGrayValue)
iMinGrayValue = bt;
if(bt>iMaxGrayValue)
iMaxGrayValue = bt;
F[bt]++;
}
}
iThrehold =0;
iNewThrehold = (iMinGrayValue+iMaxGrayValue)/2;//初始阀值(图像的平均灰度)
iDiffRec = iMaxGrayValue - iMinGrayValue;
for(int a=0;(abs(iThrehold-iNewThrehold)>0.5)&&a<nMaxIter;a++)//迭代中止条件
{
iThrehold = iNewThrehold;
//小于当前阀值部分的平均灰度值
for(int i=iMinGrayValue;i<iThrehold;i++)
{
iTotalGray += F[i]*i;//F[]存储图像信息
iTotalPixel += F[i];
}
iMeanGrayValue1 = (uchar)(iTotalGray/iTotalPixel);
//大于当前阀值部分的平均灰度值
iTotalPixel =0;
iTotalGray =0;
for(int j=iThrehold+1;j<iMaxGrayValue;j++)
{
iTotalGray += F[j]*j;//F[]存储图像信息
iTotalPixel += F[j];
}
iMeanGrayValue2 = (uchar)(iTotalGray/iTotalPixel);
iNewThrehold = (iMeanGrayValue2+iMeanGrayValue1)/2; //新阀值
iDiffRec = abs(iMeanGrayValue2 - iMeanGrayValue1);
}
return iThrehold;
}
3.演示;
演示结果见http://blog.csdn.net/ily6418031hwm/article/details/8525695 的演示结果