OpenCV中的形态学转换操作有七种:腐蚀,膨胀,开运算,闭运算,形态学梯度,礼帽,黑帽。
中文名 | 英文名 | api | 原理 | 个人理解 |
---|---|---|---|---|
腐蚀 | erode | erosion = cv2.erode(src=girl_pic, kernel=kernel) | 对滑窗中的像素点按位乘,再从中取最小值点作为输出。可以去浅色噪点 | 浅色成分被腐蚀 |
膨胀 | dilate | dilation = cv2.dilate(src=girl_pic, kernel=kernel) | 对滑窗中的像素点按位乘,再从中取最大值点作为输出。可以增加浅色成分 | 浅色成分得膨胀 |
开运算 | morphology-open | opening = cv2.morphologyEx(girl_pic, cv2.MORPH_OPEN, kernel) | 先腐蚀,后膨胀,去白噪点 | 先合再开,对浅色成分不利 |
闭运算 | morphology-close | closing = cv2.morphologyEx(girl_pic, cv2.MORPH_CLOSE, kernel) | 先膨胀,后腐蚀,去黑噪点 | 先开再合,浅色成分得势 |
形态学梯度 | morphology-grandient | gradient = cv2.morphologyEx(girl_pic, cv2.MORPH_GRADIENT, kernel) | 一幅图像腐蚀与膨胀的区别,可以得到轮廓 | 数值上解释为:膨胀减去腐蚀 |
礼帽 | tophat | tophat = cv2.morphologyEx(girl_pic, cv2.MORPH_TOPHAT, kernel) | 原图像减去开运算的差 | 数值上解释为:原图像减去开运算 |
黑帽 | blackhat | blackhat = cv2.morphologyEx(girl_pic, cv2.MORPH_BLACKHAT, kernel) | 闭运算减去原图像的差 | 数值上解释为:闭运算减去原图像 |
dilate 膨胀 (../pic/dilation.jpg):
open 开运算 (../pic/opening.jpg):
close 闭运算 (../pic/closing.jpg):
gradient 形态学梯度 (../pic/gradient.jpg):
tophat 礼帽 (../pic/tophat.jpg):
blackhat 黑帽 (../pic/blackhat.jpg):
cv2.add(open, tophat) cv2.add(开运算, 礼帽) (../pic/open_and_tophat.jpg):
close-blackhat 闭运算-黑帽 (../pic/close_subtract_blackhat.jpg):
# -*- coding: utf-8 -*-
import cv2
import numpy as np
girl_pic = cv2.imread('../pic/girl.jpg')
kernel = np.ones((5, 5), np.uint8)
# erode 腐蚀
erosion = cv2.erode(src=girl_pic, kernel=kernel)
cv2.imshow('erosion', erosion)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/erosion.jpg', erosion)
# dilate 膨胀
dilation = cv2.dilate(src=girl_pic, kernel=kernel)
cv2.imshow('dilation', dilation)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/dilation.jpg', dilation)
# open 开运算
opening = cv2.morphologyEx(girl_pic, cv2.MORPH_OPEN, kernel)
cv2.imshow('opening', opening)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/opening.jpg', opening)
# close 闭运算
closing = cv2.morphologyEx(girl_pic, cv2.MORPH_CLOSE, kernel)
cv2.imshow('closing', closing)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/closing.jpg', closing)
# gradient 形态学梯度
gradient = cv2.morphologyEx(girl_pic, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('gradient', gradient)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/gradient.jpg', gradient)
# tophat 礼帽
tophat = cv2.morphologyEx(girl_pic, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat', tophat)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/tophat.jpg', tophat)
# blackhat 黑帽
blackhat = cv2.morphologyEx(girl_pic, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('blackhat', blackhat)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/blackhat.jpg', blackhat)
# cv2.add(open, tophat) cv2.add(开运算, 礼帽)
open_and_tophat = cv2.add(opening, tophat)
cv2.imshow('open_and_tophat', open_and_tophat)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/open_and_tophat.jpg', open_and_tophat)
# close-blackhat 闭运算-黑帽
close_subtract_blackhat = closing - blackhat
cv2.imshow('close_subtract_blackhat', close_subtract_blackhat)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/close_subtract_blackhat.jpg', close_subtract_blackhat)
一开始设计实验时,用礼帽生成的图像加上开运算生成的图像能够得到原图,用黑帽生成的图像加上闭运算生成的图像却得不到原图,反而得到一张比闭运算图像更浅色的图片(如下):
想了一下,发现了问题所在:书上对黑帽的定义是:
进行闭运算之后得到的图像和原始图像的差
但是却没有说清楚被减数和减数分别是谁。根据闭运算和黑帽的定义,我觉得应该是:
黑帽 = 闭运算 - 原图
即可得:
原图 = 闭运算 - 黑帽