查看原文
其他

OpenCV中图像频率域滤波

gloomyfish OpenCV学堂 2020-02-04

点击上方↑↑↑“OpenCV学堂”关注我

代码演示如何在图像频率域实现卷积模糊与梯度提取

图像频率域

图像处理不仅可以在空间域进行还可以在频率域进行,把空间域的图像开窗卷积形式,变换得到频率域的矩阵点乘形式得到比较好的效果。转换到频率域最常见的是通过傅里叶变换得到图像的频率域表示,处理之后再反变换回去。支持各种卷积处理的效果,比如模糊,梯度提取等,OpenCV中支持傅里叶变换与逆变换的函数分别为

# 傅里叶变换函数
void cv::dft(
    InputArray src,
    OutputArray dst,
    int flags = 0,
    int nonzeroRows = 0 
)
# 傅里叶逆变换函数
void cv::idft(
    InputArray src,
    OutputArray dst,
    int flags = 0,
    int nonzeroRows = 0 
)

低通滤波

低通滤波可以看成是卷积模糊在频率域的表现形式,代码实现如下:

def low_pass_filter_demo():
    image = cv.imread("D:/images/test1.png", cv.IMREAD_GRAYSCALE)
    img_float32 = np.float32(image)

    rows, cols = image.shape
    crow, ccol = rows//2 , cols//2

    # FFT变换
    dft = cv.dft(img_float32, flags = cv.DFT_COMPLEX_OUTPUT)
    dft_shift = np.fft.fftshift(dft)

    # 创建低通滤波器,低频区域为 1, 高频区域为 0
    mask = np.zeros((rows, cols, 2), np.uint8)
    mask[crow-30:crow+30, ccol-30:ccol+30] = 1

    # 滤波
    fshift = dft_shift*mask

    # 逆变换
    f_ishift = np.fft.ifftshift(fshift)
    img_back = cv.idft(f_ishift)
    img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])
    cv.normalize(img_back, img_back, 01.0, cv.NORM_MINMAX)

    cv.imshow("input", image);
    cv.imshow("low-pass-filter", img_back)
    cv.imwrite("D:/low_pass.png", np.uint8(img_back*255))
    cv.waitKey(0)
    cv.destroyAllWindows()

高通滤波

高通滤波可以看成是图像梯度在频率域的计算,代码实现如下:

def high_pass_filter_demo():
    image = cv.imread("D:/images/test1.png", cv.IMREAD_GRAYSCALE)
    img_float32 = np.float32(image)

    rows, cols = image.shape
    crow, ccol = rows//2 , cols//2

    # FFT变换
    dft = cv.dft(img_float32, flags = cv.DFT_COMPLEX_OUTPUT)
    dft_shift = np.fft.fftshift(dft)

    # 创建高通滤波器,低频区域为 0, 高频区域为 1
    mask = np.ones((rows, cols, 2), np.uint8)
    mask[crow-30:crow+30, ccol-30:ccol+30] = 0

    # 滤波
    fshift = dft_shift*mask

    # 逆变换
    f_ishift = np.fft.ifftshift(fshift)
    img_back = cv.idft(f_ishift)
    img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])
    cv.normalize(img_back, img_back, 01.0, cv.NORM_MINMAX)

    cv.imshow("input", image);
    cv.imshow("high-pass-filter", img_back)
    cv.imwrite("D:/high_pass.png", np.uint8(img_back*255))
    cv.waitKey(0)
    cv.destroyAllWindows()

运行效果如下:


往期精选

告诉大家你 在看

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存