美文网首页人工智能
如何还原模糊的车牌----维纳反卷积滤波算法

如何还原模糊的车牌----维纳反卷积滤波算法

作者: gaoshine | 来源:发表于2018-07-10 21:53 被阅读567次

    Wiener deconv

    opencv学习笔记---维纳反卷积滤波算法演示 ,算法参考[维基百科:https://en.wikipedia.org/wiki/Wiener_deconvolution
    本例将使用算法实现模糊车牌的清晰化处理,使用Wiener反卷积算法,将因动态拍摄不清楚的车牌还原出来.

    licenseplate_motion.jpg Screen Shot 2018-07-10 at 21.59.10.png wienerdeconv.png

    维纳反卷积分滤波,常用图像复原,降噪处理,本例中模糊的车牌是运动造成的,通过反卷积滤波,调整卷积滤波的角度,距离和增加噪音,通过反卷积运算,还原出清楚的图像.

    from __future__ import print_function
    
    import numpy as np
    import cv2 as cv
    
    
    def blur_edge(img, d=31):
        h, w  = img.shape[:2]
        img_pad = cv.copyMakeBorder(img, d, d, d, d, cv.BORDER_WRAP)
        img_blur = cv.GaussianBlur(img_pad, (2*d+1, 2*d+1), -1)[d:-d,d:-d]
        y, x = np.indices((h, w))
        dist = np.dstack([x, w-x-1, y, h-y-1]).min(-1)
        w = np.minimum(np.float32(dist)/d, 1.0)
        return img*w + img_blur*(1-w)
    
    def motion_kernel(angle, d, sz=65):
        kern = np.ones((1, d), np.float32)
        c, s = np.cos(angle), np.sin(angle)
        A = np.float32([[c, -s, 0], [s, c, 0]])
        sz2 = sz // 2
        A[:,2] = (sz2, sz2) - np.dot(A[:,:2], ((d-1)*0.5, 0))
        kern = cv.warpAffine(kern, A, (sz, sz), flags=cv.INTER_CUBIC)
        return kern
    
    def defocus_kernel(d, sz=65):
        kern = np.zeros((sz, sz), np.uint8)
        cv.circle(kern, (sz, sz), d, 255, -1, cv.LINE_AA, shift=1)
        kern = np.float32(kern) / 255.0
        return kern
    
    
    if __name__ == '__main__':
    
        import sys
        fn = 'data/licenseplate_motion.jpg'
        win = 'deconvolution'
    
        img = cv.imread(fn, 0)
        if img is None:
            print('Failed to load file:', fn)
            sys.exit(1)
    
        img = np.float32(img)/255.0
        cv.imshow('input', img)
    
        img = blur_edge(img)
        IMG = cv.dft(img, flags=cv.DFT_COMPLEX_OUTPUT)
    
        defocus = '--circle'
    
        def update(_):
            ang = np.deg2rad( cv.getTrackbarPos('angle', win) )
            d = cv.getTrackbarPos('d', win)
            noise = 10**(-0.1*cv.getTrackbarPos('SNR (db)', win))
    
            if defocus:
                psf = defocus_kernel(d)
            else:
                psf = motion_kernel(ang, d)
            cv.imshow('psf', psf)
    
            psf /= psf.sum()
            psf_pad = np.zeros_like(img)
            kh, kw = psf.shape
            psf_pad[:kh, :kw] = psf
            PSF = cv.dft(psf_pad, flags=cv.DFT_COMPLEX_OUTPUT, nonzeroRows = kh)
            PSF2 = (PSF**2).sum(-1)
            iPSF = PSF / (PSF2 + noise)[...,np.newaxis]
            RES = cv.mulSpectrums(IMG, iPSF, 0)
            res = cv.idft(RES, flags=cv.DFT_SCALE | cv.DFT_REAL_OUTPUT )
            res = np.roll(res, -kh//2, 0)
            res = np.roll(res, -kw//2, 1)
            cv.imshow(win, res)
    
        cv.namedWindow(win)
        cv.namedWindow('psf', 0)
        cv.createTrackbar('angle', win, 135, 180, update)
        cv.createTrackbar('d', win, 22, 50, update)
        cv.createTrackbar('SNR (db)', win, 25, 50, update)
        update(None)
    
        while True:
            ch = cv.waitKey()
            if ch == 27:
                break
            if ch == ord(' '):
                defocus = not defocus
                update(None)
    
    
    Screen Shot 2018-07-10 at 21.59.10.png

    相关文章

      网友评论

        本文标题:如何还原模糊的车牌----维纳反卷积滤波算法

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