0
点赞
收藏
分享

微信扫一扫

【OpenCV 完整例程】88. 频率域拉普拉斯高通滤波

【OpenCV 完整例程】88. 频率域拉普拉斯高通滤波


4.3 频率域拉普拉斯高通滤波

拉普拉斯算子(Laplace)是导数算子,会突出图像中的急剧灰度变化,抑制灰度缓慢变化区域,往往会产生暗色背景下的灰色边缘和不连续图像。将拉普拉斯图像与原图叠加,可以得到保留锐化效果的图像。

拉普拉斯算子(Laplace)是最简单的各向同性导数算子(卷积核):
∇ 2 f = ∂ 2 f ∂ x 2 + ∂ 2 f ∂ y 2 ∂ 2 f ∂ x 2 = f ( x + 1 , y ) − 2 f ( x , y ) + f ( x − 1 , y ) ∂ 2 f ∂ y 2 = f ( x , y + 1 ) − 2 f ( x , y ) + f ( x , y − 1 ) ∇ 2 f ( x , y ) = f ( x + 1 , y ) + f ( x − 1 , y ) + f ( x , y + 1 ) + f ( x , y − 1 ) − 4 f ( x , y ) \begin{aligned} \nabla ^2 f &= \dfrac{\partial ^2 f}{\partial x ^2} + \dfrac{\partial ^2 f}{\partial y ^2} \\ \dfrac{\partial ^2 f}{\partial x ^2} &= f(x+1,y) - 2f(x,y) + f(x-1,y) \\ \dfrac{\partial ^2 f}{\partial y ^2} &= f(x,y+1) - 2f(x,y) + f(x,y-1) \\ \nabla ^2 f(x,y) &= f(x+1,y) + f(x-1,y) + f(x,y+1) + f(x,y-1) - 4f(x,y) \end{aligned} 2fx22fy22f2f(x,y)=x22f+y22f=f(x+1,y)2f(x,y)+f(x1,y)=f(x,y+1)2f(x,y)+f(x,y1)=f(x+1,y)+f(x1,y)+f(x,y+1)+f(x,y1)4f(x,y)

于是可以得到空间域拉普拉斯核 K1,考虑对角项后可以得到拉普拉斯核 K2。

K 1 = [ 0 1 0 1 − 4 1 0 1 0 ] ,   K 2 = [ 1 1 1 1 − 8 1 1 1 1 ] ,   K 3 = [ 0 − 1 0 − 1 4 − 1 0 − 1 0 ] ,   K 4 = [ − 1 − 1 − 1 − 1 8 − 1 − 1 − 1 − 1 ] K1= \begin{bmatrix} 0 & 1 &0\\ 1 & -4 &1\\ 0 & 1 &0\\ \end{bmatrix}, \ K2= \begin{bmatrix} 1 & 1 &1\\ 1 & -8 &1\\ 1 & 1 &1\\ \end{bmatrix}, \ K3= \begin{bmatrix} 0 & -1 &0\\ -1 & 4 &-1\\ 0 & -1 &0\\ \end{bmatrix}, \ K4= \begin{bmatrix} -1 & -1 &-1\\ -1 & 8 &-1\\ -1 & -1 &-1\\ \end{bmatrix} K1=010141010, K2=111181111, K3=010141010, K4=111181111

在频率域中拉普拉斯算子可以用传递函数描述:

H ( u , v ) = − 4 π 2 ( u 2 + v 2 ) H(u,v) = - 4 \pi ^2 (u^2 + v^2) H(u,v)=4π2(u2+v2)
采用 D(u,v) 表示到频率中心的距离函数,可以进一步表示为:
H ( u , v ) = − 4 π 2 [ ( u − P / 2 ) 2 + ( v − Q / 2 ) 2 ] = − 4 π 2 D 2 ( u , v ) H(u,v) = - 4 \pi ^2 [(u-P/2)^2 + (v-Q/2)^2] = - 4 \pi ^2 D^2(u,v) H(u,v)=4π2[(uP/2)2+(vQ/2)2]=4π2D2(u,v)

于是,

∇ 2 f ( x , y ) = J − 1 { H ( u , v ) F ( u , v ) } g ( x , y ) = f ( x , y ) + c ∇ 2 f ( x , y ) = J − 1 { [ 1 + 4 π 2 D 2 ( u , v ) ] F ( u , v ) } \nabla ^2 f(x,y) = J^{-1} \{H(u,v) F(u,v)\}\\ g(x,y)= f(x,y) + c \nabla ^2 f(x,y) \\ = J^{-1} \{[1+4 \pi ^2 D^2(u,v)] F(u,v)\} 2f(x,y)=J1{H(u,v)F(u,v)}g(x,y)=f(x,y)+c2f(x,y)=J1{[1+4π2D2(u,v)]F(u,v)}


例程 8.27:频率域图像锐化(拉普拉斯算子)

# OpenCVdemo08.py
# Demo08 of OpenCV
# 8. 图像的频率域滤波
# Copyright 2021 Youcans, XUPT
# Crated:2021-12-30    

