美文网首页
运动模糊与还原

运动模糊与还原

作者: Byte猫 | 来源:发表于2019-05-21 17:03 被阅读0次

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

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

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

    #-*- 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

    相关文章

      网友评论

          本文标题:运动模糊与还原

          本文链接:https://www.haomeiwen.com/subject/ziajaqtx.html