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
  • 4
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
OpenCV是一个广泛使用的计算机视觉库,用于图像和视频处理。下面是一些OpenCV图像处理基础知识: 1. 图像加载和显示:使用OpenCV可以加载和显示图像。可以使用`cv2.imread()`函数加载图像,并使用`cv2.imshow()`函数显示图像。 2. 图像保存:使用`cv2.imwrite()`函数可以将图像保存到文件中。 3. 图像通道:彩色图像由三个颜色通道(红色、绿色和蓝色)组成,每个通道都是一个灰度图像。可以使用`cv2.split()`函数将彩色图像拆分成单个通道,并使用`cv2.merge()`函数将单个通道合并成彩色图像。 4. 图像缩放:可以使用`cv2.resize()`函数调整图像的大小。可以指定新的宽度和高度,或者指定缩放因子。 5. 图像旋转:可以使用`cv2.getRotationMatrix2D()`函数获得旋转矩阵,并使用`cv2.warpAffine()`函数对图像进行旋转。 6. 图像平滑:可以使用不同的滤波器对图像进行平滑处理,如均值滤波器、高斯滤波器等。可以使用`cv2.blur()`函数进行均值滤波,使用`cv2.GaussianBlur()`函数进行高斯滤波。 7. 图像边缘检测:可以使用不同的边缘检测算法,如Sobel算子、Canny边缘检测等。可以使用`cv2.Sobel()`函数进行Sobel算子边缘检测,使用`cv2.Canny()`函数进行Canny边缘检测。 8. 图像阈值处理:可以使用不同的阈值处理方法对图像进行二值化处理,如全局阈值、自适应阈值等。可以使用`cv2.threshold()`函数进行全局阈值处理,使用`cv2.adaptiveThreshold()`函数进行自适应阈值处理。 以上是OpenCV图像处理的一些基础知识,希望能对你有所帮助!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LaoYuanPython

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值