# 8.27:频率域图像锐化(拉普拉斯算子)
    def LaplacianFilter(shape):  # 频域 Laplacian 滤波器
        u, v = np.mgrid[-1:1:2.0/shape[0], -1:1:2.0/shape[1]]
        D = np.sqrt(u**2 + v**2)
        kernel = -4 * np.pi**2 * D**2
        return kernel

    def imgHPfilter(image, lpTyper="Laplacian"):  # 频域高通滤波
        # (1) 中心化, centralized 2d array f(x,y) * (-1)^(x+y)
        mask = np.ones(image.shape)
        mask[1::2, ::2] = -1
        mask[::2, 1::2] = -1
        fImage = image * mask  # f(x,y) * (-1)^(x+y)

        # (2) 最优 DFT 扩充尺寸, 快速傅里叶变换的尺寸扩充
        rows, cols = image.shape[:2]  # 原始图片的高度和宽度
        rPadded = cv2.getOptimalDFTSize(rows)  # 最优 DFT 扩充尺寸
        cPadded = cv2.getOptimalDFTSize(cols)  # 用于快速傅里叶变换

        # (3) 边缘扩充(补0), 快速傅里叶变换
        dftImage = np.zeros((rPadded, cPadded, 2), np.float32)  # 对原始图像进行边缘扩充
        dftImage[:rows, :cols, 0] = fImage  # 边缘扩充,下侧和右侧补0
        cv2.dft(dftImage, dftImage, cv2.DFT_COMPLEX_OUTPUT)  # 快速傅里叶变换 (rPad, cPad, 2)

        # (4) 构建 频域滤波器传递函数: 以 Laplacian 为例
        LapFilter = LaplacianFilter((rPadded, cPadded))  # 拉普拉斯滤波器

        # (5) 在频率域修改傅里叶变换: 傅里叶变换 点乘 滤波器传递函数
        dftFilter = np.zeros(dftImage.shape, dftImage.dtype)  # 快速傅里叶变换的尺寸(优化尺寸)
        for j in range(2):
            dftFilter[:rPadded, :cPadded, j] = dftImage[:rPadded, :cPadded, j] * LapFilter

        # (6) 对高通傅里叶变换 执行傅里叶逆变换,并只取实部
        idft = np.zeros(dftImage.shape[:2], np.float32)  # 快速傅里叶变换的尺寸(优化尺寸)
        cv2.dft(dftFilter, idft, cv2.DFT_REAL_OUTPUT + cv2.DFT_INVERSE + cv2.DFT_SCALE)

        # (7) 中心化, centralized 2d array g(x,y) * (-1)^(x+y)
        mask2 = np.ones(dftImage.shape[:2])
        mask2[1::2, ::2] = -1
        mask2[::2, 1::2] = -1
        idftCen = idft * mask2  # g(x,y) * (-1)^(x+y)

        # (8) 截取左上角,大小和输入图像相等
        result = np.clip(idftCen, 0, 255)  # 截断函数,将数值限制在 [0,255]
        imgFilter = result.astype(np.uint8)
        imgFilter = imgFilter[:rows, :cols]
        return imgFilter


    # (1) 读取原始图像
    img = cv2.imread("../images/Fig0338a.tif", flags=0)  # NASA 月球影像图
    rows, cols = img.shape[:2]  # 图片的高度和宽度
    print(rows, cols)

    # (2) 空间域 拉普拉斯算子 (Laplacian)
    # 使用函数 filter2D 实现 Laplace 卷积算子
    kernLaplace = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])  # Laplacian kernel
    imgLaplace1 = cv2.filter2D(img, -1, kernLaplace, borderType=cv2.BORDER_REFLECT)
    # 使用 cv2.Laplacian 实现 Laplace 卷积算子
    imgLaplace2 = cv2.Laplacian(img, -1, ksize=3)
    imgLapReSpace = cv2.add(img, imgLaplace2)  # 恢复原图像

    # (3) 频率域 拉普拉斯算子 (Laplacian)
    imgLaplace = imgHPfilter(img, "Laplacian")  # 调用自定义函数 imgHPfilter()
    imgLapRe = cv2.add(img, imgLaplace)  # 恢复原图像

    plt.figure(figsize=(10, 6))
    plt.subplot(131), plt.imshow(img, 'gray'), plt.title("Origin from NASA"), plt.xticks([]), plt.yticks([])
    plt.subplot(132), plt.imshow(imgLapReSpace, 'gray'), plt.title("Spatial Lapalacian"), plt.xticks([]), plt.yticks([])
    plt.subplot(133), plt.imshow(imgLapRe, 'gray'), plt.title("Freauency Lapalacian"), plt.xticks([]), plt.yticks([])
    plt.tight_layout()
    plt.show()

在这里插入图片描述


(本节完)


版权声明:

youcans@xupt 原创作品,转载必须标注原文链接

Copyright 2021 youcans, XUPT

Crated:2022-2-1


举报

相关推荐

0 条评论