当前位置: 首页 > news >正文

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 ░

相关文章:

  • OpenCV-Python图像击中击不中变换理解的关键知识点及自定义实现
  • OpenCV-Python击中击不中HITMISS形态变换详解
  • OpenCV-Python击中击不中变换案例:长方形边界提取
  • OpenCV-Python击中击不中变换案例:绿叶轮廓提取
  • OpenCV-Python击中击不中变换案例:真图作核的绳网结匹配
  • 你不一定全知道的四种Python装饰器实现详解
  • 类的类装饰器简单实现思路及案例
  • OpenCV-Python图形图像处理:自用的一些工具函数源代码
  • OpenCV-Python图形图像处理:自用的一些工具函数功能及调用语法介绍
  • OpenCV-Python图形图像处理:split通道拆分和数组矩阵访问通道
  • Python图像处理:OpenCV HSV和标准表示法的区别以及转换
  • OpenCV-Python图像处理:用inRange刷选图像中指定颜色对象案例
  • PyQt事件信号实战:为QTableWidget提供键盘事件
  • OpenCV-Python图像处理:区分前景背景权重的图像融合案例
  • 2020年总结:平安辞旧岁,老牛自奋蹄!
  • 《Javascript高级程序设计 (第三版)》第五章 引用类型
  • 10个确保微服务与容器安全的最佳实践
  • 78. Subsets
  • export和import的用法总结
  • HTTP中的ETag在移动客户端的应用
  • Java教程_软件开发基础
  • spring boot下thymeleaf全局静态变量配置
  • vuex 笔记整理
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 前端设计模式
  • 适配mpvue平台的的微信小程序日历组件mpvue-calendar
  • 我看到的前端
  • 小李飞刀:SQL题目刷起来!
  • 主流的CSS水平和垂直居中技术大全
  • LevelDB 入门 —— 全面了解 LevelDB 的功能特性
  • Prometheus VS InfluxDB
  • 昨天1024程序员节,我故意写了个死循环~
  • ​HTTP与HTTPS:网络通信的安全卫士
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (1)(1.8) MSP(MultiWii 串行协议)(4.1 版)
  • (2022 CVPR) Unbiased Teacher v2
  • (二)linux使用docker容器运行mysql
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (详细版)Vary: Scaling up the Vision Vocabulary for Large Vision-Language Models
  • (转)http-server应用
  • (转)Mysql的优化设置
  • (转)Sql Server 保留几位小数的两种做法
  • .[backups@airmail.cc].faust勒索病毒的最新威胁:如何恢复您的数据?
  • .NET 8.0 发布到 IIS
  • .net core Swagger 过滤部分Api
  • .NET Framework 服务实现监控可观测性最佳实践
  • .NET开源项目介绍及资源推荐:数据持久层
  • :O)修改linux硬件时间
  • @EnableConfigurationProperties注解使用
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [ CTF ] WriteUp-2022年春秋杯网络安全联赛-冬季赛
  • [Android]Android P(9) WIFI学习笔记 - 扫描 (1)
  • [Angular] 笔记 8:list/detail 页面以及@Input
  • [Avalon] Avalon中的Conditional Formatting.
  • [DEBUG] spring boot-如何处理链接中的空格等特殊字符