基于python-tensorflow的机器视觉学习手札 (1.5)图像处理篇-图像复原技术

图像复原最基本的任务是去除图像中的噪声的同时,不丢失图像中的细节。然而抑制噪声(高频)与保留细节(高频)是一对矛盾的问题。
图像复原与图像增强都是为了改善图像的质量,但本质上有所区别。图像增强不考虑图像是如何退化的,而是试图用各种技术来增强图像的视觉效果;而图像复原需要知道图像退化的机制与过程,找到一种相应的逆处理方法,从而得到恢复后的图像。

1. 噪声

噪声可以分为加性噪声和乘性噪声两种。
细分,可以分为高斯噪声,椒盐噪声,均匀分布噪声,指数分布噪声,gamma分布噪声等。在matlab中,加入噪声只需要imnoise就可以实现。

2. 空域滤波

空域内的滤波复原方法,主要包括均值滤波复原、顺序统计滤波复原、和自适应滤波复原。

2.1 均值滤波复原

均值滤波复原就是用均值滤波算子作为卷积核计算。分为算术均值滤波和几何均值滤波。
在matlab中,算术均值滤波就是直接进行滤波:
A = imfilter(Img, psf);
而几何均值滤波则是对图像取对数,再进行滤波,然后取指数:A=exp(imfilter(log(Img),psf));
python中也可以用filter2d与numpy包来实现类似功能。
此外,还有一个逆谐波均值滤波器,有一个参数Q,用matlab实现的代码为(其实是写公式有些麻烦):

Q = 1.5;    A = imfilter(img.^(Q+1),psf)./imfilter(img.^Q,psf);

Q为正值时,可以去除椒噪声;Q为负值时,可以去除盐噪声。当Q = -1时,该滤波器为谐波均值滤波器。我也不知道opencv库中有没有这个功能(反正toturial里面没有),不过可以很简单的用numpy与filter2d来实现这个功能(照着公式填就完了)。

2.2 顺序统计滤波复原

顾名思义,顺序统计滤波就是把一个像素值周围的邻域所有元素排序,其最大值/最小值/中值就为该点复原后的值。这种方法可以用于去除椒盐噪声。在matlab中,用函数medfilt(中值滤波)与ordfilt(顺序滤波)来实现。在python中,我们还是用好用的numpy来实现。(着实很简单,如果需要我补上代码可以评论告诉我)

2.3 自适应滤波复原

自适应滤波也就是上一篇说过的维纳滤波。既然第二次提到了,那就给出一个示例代码(matlab不需要,有现成的wiener2):

def wiener(input,PSF,eps,K=0.01):        #维纳滤波,K=0.01
    input_fft=fft.fft2(input)
    PSF_fft=fft.fft2(PSF) +eps
    PSF_fft_1=np.conj(PSF_fft) /(np.abs(PSF_fft)**2 + K)
    result=fft.ifft2(input_fft * PSF_fft_1)
    result=np.abs(fft.fftshift(result))
    return result

虽然给了代码块,不过这里确实不是重点,维纳现在很少用了,自适应滤波器还是应用太少,就算用也用自适应LMS算法啥啥的。。

3. 图像复原方法

3.1 逆滤波复原

这是最简单的复原方法。其实就是傅里叶变换后,除以所用退化矩阵的傅里叶变换,再变回来,就是所谓逆滤波。这种方法其实不好用,对噪声及其敏感。除非我们知道噪声的分布(不太可能),不然会变得很乱。
不过还有一种改进,由于噪声是很高的频率部分,那可以傅里叶变换之后只在低频部分做逆滤波,不过这个范围很难确定,范围太小容易没有复原效果,范围太大又会增强噪声,还是不理想。
(不理想的东西就少说几句,反正用不到)

3.2 维纳滤波复原

维纳滤波复原对运动模糊复原效果较好。在matlab中用deconvwnr进行图像的维纳滤波复原。
维纳滤波引入了信噪比,当信噪比为0时其实就是逆滤波。用于逆滤波的算子可以写为:

%H为滤波用算子
G = 1./H.*(abs(H).^2./(abs(H).^2+NSR));

其实就是通过信噪比来自动选择上面所说的频率范围。。
(换汤不换药,实际上没好到哪去,不过复原原理本来就是这样)

3.3 约束最小二乘法复原

在matlab中,使用deconvreg来进行最小约束二乘法复原。这种方法需要知道噪声方差和均值的先验知识。
实际上,就是一个约束条件下,使得图像最平滑。用一个最小准则函数c,c 为图像的二阶导数在整个图像区域的积分。得到c的最小值的方法采用拉格朗日乘数法,所以这种方法叫约束最小二乘法复原。

close all;
clear all;
clc;
I = im2double(imread('img.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('约束最小二乘方滤波后图像');

3.4 Lucy-Richardson复原

Lucy-Richardson法就是用迭代的方法实现一个加速收敛,迭代次数少了复原不够,迭代次数多了有振铃效应。至于原理,好像是包括了极大似然和EM算法,who cares 反正知道了迭代式就可以直接跨语言使用了,分析原理有时间再说啦。。
我们可以用画信噪比和峰值信噪比的曲线来确定最佳的迭代次数,直接代进去使用就可以了。顺便说一下,matlab中Lucy-Richardson复原的函数是deconvlucy

3.5 盲解卷积复原

前面这些复原方法,需要知道图像,退化时的psf。不过在实际应用中,psf一般不容易被知道,这种情况我们就可以用盲解卷积复原。不过我们还是需要输入一个psf的估计值,在matlab中我们用deconvblind来实现盲解卷积复原。
一般盲解卷积复原初步复原后会有很大的振铃效应,使用WEIGHT参数可以消除这些效应。首先调用edge查到图像中灰度变换较大的区域,然后膨胀图像以扩充处理区域;边界与灰度变化较大的地方会被设置为0。然后再对图像重建,搞来搞去就会消除大部分的振铃效应啦!(实际上我也没搞太懂,可以看看别人转的matlab程序,虽然他也是转载的,不过转到了原创里我也不知道能不能直接转,直接给出链接:https://blog.csdn.net/mingtian715/article/details/67637458)

今天就这样。。这部分好难啊,我也没搞太清楚,希望有大牛可以在这方面,把我没说清楚的地方说清楚,可能日后仔细研究,看英文文献的时候会在番外部分给出详细的翻译和理论思路和推导吧。。

你可能感兴趣的:(心得体会)