以下为来自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 uint8
, uint16
, int16
, single
, 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
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.
代码实现
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中的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,实验效果:
参考文献:
【1】Lim, Jae S. Two-Dimensional Signal and Image Processing. Englewood Cliffs, NJ: Prentice Hall, 1990. pp. 536-540.