图像保边滤波算法集锦--局部均值滤波算法与实现

局部均值滤波算法是基于均值改进的一种具有一定保边能力的滤波器,参考论文为Lee filter Digital image enhancement and noise filtering by using local statistics,具体算法如下:


本人C实现效果如下:


主要代码如下:

int LSNFilterOneChannel(unsigned char* srcData, int width ,int height, int radius, int delta)
{	
	int len = sizeof(unsigned long) * width * height;
	unsigned char* dstData = (unsigned char*)malloc(len);
	unsigned long* meanData = (unsigned long*) malloc(len);
	unsigned long* covData = (unsigned long*) malloc(len);
	memset(meanData, 0, len);
	memset(covData, 0, len);
    MeanCovMapCalculate(srcData, width, height, width, meanData, covData, radius);
	float mean = 0, cov = 0, K = 0;
	int i, j, num = 2 * radius + 1;
	num = num * num;
	int gray = 0;
	for(j = 0; j < height; j++ )
	{
		for(i = 0; i < width; i++)
		{
			len = i + j * width;
			mean = (float)meanData[len];
			cov = (float)covData[len];
			cov = cov - mean * mean;
			K = cov / (cov + delta);
			gray = (int)((1.0 - K) * mean + K * (float)srcData[len]);
			dstData[len] = CLIP3(gray, 0, 255);
		}
	}
	memcpy(srcData, dstData, len);
	free(meanData);
	free(covData);
	free(dstData);
	return 0;
};
void f_LSNFilter(unsigned char* srcData, int nWidth, int nHeight, int nStride, int radius, int delta)
{
	if (srcData == NULL)
	{
		return;
	}
	unsigned char* rData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* gData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* bData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* pSrc = srcData;
	unsigned char* pR = rData;
	unsigned char* pG = gData;
	unsigned char* pB = bData;
	for(int j = 0; j < nHeight; j++)
	{
		for(int i = 0; i < nWidth; i++)
		{
			*pR = pSrc[2];
			*pG = pSrc[1];
			*pB = pSrc[0];
			pR++;
			pG++;
			pB++;
			pSrc += 4;
		}
	}
	#pragma omp parallel sections  num_threads(omp_get_num_procs())
	{
		#pragma omp  section					
			LSNFilterOneChannel(rData, nWidth, nHeight, radius, delta);
		#pragma omp  section
			LSNFilterOneChannel(gData, nWidth, nHeight, radius, delta);
		#pragma omp  section
			LSNFilterOneChannel(bData, nWidth, nHeight, radius, delta);
	}
	pSrc = srcData;
	pR = rData;
	pG = gData;
	pB = bData;
	int R, G, B;
	for(int j = 0; j < nHeight; j++)
	{
		for(int i = 0; i < nWidth; i++)
		{
            pSrc[0] = *pB;
			pSrc[1] = *pG;
			pSrc[2] = *pR;
			pR++;
			pG++;
			pB++;
			pSrc += 4;
		}
	}
	free(rData);
	free(gData);
	free(bData);
}
void f_LSNFilterOneChannel(unsigned char* srcData, int nWidth, int nHeight, int nStride, int radius, int delta)
{
	if (srcData == NULL)
	{
		return;
	}
	unsigned char* yData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* cbData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* crData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);
	unsigned char* pSrc = srcData;
	int Y, CB, CR;
	unsigned char* pY = yData;
	unsigned char* pCb = cbData;
	unsigned char* pCr = crData;
	for(int j = 0; j < nHeight; j++)
	{
		for(int i = 0; i < nWidth; i++)
		{
			RGBToYCbCr(pSrc[2],pSrc[1],pSrc[0],&Y,&CB,&CR);
			*pY = Y;
			*pCb = CB;
			*pCr = CR;
			pY++;
			pCb++;
			pCr++;
			pSrc += 4;
		}
	}
	LSNFilterOneChannel(yData, nWidth, nHeight, radius, delta);
	pSrc = srcData;
	pY = yData;
	pCb = cbData;
	pCr = crData;
	int R, G, B;
	for(int j = 0; j < nHeight; j++)
	{
		for(int i = 0; i < nWidth; i++)
		{
			YCbCrToRGB(*pY, *pCb, *pCr, &R, &G, &B);
            pSrc[0] = B;
			pSrc[1] = G;
			pSrc[2] = R;
			pY++;
			pCb++;
			pCr++;
			pSrc += 4;
		}
	}free(yData);free(cbData);free(crData);
}


最后给出完整的DEMO:点击打开链接

本人QQ : 1358009172

  • 11
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Trent1985

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值