运动模糊与还原

运动模糊是指由于相机和物体之间的相对运动造成的模糊,又称为动态模糊。

一、已知模糊核的运动模糊

在已知模糊运动核的前提下,可通过核线性卷积的形式对图像添加运动模糊。

#-*- coding:utf-8 -*-
import cv2 as cv
import numpy as np
import math
from PIL import Image
import matplotlib.pyplot as plt

def motion_PSF(image_size, motion_angle, motion_dis):
    '''
    建立退化模型,仿真运动模糊
    INPUT -> 图像尺寸, 运动角度, 模糊尺度
    OUTPUT -> PSF(点扩散函数)
    '''
    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 make_blurred(img_arr, PSF, eps):
    '''
    对图片进行运动模糊
    INPUT -> 图像数组, PSF(点扩散函数), 噪声
    OUTPUT -> 模糊后的图像
    '''
    # 将空间域转化为频率域
    img_f = np.fft.fft2(img_arr)

    PSF_f = np.fft.fft2(PSF)

    blurred = np.fft.ifft2(img_f * PSF_f)
    blurred = np.abs(np.fft.fftshift(blurred))
    return blurred

def array_to_image(image_arr):
    '''
    数组还原为图片
    INPUT  -> 数组
    OUTPUT -> 单张图文件
    '''
    if len(image_arr.shape) == 3:  # 格式为(height(rows), weight(colums), 3)
        r = Image.fromarray(np.uint8(image_arr[:,:,0]))
        g = Image.fromarray(np.uint8(image_arr[:,:,1]))
        b = Image.fromarray(np.uint8(image_arr[:,:,2]))
        image = Image.merge("RGB", (r, g, b))
        return image        
    elif len(image_arr.shape) == 2:  # 格式为(height(rows), weight(colums))
        return Image.fromarray(np.uint8(image_arr))

img_arr = np.array(Image.open('tools/33.jpg').convert('L'))
PSF = motion_PSF((img_arr.shape[0], img_arr.shape[1]), 30, 15)
blurred = make_blurred(img_arr, PSF, 1e-4)

# 可视化
plt.imshow(array_to_image(blurred))
plt.show()

反之也可利用该核精确的去除该运动模糊。
使用逆滤波可以精确还原图像,但是它对噪声非常敏感。
最小均方差(维纳)滤波用来还原含有噪声的模糊图像,但是需要估计图像的信噪比(SNR)或者噪信比(NSR)。若无噪声,此时维纳滤波相当于逆滤波,恢复运动模糊效果是极好的。

def inverse(blurred, PSF, eps):
    '''
    逆滤波图像还原
    INPUT  -> 模糊图像, 点扩散函数, 噪声
    '''
    blurred_f = np.fft.fft2(blurred)

    PSF_f = np.fft.fft2(PSF) + eps  # 噪声功率

    result = np.fft.ifft2(blurred_f / PSF_f) # 计算F(u,v)的傅里叶反变换
    result = np.abs(np.fft.fftshift(result))
    return result

def wiener(blurred, PSF, eps, SNR=0.001):
    '''
    维纳滤波图像还原
    INPUT  -> 模糊图像, 点扩散函数, 噪声功率, 信噪比0.01
    '''
    blurred_f = np.fft.fft2(blurred)

    PSF_f = np.fft.fft2(PSF) + eps
    PSF_f_1 = np.conj(PSF_f) /(np.abs(PSF_f)**2 + SNR)

    result = np.fft.ifft2(blurred_f * PSF_f_1)
    result = np.abs(np.fft.fftshift(result))
    return result

img2 = inverse(blurred, PSF, 0)
img2 = wiener(blurred, PSF, 0)

二、未知模糊核的运动模糊

在实际应用场景是不知道的运动模糊的卷积核的。

1、Richardson-Lucy算法

Richardson–Lucy算法是一个在泊松噪声背景下用于图像恢复的迭代技术。迭代公式:



对于没有噪声干扰的理想模糊图像,迭代次数越多恢复的效果越好。每次迭代时,都会提高解的似然性,随着迭代次数的增加,最终将会收敛在最大似然性的解,但随着迭代次数的增加也会增加计算量。
对于含有噪声干扰的模糊图像,随着迭代次数的增加噪声被放大,而且迭代时间随之增长。当迭代超过50次后,恢复结果并没有明显改观。

2、基于GAN的去运动模糊

DeblurGAN是Orest Kupyn等人于17年11月提出的一种模型。他们结合GAN和多元内容损失来构建DeblurGAN,以实现对运动图像的去模糊化。
DeblurGAN

你可能感兴趣的:(运动模糊与还原)