- Normalized Cross-Correlation, NCC
- power spectrum density, PSD
可以将上面的公式写为
其中
H(u,v) 为退化函数, Sη 和 Sf 是噪声与未退化图像的功率谱。信噪比为
函数的约束条件为
这个最优化问题的频域解决办法由下式给出
其中 P(u,v) 是拉普拉斯算子 p(x,y) 的傅立叶变换,有
未知量有 γ 和 ∥η∥2 两个。若已知和噪声功率(标量)成比例的 ∥η∥2 ,则通过迭代, γ 可以得出。
%%
clc,clear,close all
% 原始图像
f = checkerboard(8);
% 噪声滤波器
PSF = fspecial('motion', 7, 45);
% 退化图像
gb = imfilter( f, PSF, 'circular' );
% 高斯滤波
noise = imnoise( zeros(size(f)), 'gaussian', 0, 0.001 );
% 将噪声加到原图上
g = gb + noise;
figure
subplot(221), imshow( f ), title('原图')
subplot(222), imshow( noise, [] ), title('高斯噪声')
subplot(223), imshow( gb ), title('退化图像')
subplot(224), imshow( g ), title('退化图像加高斯噪声')
%% 图像复原
% 噪信比默认为0,即信噪比相当于无穷大,即直接逆滤波的过程
fr1 = deconvwnr( g, PSF );
Sn = abs( fft2(noise) ) .^2;
nA = sum( Sn(:) ) / numel( noise );
Sf = abs( fft2(f) ) .^2;
fA = sum( Sf(:) ) / numel( f );
R = nA / fA; % 平均噪信比计算
% 使用常数比例的维纳滤波进行复原
fr2 = deconvwnr( g, PSF, R );
% 使用自相关函数的维纳滤波进行复原
Ncorr = fftshift( real(ifft2(Sn)) );
Fcorr = fftshift( real(ifft2(Sf)) );
fr3 = deconvwnr( g, PSF, Ncorr, Fcorr );
figure
subplot(221), imshow( g ), title('模糊的运动图像')
subplot(222), imshow( fr1, [] ), title('直接逆滤波复原图像')
subplot(223), imshow( fr2, [] ), title('常数比例维纳滤波复原图像')
subplot(224), imshow( fr3, [] ), title('使用自相关函数的维纳滤波复原图像')
%% 约束最小二乘滤波
% 4 约等于 64*64*0.001
fr1 = deconvreg( g, PSF, 4 );
fr2 = deconvreg( g, PSF, 0.4, [1e-7, 1e7] );
figure
subplot(221), imshow( g ), title('模糊的运动图像')
subplot(222), imshow( fr1, [] ), title('仅噪声功率参数的正则滤波')
subplot(223), imshow( fr2, [] ), title('包含噪声和gamma范围的正则滤波')
%% Lucy-Richardson算法的迭代非线性复原
g = checkerboard(8);
ori = g;
PSF = fspecial( 'gaussian', 7, 10 );
SD = 0.01;
g = imnoise( imfilter(g, PSF), 'gaussian', 0, SD^2 );
damper = 10*SD;
lim = ceil( size(PSF, 1) / 2 );
weight = zeros( size(g) );
weight( lim+1:end-lim, lim+1:end-lim ) = 1;
numit = 5;
f5 = deconvlucy( g, PSF, numit, damper, weight );
numit = 20;
f20 = deconvlucy( g, PSF, numit, damper, weight );
numit = 50;
f50 = deconvlucy( g, PSF, numit, damper, weight );
numit = 100;
f100 = deconvlucy( g, PSF, numit, damper, weight );
figure
subplot(231), imshow( ori ), title('原始图像')
subplot(232), imshow( g, [] ), title('加两次高斯噪声的图')
subplot(233), imshow( f5, [] ), title('LR 5次迭代')
subplot(234), imshow( f20 ), title('LR 20次迭代')
subplot(235), imshow( f50, [] ), title('LR 50次迭代')
subplot(236), imshow( f100,[] ), title('LR 100次迭代')
Radon
方法进行估计,运动的长度可以用倒谱法进行估计参考链接:http://www.cnblogs.com/yomman/p/3424494.html
代码
function [beta, len] = getMotionPara( img, showImg )
% getMotionPara : 得到运动模糊图像的的参数估计
% img : 输入的灰度图像
% beta : 运动参数的角度
% len : 运动参数的长度
% 用这两个参数可以对图像进行复原
if nargin <= 1
showImg = false;
end
fg = fft2( img );
spec = log(1+abs(fg));
specCenter = fftshift( spec );
thres = graythresh( specCenter );
bw = edge( specCenter, 'canny', thres );
th = 1:180;
R = radon( bw, th );
maxRadon = max(R(:));
[~, n] = find( R == maxRadon );
[M, N] = size( specCenter );
beta = atan( tan(n*pi/180)*M/N)*180/pi;
%利用倒谱的方法估计模糊尺度
theta = beta;
%――――――――――――――――――――――――――――
%转化为倒谱域:Cep(g(x,y)) = invFT{log(FT(g(x,y)))}
fin = fft2(img); %转化为频域
lgfin = abs(log(1 + abs(fin))); %转化为对数,abs是求复数的模
cin = ifft2(lgfin); %得到倒谱域的图像
cinrot = imrotate(cin, -theta); %旋转图像,使模糊方向水平
%计算每列的平均值
for i=1:size(cinrot, 2) %列数
avg(i) = 0;
for j=1:size(cinrot, 1) %行数
avg(i) = avg(i) + cinrot(j, i);
end
avg(i) = avg(i)/size(cinrot, 1); %第i列的平均值
end
avgr = real(avg);
%用第一个负值计算模糊尺度
index = 0;
for i = 1:round(size(avg,2)),
if real(avg(i))<0,
index = i;
break;
end
end
%如果找到了模糊尺度,则:
if index~=0
len = index;
else
%如果没有找到模糊尺度(无负峰),则利用查找最低峰的方法再查找
index = 1;
startval = avg(index);
for i = 1 : round(size(avg, 2)/2),
if startval>avg(i),
startval = avg(i);
index = i;
end
end
len = index;
end
if showImg
subplot(221), imshow( img ), title('原图')
subplot(222), imshow( specCenter, [] ), title('居中后的压缩频谱')
subplot(223), imshow( bw ), title('频谱二值化图像')
subplot(224), imshow( R ), title('Radon变换后图像')
end
end
一些信噪比等的参数主要是通过尝试得出
代码(main.m)
%%
clc,clear,close all
img = imread( '1.jpg' );
gb = double(rgb2gray( img )) / 255;
%% 运动参数估计
[beta, len] = getMotionPara( gb );
fprintf('PSF parameters, angle : %.2f, length : %.2f\n', beta, len);
%% 图像噪声去除
% 运动噪声滤波器估计
PSF = fspecial('motion', len, beta);
% 直接逆滤波求得结果
% 逆滤波得到的结果很差,说明原图中有较多噪声,需要通过其他方法去除
res1 = deconvwnr( gb, PSF );
% 维纳滤波
% 随便给的一个信噪比的值
nsr = 0.01;
res2 = deconvwnr( gb, PSF, nsr );
% 约束最小二乘滤波
% 尝试给出的一个噪声能量值
noisePower = 10;
res3 = deconvreg( gb, PSF, noisePower );
figure
subplot(231), imshow( img ), title('原图')
subplot(232), imshow( res1, [] ), title('逆滤波复原后图像')
subplot(233), imshow( res2, [] ), title('维纳后图像')
subplot(234), imshow( res3, [] ), title('约束最小二乘复原后图像')
效果图
注:其实图像复原最重要的还是参数估计和噪声估计,不然复原效果会一直很差