OpenCV中一个最容易搞错的形态学操作

点击上方“小白学视觉”,选择加"星标"或“置顶

重磅干货,第一时间送达

击中击不中解释

OpenCV中除了常见腐蚀、膨胀、开闭操作之外,还有个非常有用的形态学操作,就是击中击不中。击中击不中也是基础形态学操作组合,它可以实现对象的细化跟剪枝操作。形态学操作都是基于各种形状的结构元素,基于输入图像,跟结构元素操作得到输出图像,击中击不中操作是在二值图像的模式匹配跟发现上非常有用,它是基于两个结构元素分别是B1跟B2、第一个结构元素B1在图像上完成腐蚀操作、然后第二个结构元素B2在图像完成腐蚀操作,然后合并最终输出得到。详解步骤如下:

1.使用B1完成对图像腐蚀
2.使用B2完成对图像腐蚀
3.对上述两步的输出结果进行位与操作输出最终结果

上述步骤可以把结构元素B1+B2得到一个结构元素B,可以直接完成一次操作就为击中击不中(Hit And Miss)

举例如下,假设有如下的结构元素:

cedf1fa8b09d7f129056f3912b55dea6.png

上图B1、B2对图像进行腐蚀,可以合并为B1 + B2,其中中心元素-1表示该点为背景像素点,上下左右四个点值为1表示前景像素点,角上四个点为0表示任意像素值均可。这里就是Hit And Miss的结构元素定义。使用该结构元素对输入图像二值图像完成操作,得到输出图像,图示如下:

3e04ffb32c125ba4cb6277c82910e715.jpeg

通过设计不同的结构元素会得到不同的输出图像,图示如下:

01e262e862e4397b056ef683e099a4ad.jpeg

OpenCV中的Hit And Miss

OpenCV中的击中击不中的函数,是跟开闭操作一样的功能函数

void cv::morphologyEx(
    InputArray  src,
    OutputArray dst,
    int   op,
    InputArray      kernel,
    Point       anchor = Point(-1,-1),
    int   iterations = 1,
    int   borderType = BORDER_CONSTANT,
    const Scalar & borderValue = morphologyDefaultBorderValue()
)

参数解释:

  • src表示输入图像

  • dst表示输出图像

  • op 这里必须是MORPH_HITMISS

  • kernel 表示结构元素

  • anchor 表示锚定位置,默认是结构元素中心位置

剩下的参数默认即可,一般情况都不用设置。

代码演示-二值对象边缘发现

使用击中击不中实现二值对象的边缘提取,如下:

5bbfd2ade99b72e6398426f3195c482d.png

左侧是原图、右侧是基于击中击不中提取到轮廓边缘。

代码实现如下:

image = cv.imread("D:/images/my_mask.png")
gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY)
ret, binary = cv.threshold(gray, 0, 255, cv.THRESH_BINARY | cv.THRESH_OTSU)
cv.imshow("input", binary)
hmk1 = np.zeros((3, 3), dtype=np.int32)
hmk1[0, 0] = 1
hmk1[1, 1] = -1
print(hmk1)
h1 = cv.morphologyEx(binary, cv.MORPH_HITMISS, hmk1)

hmk1 = np.zeros((3, 3), dtype=np.int32)
hmk1[2, 2] = 1
hmk1[1, 1] = -1
print(hmk1)
h2 = cv.morphologyEx(binary, cv.MORPH_HITMISS, hmk1)

dst = cv.add(h1, h2)
cv.imshow("output", dst)

cv.waitKey(0)
cv.destroyAllWindows()

使用的结构元素为:

1ddfcf41ee76b575f738988cecc89e88.png

另外一个运行测试

原图

81a2e0ad65747249d7d6abd3b3714034.jpeg

运行结果

38913ca144e875974a1f17d798b07504.png

掉坑的记录

OpenCV中的结构元素通过Mat来表示,默认的数据类是CV_8UC1, 但是对Hit And Miss来说,数据类型必须是 CV_32SC 如果使用默认数据类型就会导致-1溢出错误。但是多数初学者都不会意识到这个问题,一般如下定义结构元素,然后去执行Hit And Miss操作:

hmk1 = np.zeros((3, 3), dtype=np.uint8)
hmk1[0, 0] = 1
hmk1[1, 1] = -1
h1 = cv.morphologyEx(binary, cv.MORPH_HITMISS, hmk1)

输出结果跟原图一样,没有任何改变,很多人都会因此发狂,还反馈说OpenCV的Hit And Miss根本无法使用,我晕!这个时候只需要把结构元素定义改为

hmk1 = np.zeros((3, 3), dtype=np.int32)
hmk1[0, 0] = 1
hmk1[1, 1] = -1
print(hmk1)
h1 = cv.morphologyEx(binary, cv.MORPH_HITMISS, hmk1)

就会运行正确了。

 
 

好消息!

小白学视觉知识星球

开始面向外开放啦👇👇👇

 
 

2e10128edf90a392b9aa463cdc062e0c.jpeg

下载1:OpenCV-Contrib扩展模块中文版教程

在「小白学视觉」公众号后台回复:扩展模块中文教程,即可下载全网第一份OpenCV扩展模块教程中文版,涵盖扩展模块安装、SFM算法、立体视觉、目标跟踪、生物视觉、超分辨率处理等二十多章内容。


下载2:Python视觉实战项目52讲
在「小白学视觉」公众号后台回复:Python视觉实战项目,即可下载包括图像分割、口罩检测、车道线检测、车辆计数、添加眼线、车牌识别、字符识别、情绪检测、文本内容提取、面部识别等31个视觉实战项目,助力快速学校计算机视觉。


下载3:OpenCV实战项目20讲
在「小白学视觉」公众号后台回复:OpenCV实战项目20讲,即可下载含有20个基于OpenCV实现20个实战项目,实现OpenCV学习进阶。


交流群

欢迎加入公众号读者群一起和同行交流,目前有SLAM、三维视觉、传感器、自动驾驶、计算摄影、检测、分割、识别、医学影像、GAN、算法竞赛等微信群(以后会逐渐细分),请扫描下面微信号加群,备注:”昵称+学校/公司+研究方向“,例如:”张三 + 上海交大 + 视觉SLAM“。请按照格式备注,否则不予通过。添加成功后会根据研究方向邀请进入相关微信群。请勿在群内发送广告,否则会请出群,谢谢理解~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值