OpenCV图形图像击中击不中HITMISS变换处理基础知识

☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython

博文传送门:

老猿关于HTM变换的博文目录请见:
https://blog.csdn.net/LaoYuanPython/article/details/110676764 OpenCV-Python击中击不中HITMISS形态变换详解

一、引言

本文介绍内容大部分源于OpenCV官方资料,与《OpenCV击中击不中HITMISS形态变换公开资料汇总 https://blog.csdn.net/LaoYuanPython/article/details/110676941》中部分博文内容存在交叉,但老猿将尽量包含更多的内容。

击中击不中变换(Hit-or-Miss transform 或 Hit-and-Miss transform,简称HMT变换),用于在二值图像中查找给定的结构或模式,它也是更高级的形态学操作(如细化或修剪)的基础。在OpenCV-Python中,击中击不中变换使用与腐蚀、膨胀等运算相同的函数morphologyEx,具体函数介绍请参考《OpenCV-Python图像形态变换概述及morphologyEx函数介绍 https://blog.csdn.net/LaoYuanPython/article/details/109556425》有关介绍。

二、相关理论

形态变换运算根据图像的形状来处理图像,这些运算使用一个或多个结构元素(老猿前面都称为核矩阵)作用于输入图像以获得输出图像,前面介绍的腐蚀和膨胀就是两个最基本的形态变换运算,二者的组合会形成更多高阶形态变换运算,击中击不中变换是基于两次腐蚀组合形成的形态变换运算。

腐蚀运算的腐蚀过程相当于对可以填入结构元素的位置作标记的过程。腐蚀时,虽然标记点取决于锚点在结构元素中的相对位置,但输出图像的形状与此无关,改变锚点的位置,只会导致输出结果发生平移。由于腐蚀的过程相当于对可以填入结构元素的位置作标记的过程,因此可以利用腐蚀标记的内容来确定目标的位置,这就是击中击不中变换模式匹配后面的原理,因此击中击不中变换是形态学中用来检测特定形状所处位置的一个基本工具。

击中击不中变换用于在二值图像中查找由结构元素矩阵指定特征(如单个像素、颗粒中交叉或纵向的特征、直角边缘或其他用户自定义的特征等)的图像模式,不过特殊的是,击中击不中变换进行目标检测时,既要检测到目标的内部,也要检测到外部,即在一次运算中可以同时捕获内外标记。

击中击不中变换使用了两个结构元素B1和B2,要求在目标图像中查找与B1形状匹配且和B2形状不匹配的图像内容,B1用于探测图像内部,作为击中部分,B2用于探测图像外部,作为击不中部分。显然,B1和B2是不应该相连接的,即B1∩B2=Φ。从数学上讲,使用结构元素B1和B2的并集B(B称为复合结构元素)应用于图像A的运算可以表示为:
在这里插入图片描述
上述公式可以解释为如下步骤:

  1. 使用B1对A进行腐蚀得到结果图像C1;
  2. 使用B2对A的补集进行腐蚀得到结果图像C2;
  3. 取C1和C2的交集作为使用B1和B2对A进行击中击不中变换的结果。

上述运算过程中B1为击中使用核,B2为击不中使用核。

击中击不中变换实际上是先在图像A中,寻找满足第一个结构元素B1模式的结构,找到之后相当于“击中”。然后用第二个结构元素B2,直接在原图击中的位置进行匹配,如果不匹配,也就是“击不中”。如果满足以上两点,就是我们要找的结构形状,把其与核锚点对应的中心像素置为255,作为输出。

三、击中击不中图例讲解

下面以一个输入图像矩阵和使用不同的结构元素核来图解说明击中击不中变换。

3.1、输入图像矩阵图例

在本案例中输入图像对应矩阵为:
在这里插入图片描述

3.2、结构元素核图例1

在这里插入图片描述

上述三个图例中,第一个是击中使用核,第二个为击不中使用核,第三个为前两个核的组合叠加。在这个案例中,击中核表示的是需要查找中心位置像素为背景(值0对应黑色,在OpenCV中表示背景色),其上下左右四个像素为前景(非0表示前景),核的其他位置的像素无需关注,可以是0或1。

3.3、结果图像矩阵

使用上面的核和输入图像进行击中击不中变换,最后的输出图像是矩阵为:
在这里插入图片描述

3.4、更多案例

下面是上面输入图像矩阵使用另外两种核的输出图像矩阵案例:
在这里插入图片描述
在这里插入图片描述
从上述案例可以看出,击中击不中变换的结果图像矩阵保留的像素,是这些像素与核矩阵锚点重合后周边像素与核矩阵像素完全匹配的那些像素。

四、OpenCV-Python示例

上面第一个案例使用OpenCV-python实现的代码如下:

import cv2 as cv
import numpy as np
input_image = np.array((
    [0, 0, 0, 0, 0, 0, 0, 0],
    [0, 255, 255, 255, 0, 0, 0, 255],
    [0, 255, 255, 255, 0, 0, 0, 0],
    [0, 255, 255, 255, 0, 255, 0, 0],
    [0, 0, 255, 0, 0, 0, 0, 0],
    [0, 0, 255, 0, 0, 255, 255, 0],
    [0,255, 0, 255, 0, 0, 255, 0],
    [0, 255, 255, 255, 0, 0, 0, 0]), dtype="uint8")
