zoukankan      html  css  js  c++  java
  • OpenCVPython系列之顶帽与黑帽操作

    上个教程中我们遗留了一些问题,那就是经过图像开运算或者是闭运算之后亮度会发生变化,这就会对后期的图像处理造成一定的困扰,所以本次教程我们介绍OpenCV的顶帽与黑帽运算,来解决这些问题。

    顶帽

    顶帽运算又常常被译为”礼帽“运算。为原图像与上文刚刚介绍的“开运算“的结果图之差,数学表达式如下:

    image.png

    因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

    帽运算往往用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用顶帽运算进行背景提取。

    现在我们来进行一些实战操作,我们先来看一幅图片:

    image.png

    这是之后我们将要讲述的一个是实战案例-卡片上的数字识别,首先我们需要做的就是对图像先进行灰度化,然后再进行阈值化,这样才方便后期提取轮廓,我们先来用OTSU算法进行阈值化:

    import cv2
    import numpy as np
    
    
    img = cv2.imread('credit_card_.png')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    threshold = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV|
                              cv2.THRESH_OTSU)[1]
    cv2.imshow("img",img)
    cv2.imshow("thres",threshold)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    image.png

    事实情况很糟糕,这样的阈值化根本无法让我们进行下一步的操作,我们看原图发现右下角的字体与背景的亮度都有些高,所以会出现这种情况,现在想让字体与背景分离出来,我们可以用顶帽操作对前景进行明亮化:

    import cv2
    import numpy as np
    
    
    img = cv2.imread('credit_card_.png')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(21,21))
    tophat = cv2.morphologyEx(gray,cv2.MORPH_TOPHAT,kernel)
    threshold = cv2.threshold(gray,0,255,cv2.THRESH_BINARY_INV|
                              cv2.THRESH_OTSU)[1]
    cv2.imshow("img",img)
    cv2.imshow("thres",threshold)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    image.png

    我们再来看这样的效果是不是好的多了?中间的数字字体被完整的分离了出来,事实上,在很多地方我们经常会用到顶帽操作。

    黑帽

    黑帽运算为”闭运算“的结果图与原图像之差。数学表达式为:

    image.png

    黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。所以,黑帽运算用来分离比邻近点暗一些的斑块。非常完美的轮廓效果图,同样我们来看实例代码:

    import cv2
    import numpy as np
    
    
    img = cv2.imread('close.jpg')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
    tophat = cv2.morphologyEx(gray,cv2.MORPH_BLACKHAT,kernel)
    cv2.imshow("img",img)
    cv2.imshow("thres",tophat)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    image.png

    形态学梯度

    现在我们来看OpenCV形态学处理中的最后一个操作——形态学梯度,它本质上就是对图像的边缘提取,也可以说是膨胀的结果减去腐蚀的结果,我们来看实际效果:

    import cv2
    import numpy as np
    
    
    img = cv2.imread('close.jpg')
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))
    tophat = cv2.morphologyEx(gray,cv2.MORPH_GRADIENT,kernel)
    cv2.imshow("img",img)
    cv2.imshow("thres",tophat)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    image.png

    这就对图像的边缘进行了检测。

    本次教程的结束同时也意味着OpenCV中形态学处理部分的结束,实际上我们发现,它们都可以用一个函数API来进行调用:

    cv2. morphologyEx()

    关于它我们在前面已经有所介绍,现在总结一下,它总共可以进行这些操作:

    (1)MORPH_OPEN:开运算

    (2)MORPH_CLOSE:闭运算

    (3)MORPH_GRADIENT:形态学梯度

    (4)MORPH_TOPHAT:顶帽

    (5)MORPH_BLACKHAT:黑帽

    (6)MORPH_ERODE:腐蚀

    (7)MORPH_DILATE:膨胀

    图像形态学的处理是非常重要的,大家一定要熟练掌握。

  • 相关阅读:
    88. Merge Sorted Array
    87. Scramble String
    86. Partition List
    85. Maximal Rectangle
    84. Largest Rectangle in Histogram
    83. Remove Duplicates from Sorted List
    82. Remove Duplicates from Sorted List II
    81. Search in Rotated Sorted Array II
    80. Remove Duplicates from Sorted Array II
    计算几何——点线关系(叉积)poj2318
  • 原文地址:https://www.cnblogs.com/wuyuan2011woaini/p/15656160.html
Copyright © 2011-2022 走看看