您的位置:首页 > 编程语言 > C语言/C++

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

2014-07-26 15:41 507 查看
以下为来自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

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 
A
wiener2
 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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息