kernel = np.array((
        [0, 1, 0],
        [1, -1, 1],
        [0, 1, 0]), dtype="int")
output_image = cv.morphologyEx(input_image, cv.MORPH_HITMISS, kernel)
rate = 50
kernel = (kernel + 1) * 127
kernel = np.uint8(kernel)
kernel = cv.resize(kernel, None, fx = rate, fy = rate, interpolation = cv.INTER_NEAREST)
cv.imshow("kernel", kernel)
cv.moveWindow("kernel", 0, 0)
input_image = cv.resize(input_image, None, fx = rate, fy = rate, interpolation = cv.INTER_NEAREST)
cv.imshow("Original", input_image)
cv.moveWindow("Original", 0, 200)
output_image = cv.resize(output_image, None , fx = rate, fy = rate, interpolation = cv.INTER_NEAREST)
cv.imshow("Hit or Miss", output_image)
cv.moveWindow("Hit or Miss", 500, 200)
cv.waitKey(0)
cv.destroyAllWindows()

执行后显示图像如下:
在这里插入图片描述
通过上述案例及实现的代码,可以看到几点:
1、代表结构元素的核矩阵元素为int类型,而不是UINT类型;
2、在OpenCV中变换仅使用了一个结构元素,具体关于结构元素的使用和构造将在后续博文中详细介绍。

五、小结

本节基于OpenCV官方文档基础之上,介绍了击中击不中HITMISS变换处理的原理、算法、图解案例以及案例实现,击中击不中HITMISS变换处理是通过两次腐蚀查找图像内部特定的形状。

六、引申阅读

老猿在学习这部分内容时,考虑到OpenCV的实现时发现这里有如下几个问题:

  1. 补集怎么计算?
  2. 交集怎么计算?
  3. B1和B2怎么构造?
  4. 能否根据介绍的算法利用腐蚀实现一个自定义的击中击不中HITMISS变换处理?

这些问题将在后续的博文中回答,在此先留一个悬疑。

老猿关于HTM变换的其他博文:

https://blog.csdn.net/LaoYuanPython/article/details/110676764 OpenCV-Python击中击不中HITMISS形态变换详解

写博不易,敬请支持:

如果阅读本文于您有所获,敬请点赞、评论、收藏,谢谢大家的支持!

更多OpenCV-Python的介绍请参考专栏《OpenCV-Python图形图像处理 》
专栏网址https://blog.csdn.net/laoyuanpython/category_9979286.html

关于老猿的付费专栏

  1. 付费专栏《使用PyQt开发图形界面Python应用 https://blog.csdn.net/laoyuanpython/category_9607725.html 》专门介绍基于Python的PyQt图形界面开发基础教程,对应文章目录为《使用PyQt开发图形界面Python应用专栏目录 》(https://blog.csdn.net/LaoYuanPython/article/details/107580932);
  2. 付费专栏《moviepy音视频开发专栏 https://blog.csdn.net/laoyuanpython/category_10232926.html)详细介绍moviepy音视频剪辑合成处理的类相关方法及使用相关方法进行相关剪辑合成场景的处理,对应文章目录为《moviepy音视频开发专栏文章目录》(https://blog.csdn.net/LaoYuanPython/article/details/107574583);
  3. 付费专栏《OpenCV-Python初学者疑难问题集 https://blog.csdn.net/laoyuanpython/category_10581071.html》为《OpenCV-Python图形图像处理 https://blog.csdn.net/laoyuanpython/category_9979286.html》的伴生专栏,是笔者对OpenCV-Python图形图像处理学习中遇到的一些问题个人感悟的整合,相关资料基本上都是老猿反复研究的成果,有助于OpenCV-Python初学者比较深入地理解OpenCV,对应文章目录为《OpenCV-Python初学者疑难问题集专栏目录 https://blog.csdn.net/LaoYuanPython/article/details/109713407》。

前两个专栏都适合有一定Python基础但无相关知识的小白读者学习,第三个专栏请大家结合《OpenCV-Python图形图像处理 https://blog.csdn.net/laoyuanpython/category_9979286.html》的学习使用。

对于缺乏Python基础的同仁,可以通过老猿的免费专栏《专栏:Python基础教程目录》(https://blog.csdn.net/laoyuanpython/category_9831699.html)从零开始学习Python。

如果有兴趣也愿意支持老猿的读者,欢迎购买付费专栏。

跟老猿学Python、学OpenCV!

☞ ░ 前往老猿Python博文目录 https://blog.csdn.net/LaoYuanPython

LaoYuanPython CSDN认证博客专家 Python专家 CSDN博客专家 博客之星季军
侥幸获得CSDN 2020博客之星季军,博客主要聚焦Python相关知识,包括Python、爬虫、PyQt图形界面开发、Moviepy音视频剪辑、OpenCV图形图像处理等方向,内容都是老猿零基础学习相关知识的总结,许多内容是深入研究、测试甚至源码分析后的成果,在官网和网上都没有。有独特之见的专栏主要包括PyQt、Moviepy、Python、OpenCV相关专栏,特别是PyQt、Moviepy以及OpenCV疑难问题相关的付费专栏。另外博客内容还涉及5G、区块链和人工智能数学基础等非Python领域。欢迎大家批评指正!

如有疑问,请在 老猿Python 微信公号提问。谢谢!
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页
实付 29.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值