Python+OpenCV:图像梯度

82 篇文章 20 订阅

Python+OpenCV:图像梯度(Image Gradients)

理论

OpenCV提供了三种类型的梯度滤波器或高通滤波器,Sobel, Scharr和Laplacian。

1. Sobel和Scharr导数

Sobel算子是一种联合高斯平滑加微分运算,具有较强的抗噪声能力。

您可以指定要取的导数的方向,垂直的或水平的(分别通过参数yorder和xorder)。

你也可以通过参数ksize来指定内核的大小。

如果ksize = -1,则使用3x3的Scharr滤波器,其结果优于3x3的Sobel滤波器。

请查看文档中使用的内核。

2. Laplacian导数

它计算由关系给出的图像的拉普拉斯算子,其中每个导数都使用Sobel导数找到。

如果ksize = 1,则使用下面的内核进行过滤:

示例

####################################################################################################
# 图像梯度(Image Gradients)
def lmc_cv_image_gradients():
    """
        函数功能: 图像梯度(Image Gradients).
    """

    # 读取图像
    image = lmc_cv.imread('D:/99-Research/Python/Image/Sudoku.jpg')
    image = lmc_cv.cvtColor(image, lmc_cv.COLOR_BGR2GRAY)

    # 图像梯度(Image Gradients)
    laplacian_image = lmc_cv.Laplacian(image, lmc_cv.CV_64F, ksize=3, scale=1, delta=0,
                                       borderType=lmc_cv.BORDER_DEFAULT)
    sobelx_image = lmc_cv.Sobel(image, lmc_cv.CV_64F, 1, 0, ksize=5, scale=1, delta=0,
                                borderType=lmc_cv.BORDER_DEFAULT)
    sobely_image = lmc_cv.Sobel(image, lmc_cv.CV_64F, 0, 1, ksize=5, scale=1, delta=0,
                                borderType=lmc_cv.BORDER_DEFAULT)

    # 显示图像
    pyplot.figure('Image Display')
    titles = ['Original', 'Laplacian', 'Sobel X', 'Sobel Y']
    images = [image, laplacian_image, sobelx_image, sobely_image]
    for i in range(4):
        pyplot.subplot(2, 2, i + 1)
        pyplot.imshow(images[i], 'gray')
        pyplot.title(titles[i])
        pyplot.xticks([])
        pyplot.yticks([])
    pyplot.show()

    # 根据用户输入保存图像
    if ord("q") == (lmc_cv.waitKey(0) & 0xFF):
        # 销毁窗口
        pyplot.close()
    return

强调

在上一个例子中,输出数据类型是cv.CV_8U或np.uint8。但这有一个小问题,黑到白的过渡被认为是正斜率(它有一个正值),而白到黑的过渡被认为是负斜率(它有一个负值)。

所以当你把数据转换成np.uint8,所有负斜率均为零。简单地说,你错过了这条边。

如果您想检测这两个边,更好的选择是保持输出数据类型为一些更高的形式,如cv.CV_16S, cv.CV_64F等,取其绝对值,然后转换回cv.CV_8U。

下面的代码演示了水平Sobel滤波器的这个过程和结果的不同。

####################################################################################################
# 正负梯度(Positive-Negative slope)
def lmc_cv_positive_negative_slope():
    """
        函数功能: 正负梯度(Positive-Negative slope).
    """

    # 读取图像
    image = lmc_cv.imread('D:/99-Research/Python/Image/Box.png')
    image = lmc_cv.cvtColor(image, lmc_cv.COLOR_BGR2GRAY)

    # 正负梯度(Positive-Negative slope)
    # Output dtype = cv.CV_8U
    sobelx8u_image1 = lmc_cv.Sobel(image, lmc_cv.CV_8U, 1, 0, ksize=5, scale=1, delta=0,
                                   borderType=lmc_cv.BORDER_DEFAULT)
    # Output dtype = cv.CV_64F. Then take its absolute and convert to cv.CV_8U
    sobelx64f_image = lmc_cv.Sobel(image, lmc_cv.CV_64F, 1, 0, ksize=5, scale=1, delta=0,
                                   borderType=lmc_cv.BORDER_DEFAULT)
    abs_sobel64f_image = np.absolute(sobelx64f_image)
    sobelx8u_image2 = np.uint8(abs_sobel64f_image)

    # 显示图像
    pyplot.figure('Image Display')
    titles = ['Original', 'Sobel CV_8U', 'Sobel abs(CV_64F)']
    images = [image, sobelx8u_image1, sobelx8u_image2]
    for i in range(3):
        pyplot.subplot(1, 3, i + 1)
        pyplot.imshow(images[i], 'gray')
        pyplot.title(titles[i])
        pyplot.xticks([])
        pyplot.yticks([])
    pyplot.show()

    # 根据用户输入保存图像
    if ord("q") == (lmc_cv.waitKey(0) & 0xFF):
        # 销毁窗口
        pyplot.close()
    return

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值