OpenCV的查找命中或未命中

返回:OpenCV系列文章目录(持续更新中......)

上一篇:OpenCV4.9更多形态转换

下一篇:OpenCV系列文章目录(持续更新中......)

目标

在本教程中,您将学习如何使用 Hit-or-Miss 转换(也称为 Hit-and-Miss 转换)在二进制映像中查找给定配置或模式。这种变换也是更高级的形态操作(如疏伐或修剪)的基础。

我们将使用OpenCV函数 morphologyEx() .

命中或未命中理论

形态学运算符根据图像的形状处理图像。这些运算符将一个或多个结构化元素应用于输入图像以获取输出图像。两种基本的形态操作是侵蚀扩张。这两种操作的组合会产生高级形态转换,例如打开关闭顶帽转换。要了解有关这些和其他基本形态操作的更多信息,请参阅前面的教程(侵蚀和扩张)和(更多形态转换)。

命中或未命中变换对于查找二进制图像中的模式非常有用。特别是,它找到那些邻域与第一个结构元素B1的形状匹配,但同时与第二个结构元素 B2 的形状不匹配的像素。从数学上讲,应用于图像A的运算可以表示如下:

因此,命中或未命中操作包括三个步骤:

  1. 使用结构元素B1侵蚀图像 A。
  2. 侵蚀图像A(AC)的补码与结构元素(B2)。
  3. AND 来自步骤 1 和步骤 2。

结构元素 B1和 B2 可以组合成一个元素B。让我们看一个例子:

在本例中,我们正在寻找一种模式,其中中心像素属于背景,而北、南、东、西像素属于前景。附近的其余像素可以是任何类型的,我们不关心它们。现在,让我们将此内核应用于输入图像:

 

您可以看到该图案仅在图像中的一个位置找到。

代码

与上一个示例对应的代码如下所示。

您也可以从这里下载

C++:

#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/highgui.hpp> 
using namespace cv; 
int main(){Mat input_image = (Mat_<uchar>(8, 8) <<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); Mat kernel = (Mat_<int>(3, 3) <<0, 1, 0,1, -1, 1,0, 1, 0); Mat output_image;morphologyEx(input_image, output_image, MORPH_HITMISS, kernel); const int rate = 50;kernel = (kernel + 1) * 127;kernel.convertTo(kernel, CV_8U); resize(kernel, kernel, Size(), rate, rate, INTER_NEAREST);imshow("kernel", kernel);moveWindow("kernel", 0, 0); resize(input_image, input_image, Size(), rate, rate, INTER_NEAREST);imshow("Original", input_image);moveWindow("Original", 0, 200); resize(output_image, output_image, Size(), rate, rate, INTER_NEAREST);imshow("Hit or Miss", output_image);moveWindow("Hit or Miss", 500, 200); waitKey(0);return 0;
}

Java:

