OpenCV-Python系列之顶帽与黑帽操作

上个教程中我们遗留了一些问题,那就是经过图像开运算或者是闭运算之后亮度会发生变化,这就会对后期的图像处理造成一定的困扰,所以本次教程我们介绍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:膨胀

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

posted @ 2021-12-07 14:52  wuyuan2011woaini  阅读(504)  评论(0编辑  收藏  举报