模糊阈值分割代码(1)

前几天,应一个网友的要求,根据文章《图像的自适应模糊阈值分割法》,写了个简单的代码:

/*
名称:BlurCure
参数:lpBmp - 图像数据指针
      lSrcWidth - 图像宽度
      lSrcHeight - 图像高度
      dLineBites - 图像单行数据量
说明:获取模糊阈值分割的模糊曲线dBlurData
*/
void BlurCurve(LPSTR lpBmp, long lSrcWidth, long lSrcHeight, DWORD dLineBites)
{
	if(lpBmp == NULL)
		return;
	int i,j;
	LPSTR lpSrcPtr = NULL;
	BYTE btTempValue = 0;
	int nTistogram[256] = {0};
	for (i = 0;i < lSrcHeight; ++i)
	{
		lpSrcPtr = lpBmp + i * dLineBites;
		for (j = 0;j <lSrcWidth; ++j)
		{
			btTempValue = (BYTE)*(lpSrcPtr + j);
			nTistogram[btTempValue]++;
		}
	}
	int nWinWidth = 20;//搜索的窗宽
	double dBlurData[256]={0};
	double dGetMemship = 0;
	for (int nGrayPos = 0; nGrayPos < 256; ++nGrayPos)
	{
		for (j = 0;j <256; ++j)
		{
			dGetMemship = MemshipFunc(j,nGrayPos,nWinWidth);
			if(dGetMemship > 0.5)
				dGetMemship = 1 - dGetMemship;
			if(dGetMemship < 0)
				dGetMemship = 0;
			dBlurData[nGrayPos] += nTistogram[j]*dGetMemship;
		}
		dBlurData[nGrayPos] *= 2.0/(lSrcHeight*lSrcWidth);
	}
}


/*
隶属度函数:MemshipFunc
*/
double MemshipFunc(int nGray,const int& nWinCent,const int& nWinWidth)
{
	int nLeft = nWinCent-nWinWidth;
	int nRight = nWinCent+nWinWidth;
	if(nGray >= 0 && nGray <= nLeft)
		return 0;
	else if(nGray > nLeft && nGray <= nWinCent)
	{
		double dMem = double(nGray - nLeft)/(2*nWinWidth);
		return 2*dMem*dMem;
	}
	else if(nGray > nWinCent && nGray <= nRight)
	{
		double dMem = double(nGray - nLeft)/(2*nWinWidth);
		return 1-2*dMem*dMem;
	}
	return 1;
}

原始图像:


直方图:

模糊曲线:

从上图可以看出,经过模糊化后,直方图变的平滑了很多,下一步主要进行曲线最小值的搜索。


另外,模糊缺陷的保值性与窗宽nWinWidth 有很大的关系,窗宽取的合适,获得的模糊曲线就更容易分割。而所谓自适应模糊化分割,就是找到合适的nWinWdith,目前,找合适的nWinWdith有很多方法,大部分都是搜索法,然后按照设定的准则停止(比如文中讲到的极点法、还有区间法等)搜索,最后获得合适的nWinWidth。


我将再后续的工作中,尝试不同的搜索方法,并把代码奉上。

阅读更多

没有更多推荐了,返回首页