import org.opencv.core.*;
import org.opencv.highgui.HighGui;
import org.opencv.imgproc.Imgproc;class HitMissRun{public void run() {Mat input_image = new Mat( 8, 8, CvType.CV_8UC1 );int row = 0, col = 0;input_image.put(row ,col,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);Mat kernel = new Mat( 3, 3, CvType.CV_16S );kernel.put(row ,col,0, 1, 0,1, -1, 1,0, 1, 0 );Mat output_image = new Mat();Imgproc.morphologyEx(input_image, output_image, Imgproc.MORPH_HITMISS, kernel);int rate = 50;Core.add(kernel, new Scalar(1), kernel);Core.multiply(kernel, new Scalar(127), kernel);kernel.convertTo(kernel, CvType.CV_8U);Imgproc.resize(kernel, kernel, new Size(), rate, rate, Imgproc.INTER_NEAREST);HighGui.imshow("kernel", kernel);HighGui.moveWindow("kernel", 0, 0);Imgproc.resize(input_image, input_image, new Size(), rate, rate, Imgproc.INTER_NEAREST);HighGui.imshow("Original", input_image);HighGui.moveWindow("Original", 0, 200);Imgproc.resize(output_image, output_image, new Size(), rate, rate, Imgproc.INTER_NEAREST);HighGui.imshow("Hit or Miss", output_image);HighGui.moveWindow("Hit or Miss", 500, 200);HighGui.waitKey(0);System.exit(0);}
}public class HitMiss
{public static void main(String[] args) {// load the native OpenCV librarySystem.loadLibrary(Core.NATIVE_LIBRARY_NAME);new HitMissRun().run();}
}

 Python:

import cv2 as cv
import numpy as npinput_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()

正如你所看到的,它就像使用函数morphologyEx()和操作类型MORPH_HITMISS和所选的内核一样简单。

其他例子

在这里,您可以找到将不同内核应用于之前使用的同一输入图像的输出结果:

 

现在试试你自己的模式吧!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/619656.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

构建第一个ArkTS应用之stateStyles:多态样式

Styles和Extend仅仅应用于静态页面的样式复用&#xff0c;stateStyles可以依据组件的内部状态的不同&#xff0c;快速设置不同样式。这就是我们本章要介绍的内容stateStyles&#xff08;又称为&#xff1a;多态样式&#xff09;。 概述 stateStyles是属性方法&#xff0c;可以…

【Linux C | 多线程编程】线程同步 | 条件变量(万字详解)

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; ⏰发布时间⏰&#xff1a;2024-04-15 0…

【合合TextIn】智能文档处理系列—电子文档解析技术全格式解析

一、引言 在当今的数字化时代&#xff0c;电子文档已成为信息存储和交流的基石。从简单的文本文件到复杂的演示文档&#xff0c;各种格式的电子文档承载着丰富的知识与信息&#xff0c;支撑着教育、科研、商业和日常生活的各个方面。随着信息量的爆炸性增长&#xff0c;如何高…

2024年MathorCup数学应用挑战赛C题思路分析(妈妈杯)

2024年第十四届MathorCup数学应用挑战赛C题解析 文章目录 题目概览第一问&#xff1a;货量预测第二问&#xff1a;运输线路变化的预测第三问&#xff1a;单目标优化第四问&#xff1a;排班计划的优化 MATLAB代码框架货量预测人员排班 2024年的MathorCup数学应用挑战赛再次为我…

基于SpringBoot和Vue的企业客户管理系统

今天要和大家聊的是基于SpringBoot和Vue的企业客户管理系统 &#xff01;&#xff01;&#xff01; 有需要的小伙伴可以通过文章末尾名片咨询我哦&#xff01;&#xff01;&#xff01; &#x1f495;&#x1f495;作者&#xff1a;李同学 &#x1f495;&#x1f495;个人简介…

Spring框架第一篇(Spring概述与IOC思想)

文章目录 一、Spring概述二、Spring家族三、Spring Framework四、IOC思想五、IOC容器在Spring中的实现 一、Spring概述 Spring 是最受欢迎的企业级 Java 应用程序开发框架&#xff0c;数以百万的来自世界各地的开发人员使用 Spring 框架来创建性能好、易于测试、可重用的代码。…

界面控件DevExpress WinForms/WPF v23.2 - 富文本编辑器支持内容控件

众所周知内容控件是交互式UI元素(文本字段、下拉列表、日期选择器)&#xff0c;用于在屏幕上输入和管理信息。内容控件通常在模板/表单中使用&#xff0c;以标准化文档格式和简化数据输入。DevExpress文字处理产品库&#xff08;Word Processing Document API、WinForm和WPF富文…

图像分类——综合车辆数据集

一、重要性及意义 智能交通管理&#xff1a;车辆图像分类是智能交通系统&#xff08;ITS&#xff09;中的关键组成部分。通过对监控摄像头捕捉到的车辆图像进行自动分类&#xff0c;系统能够实时识别车辆类型、颜色、品牌等信息&#xff0c;进而实现交通流量监控、违章行为检测…

10万字208道Java经典面试题总结(2024修订版)- SSM篇

&#x1f345; 作者简介&#xff1a;哪吒&#xff0c;CSDN2021博客之星亚军&#x1f3c6;、新星计划导师✌、博客专家&#x1f4aa; &#x1f345; 哪吒多年工作总结&#xff1a;Java学习路线总结&#xff0c;搬砖工逆袭Java架构师 &#x1f345; 技术交流&#xff1a;定期更新…

AI2 项目合并工具:轻松合并多个项目的屏幕、素材及拓展

有时我们需要把App Inventor做好的多个.aia项目中的一部分抽取出来&#xff0c;做一个新的项目&#xff0c;由于界面的直接Ctrl C/V复制粘贴可能会导致布局不能100%还原&#xff0c;还会有部分代码块丢失&#xff1b;并且涉及多个项目很难进行拷贝&#xff0c;从来开始弄又费时…

RoguelikeGenerator Pro - Procedural Level Generator

Roguelike Generator Pro是一款功能丰富、高度可定制的关卡和地牢生成器,允许您使用GamObjects、Tilemaps或自定义解决方案按程序创建3D/2D/2.5D关卡 这是怎么一回事? Roguelike Generator Pro是一款强大而简单的关卡和地牢生成器。该资源允许您使用GamObjects、Tilemaps或自…

手写商城项目学习/复习到的知识

1.在windowr创建项目可以选择自定义/vue2/vue3,但尝试在vscode不能选择. 2.vant vant是组件库,可导入结构等.vant2用于vue2,vant3,vant\4用于vue3 vant2的使用 官网: Vant 2 - 轻量、可靠的移动端组件库 (gitee.io) 全部导入:将vant所有的组件放到了所有组件内component使…