1. 概述
图像的退化是一个很常见的现象,现实中,很可能因为成像系统的缺陷,或者一些认为的干扰导致图像退化。对于退化,可以用如下模型表示:
空域:
频域:
其中h/H表示退化模型,而/N表示噪声。
如果我们知道退化模型的化,对现有的图像做一次逆操作,就可以复原出原始的图像。即:
空域:(这里的/表示卷积的逆操作,因为不知道用什么表示,暂时用这个表示)
频域:
先看空域的表达,卷积的操作的逆操作根本无法想象到底是个什么东西。而在频域,则变成了求商。在空域求卷积和在频域求积是一样的,因此在这里,我们可以在频域做逆滤波的操作。
再观察频域的表达式,我们也可以得到一些信息:(1) 因为不可知,即使知道了图像的退化模型,也不能完全的复原出图像。(2) 在退化函数
很小的时候,
会被忽略掉。
2. 图像的运动模糊
运动模糊是由于相对运动引入的模糊,那么其退化模型就是相对运动。在本节,我们给图像模拟运动模糊。步骤如下:
1. 获取空域点扩散模型,在这里,我们用空域的退化模型去得到频域的退化模型。
2. 获取源图像的傅里叶变换和点扩散模型的傅里叶变换,将其相乘,再做傅里叶反变换,得到模糊后的图像。
代码如下:
def get_motion_dsf(image_size, motion_angle, motion_dis):
"""
获取运动模糊的点扩散函数模板
:param image_size: 图像的大小
:param motion_angle: 运动的角度,单位为度,正常直角坐标系方向
:param motion_dis: 运动的距离,以像素点为单位
:return: numpy.ndarray
"""
PSF = np.zeros(image_size) # 点扩散函数
x_center = (image_size[0] - 1) / 2
y_center = (image_size[1] - 1) / 2
sin_val = math.sin(motion_angle * math.pi / 180)
cos_val = math.cos(motion_angle * math.pi / 180)
# 将对应角度上motion_dis个点置成1
for i in range(motion_dis):
x_offset = round(sin_val * i)
y_offset = round(cos_val * i)
PSF[int(x_center - x_offset), int(y_center + y_offset)] = 1
return PSF / PSF.sum() # 归一化
def motion_blurred(img, psf, eps):
"""
:param input: 输入图像
:param PSF: 点扩散模板
:param eps: 噪声功率
:return:
"""
img_fft = np.fft.fft2(img)
psf_fft = np.fft.fft2(psf) + eps
blurred_img = np.fft.ifft2(img_fft * psf_fft)
blurred_img = np.abs(np.fft.fftshift(blurred))
return blurred_img
def motion_test(img):
PSF = get_motion_dsf(img.shape, 45, 50) # 相对运动的卷积模板
blurred_img = motion_blurred(img, PSF, 1e-3)
3. 运动模糊图像的逆滤波
综上,我们对有运动模糊的图像在频域做除,就可以复原图像,代码如下:
def inverse_filter(img, psf, eps):
"""
对输入图像进行逆滤波
:param img: 输入图像
:param psf: 点扩散模型
:param eps: 噪声功率
:return: 逆滤波结果
"""
img_fft = np.fft.fft2(img)
psf_fft = np.fft.fft2(psf) + eps
result = np.fft.ifft2(img_fft / psf_fft)
result = np.abs(np.fft.fftshift(result))
return result
def motion_test(img):
PSF = get_motion_dsf(img.shape, 45, 50) # 相对运动的卷积模板
blurred_img = motion_blurred(img, PSF, 1e-3)
back_img = inverse_filter(blurred_img, PSF, 1e-3)
mp = my_plt(1, 3)
mp.imshow('motion blur', blurred)
dst = np.zeros(PSF.shape)
norm_psf = cv2.normalize(PSF, dst, 1.0, 0.0, cv2.NORM_MINMAX)
mp.imshow('psf', (norm_psf*255).astype(np.uint8))
mp.imshow('back img', back_img)
mp.show()
运行结果如下:
其中motion blur为模拟运动模糊之后的结果;psf为点扩散模型,图中为45度的运动的话,图像为一个从中心开始从45度走的线;back img为motion blur逆滤波的结果。