主要就是写公式和调用函数,注释应该还挺清晰的,直接复制就能运行
模拟大气湍流
im = imread("demo1.jpg");
subplot(131); imshow(im); title('原图');
k = 0.0025;
[h, w] = size(im);
% 傅里叶变换
F = fftshift(fft2(im));
% 计算退化模型
H = zeros(h, w);
for i = 1 : h
for j = 1 : w
H(i, j) = exp(-k * ((i - h/2)^2 + (j - w/2)^2)^(5/6));
end
end
% 计算退化后的图像
SDF = F.*H;
im_sat = uint8(real(ifft2(SDF)));
subplot(132); imshow(im_sat); title('模拟大气湍流');
% 直接逆滤波
F_N = SDF./H;
im_N = uint8(real(ifft2(F_N)));
subplot(133); imshow(im_N); title('直接逆滤波');
模拟运动模糊
im = imread("demo2.jpg");
subplot(231); imshow(im); title('原图');
% 傅里叶变换
im = im2double(im);
F=fftshift(fft2(im));
% 计算退化模型
[M,~] = size(im);
T = 1; a = 0.1; b = 0.1;
v = (-M / 2:M / 2-1);
u = v';
A = repmat(a.*u, 1, M) + repmat(b.*v, M, 1);
H = T/pi./A.*sin(pi.*A).*exp(-1i*pi.*A);
H(A == 0) = T;
% 计算退化后的图像
SDF = F.*H;
im_smb = real(ifft2(ifftshift(SDF)));
subplot(232); imshow(im_smb); title('运动模糊');
% 加噪
% noise = imnoise(im_smb,"gaussian", 0, 0.01); % 直接在空域对图像加噪
noise = imnoise(zeros(M,M),"gaussian",0, 0.00001); %获取空域噪声
FNoise = fftshift(fft2(noise)); % 将噪声转化到频域
SDFN = F.*H + FNoise; % 图像加噪
im_smbn = real(ifft2(ifftshift(SDFN)));
subplot(233); imshow(im_smbn); title('运动模糊加高斯噪声');
% 无噪直接逆滤波
F_N = SDF./H;
im_N = real(ifft2(ifftshift(F_N)));
subplot(234); imshow(im_N); title('无噪直接逆滤波');
% 有噪直接逆滤波
F_NN = SDFN./H;
im_NN = real(ifft2(ifftshift(F_NN)));
subplot(235); imshow(im_NN); title('有噪直接逆滤波');
% 截止半径R内逆滤波
R = 5;
FD = zeros(M);
for i = 1:M
for j = 1:M
if sqrt((i - M/2).^2 + (j - M/2).^2) < R
FD(i,j) = SDFN(i,j)./H(i,j);
end
end
end
im_NNR = real(ifft2(ifftshift(FD)));
subplot(236); imshow(im_NNR); title('有噪截止半径5逆滤波');
%%% 维纳滤波 %%%
figure();
subplot(221); imshow(im); title('原图');
subplot(222); imshow(im_smbn); title('运动模糊加高斯噪声');
% 维纳滤波公式
buf=(abs(H)).^2; % H(u,v)^2
SNR=(FNoise.^2)./(F.^2); % 计算理论K值,功率谱除后平方
F_WN=SDFN./H.*buf./(buf+SNR); % 代入公式
im_wf=real(ifft2(ifftshift(F_WN))); % 逆傅里叶变换
subplot(223); imshow(im_wf); title('理论维纳滤波');
% k = 0.01的维纳滤波
bestK=0.02;
F_WN=SDFN./H.*buf./(buf+bestK);
im_wf=real(ifft2(ifftshift(F_WN)));
subplot(224); imshow(im_wf); title('k=0.02维纳滤波');
最小二乘滤波
I = im2double(imread('demo2.jpg'));
[hei,wid,~] = size(I);
subplot(2,2,1),imshow(I);
title('原图像');
% 模拟运动模糊.
LEN = 21;
THETA = 11;
PSF = fspecial('motion', LEN, THETA);%产生运动模糊算子,即点扩展函数
blurred = imfilter(I, PSF, 'conv', 'circular');
subplot(2,2,2), imshow(blurred); title('模糊图像');
Pf = psf2otf(PSF,[hei,wid]);%退化函数的FFT
% 添加加性噪声
noise_mean = 0;
noise_var = 0.00001;
blurred_noisy = imnoise(blurred, 'gaussian',noise_mean, noise_var);
subplot(2,2,3), imshow(blurred_noisy)
title('带运动模糊和噪声图像')
p = [0 -1 0;-1 4 -1;0 -1 0];%拉普拉斯模板
P = psf2otf(p,[hei,wid]);
gama = 0.001;
If = fft2(blurred_noisy);
numerator = conj(Pf);%conj函数,用于求一个复数的复共轭
denominator = Pf.^2 + gama*(P.^2);
deblurred2 = ifft2( numerator.*If./ denominator );%约束最小二乘方滤波在频率域中的表达式
subplot(2,2,4), imshow(deblurred2)
title('约束最小二乘方滤波后图像');
自动调参最小二乘滤波
im = imread('demo2.jpg');
[M,~] = size(im);
im = im2double(im);
subplot(2,2,1), imshow(im)
title('原图')
% 加模糊
PSF = fspecial('motion', 100, 11);
im_smb = imfilter(im, PSF, 'conv', 'circular');
% 加噪
mean = 0;
var = 0.00001;
im_smbn = imnoise(im_smb, 'gaussian', mean, var);
subplot(2,2,2), imshow(im_smbn)
title('运动模糊加高斯噪声')
% 运动模糊的傅里叶变换
H = psf2otf(PSF,[M,M]);
% 函数的傅里叶变换
p = [0 -1 0; -1 4 -1; 0 -1 0]; % 拉普拉斯算子
P = psf2otf(p,[M,M]);
% gama = M*M*(mean+var*var);
gama = 0.001; % 参数γ
G = fft2(im_smbn);
H2 = conj(H); % H的复共轭
im_LS = ifft2( H2.*G./ (H.^2 + gama*(P.^2)));% 最小二乘方滤波公式
subplot(2,2,3), imshow(im_LS)
title('手动调参最小二乘方滤波');
gap=0.0001;
gama=0.0001;
a=0.05;
yita=M*M*(mean+var*var);
iteration=0;
while (true)
iteration = iteration+1;
if iteration > 10000 % 设置循环次数
break;
end
Fs=(H2.*G)./ (abs(H).^2+gama*(abs(P).^2));
R=G-H.*Fs;
r=ifftshift(R);
r_=ifft2(r);
rr=sum(sum(r_.^2));
if rr<yita + a
gama = gama + gap;
elseif rr > yita + a
gama = gama - gap;
else
break
end
end
im_LS = ifft2( H2.*G./ (H.^2 + gama*(P.^2)));
subplot(2,2,4), imshow(im_LS)
title('自动调参最小二乘方滤波');
实现效果