数字图像处理,自适应维纳滤波的C++实现

以下为来自Matlab的基本原理

wiener2

2-D adaptive noise-removal filtering

The syntax wiener2(I,[m n],[mblock nblock],noise) has been removed. Use the wiener2(I,[m n],noise) syntax instead.

Syntax

J = wiener2(I,[m n],noise)
[J,noise] = wiener2(I,[m n])

Description

wiener2 lowpass-filters a grayscale image that has been degraded by constant power additive noise. wiener2 uses a pixelwise adaptive Wiener method based on statistics estimated from a local neighborhood of each pixel.

J = wiener2(I,[m n],noise) filters the image I using pixelwise adaptive Wiener filtering, using neighborhoods of size m-by-n to estimate the local image mean and standard deviation. If you omit the [m n] argument, m and n default to 3. The additive noise (Gaussian white noise) power is assumed to be noise.

[J,noise] = wiener2(I,[m n]) also estimates the additive noise power before doing the filtering. wiener2 returns this estimate in noise.

Class Support

The input image I is a two-dimensional image of class uint8uint16int16single, or double. The output image J is of the same size and class as I.

Examples

For an example, see Remove Noise By Adaptive Filtering.

More About

collapse all

Algorithms

wiener2 estimates the local mean and variance around each pixel.

and

where  is the N-by-M local neighborhood of each pixel in the image Awiener2 then creates a pixelwise Wiener filter using these estimates,

where ν2 is the noise variance. If the noise variance is not given, wiener2 uses the average of all the local estimated variances.

References

[1] Lim, Jae S., Two-Dimensional Signal and Image Processing, Englewood Cliffs, NJ, Prentice Hall, 1990, p. 548, equations 9.26, 9.27, and 9.29.

See Also

filter2 | medfilt2


代码实现

1,算法流程:


2,Matlab代码实现:

简化版本:
function [f,noise] = adpwiener2(g,nhood)
noise = [];
g = im2double(g);

% 计算均值
localMean = filter2(ones(nhood), g) / prod(nhood);

% 计算方差
localVar = filter2(ones(nhood), g.^2) / prod(nhood) - localMean.^2;

% 如果需要,计算噪声能量
if (isempty(noise))
  noise = mean2(localVar);
end

% 计算结果
% f = localMean + (max(0, localVar - noise) ./ ...
%           max(localVar, noise)) .* (g - localMean); 
f = g - localMean;
g = localVar - noise; 
g = max(g, 0);
localVar = max(localVar, noise);
f = f ./ localVar;
f = f .* g;
f = f + localMean;


3,C++代码实现

处理结果与matlab库函数一模一样。
//对应matlab中的filter2,但是此处功能多了一些
double filter2(
	double* srcbuffer,
	int width,
	int height,
	int kernelsize,
	double* dstbuffer1,
	double* dstbuffer2
	)
{
	//kernel的中心位置
	int center_pos = kernelsize / 2;
	int i, j;
	double sumvar = 0.0;
	for (i = 0; i < height; ++i)    // 行
	{
		for (j = 0; j < width; ++j)    // 列
		{
			for (int m = 0; m < kernelsize; ++m)     // kernel行
			{
				int mm = kernelsize - 1 - m;      // 核的行索引

				for (int n = 0; n < kernelsize; ++n) // kernel列
				{
					int nn = kernelsize - 1 - n;  // 核的列索引
					// 输入图像信号的索引,用于检查边界
					int ii = i + (m - center_pos);
					int jj = j + (n - center_pos);
					// 忽视越界
					if (ii >= 0 && ii < height && jj >= 0 && jj < width)
					{
						dstbuffer1[i*width + j] += srcbuffer[ii*width + jj] / (kernelsize*kernelsize);
						dstbuffer2[i*width + j] += srcbuffer[ii*width + jj] * srcbuffer[ii*width + jj] / (kernelsize*kernelsize);
					}
				}
			}
			dstbuffer2[i*width + j] -= dstbuffer1[i*width + j] * dstbuffer1[i*width + j];
			sumvar += dstbuffer2[i*width + j];
		}
	}
	return sumvar / (width*height);//求取noise
}


void adpwiener2(
	unsigned char* inbuffer,
	int kernelsize,
	int width,
	int height,
	unsigned char* outbuffer
	)
{
	double len = 1.0*kernelsize*kernelsize;
	double* srcbuffer = new double[width*height];//对应matlab中的g
	double* localMeanArr = new double[width*height];//对应matlab中的localMean,以下同理
	double* localVarArr = new double[width*height];
	double* dstbuffer = new double[width*height];
	//初始化
	for (int i = 0; i < width*height; i++)
		localVarArr[i] = localMeanArr[i] = 0.0;
	for (int i = 0; i < width*height; i++)
		srcbuffer[i] = double(inbuffer[i]);

	double noise = filter2(srcbuffer, width, height, kernelsize, localMeanArr, localVarArr);

	for (int i = 0; i < width*height; i++)
	{
		dstbuffer[i] = srcbuffer[i] - localMeanArr[i];//f = g - localMean;
		srcbuffer[i] = localVarArr[i] - noise;//g = localVar - noise; 
		if (srcbuffer[i] < 0.0)//g = max(g, 0);
			srcbuffer[i] = 0.0;
		localVarArr[i] = max(localVarArr[i], noise);//localVar = max(localVar, noise);
		dstbuffer[i] = dstbuffer[i] / localVarArr[i] * srcbuffer[i] + localMeanArr[i];//f = f ./ localVar.*+localMean;
		outbuffer[i] = unsigned char(dstbuffer[i]);//转换成图像数据
	}

	delete[] srcbuffer;
	srcbuffer = NULL;
	delete[] localMeanArr;
	localMeanArr = NULL;
	delete[] localVarArr;
	localVarArr = NULL;
	delete[] dstbuffer;
	dstbuffer = NULL;
}




4,实验效果:

对原图处理结果,注意是5*5的窗口




对椒盐噪声处理结果,注意是5*5的窗口,结果较差


对高斯噪声的处理结果,注意是5*5的窗口,结果较优


参考文献:

【1】Lim, Jae S. Two-Dimensional Signal and Image Processing. Englewood Cliffs, NJ: Prentice Hall, 1990. pp. 536-540.


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值