【Emgu CV教程】10.13、利用形状场景算法比较轮廓

2024-04-08 11:20

本文主要是介绍【Emgu CV教程】10.13、利用形状场景算法比较轮廓,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 一、演示
    • 1.原始素材
    • 2.代码
    • 3.运行结果


形状场景算法比较轮廓,要引用Emgu.CV.Shape,定义检测器ShapeContextDistanceExtractor,然后对两个轮廓进行比较,得出结果。

一、演示

1.原始素材

原始图像srcMat1如下图:
在这里插入图片描述
待比较的图像srcMat2如下图:
在这里插入图片描述

2.代码

轮廓检索模式要选择RetrType.External,代码如下:

Mat tempMat1 = srcMat1.Clone();
Mat tempMat2 = srcMat2.Clone();
Mat gray1 = new Mat();
Mat gray2 = new Mat();// 二值化图片1,确保黑里面找白
CvInvoke.CvtColor(tempMat1, gray1, ColorConversion.Bgr2Gray);
CvInvoke.Threshold(gray1, gray1, 50, 255, ThresholdType.Binary);
VectorOfVectorOfPoint contours1 = new VectorOfVectorOfPoint();
VectorOfRect hierarchy1 = new VectorOfRect();
CvInvoke.FindContours(gray1, contours1, hierarchy1, RetrType.External, ChainApproxMethod.ChainApproxNone);
Mat contourMat1 = new Mat(new System.Drawing.Size(gray1.Cols, gray1.Rows), DepthType.Cv8U, 1);
contourMat1.SetTo(new MCvScalar(0, 0, 0));// 按照面积筛选,太小的轮廓不计算
Dictionary<int, double> dict1 = new Dictionary<int, double>();
if (contours1.Size > 0)
{for (int i = 0; i < contours1.Size; i++){double area = CvInvoke.ContourArea(contours1[i]);Rectangle rect = CvInvoke.BoundingRectangle(contours1[i]);if (rect.Width > 2 && rect.Height > 2 && area < 3000000){dict1.Add(i, area);}}
}// 二值化图片2,确保黑里面找白
CvInvoke.CvtColor(tempMat2, gray2, ColorConversion.Bgr2Gray);
CvInvoke.Threshold(gray2, gray2, 50, 255, ThresholdType.Binary);
VectorOfVectorOfPoint contours2 = new VectorOfVectorOfPoint();
VectorOfRect hierarchy2 = new VectorOfRect();
CvInvoke.FindContours(gray2, contours2, hierarchy2, RetrType.External, ChainApproxMethod.ChainApproxNone);
Mat contourMat2 = new Mat(new System.Drawing.Size(gray1.Cols, gray1.Rows), DepthType.Cv8U, 1);
contourMat2.SetTo(new MCvScalar(0, 0, 0));// 按照面积筛选,太小的轮廓不计算
Dictionary<int, double> dict2 = new Dictionary<int, double>();
if (contours2.Size > 0)
{for (int i = 0; i < contours2.Size; i++){double area = CvInvoke.ContourArea(contours2[i]);Rectangle rect = CvInvoke.BoundingRectangle(contours2[i]);if (rect.Width > 2 && rect.Height > 2 && area < 3000000){dict2.Add(i, area);}}
}// 排序,取最大的轮廓再判断
IOrderedEnumerable<KeyValuePair<int, double>> descendingDict1 = dict1.OrderByDescending(x => x.Value);
IOrderedEnumerable<KeyValuePair<int, double>> descendingDict2 = dict2.OrderByDescending(x => x.Value);
using (HistogramCostExtractor comparer = new ChiHistogramCostExtractor())
using (ThinPlateSplineShapeTransformer transformer = new ThinPlateSplineShapeTransformer())
using (ShapeContextDistanceExtractor extractor = new ShapeContextDistanceExtractor(comparer, transformer))
{CvInvoke.DrawContours(contourMat1, contours1, descendingDict1.First().Key, new MCvScalar(255, 255, 255), 1);CvInvoke.DrawContours(contourMat2, contours2, descendingDict2.First().Key, new MCvScalar(255, 255, 255), 1);float distance = extractor.ComputeDistance(contours1[descendingDict1.First().Key], contours2[descendingDict2.First().Key]);MessageBox.Show("形状场景距离是:" + distance);
}

3.运行结果

利用extractor.ComputeDistance()函数计算出的形状场景距离是:0.1476557

在这里插入图片描述
如果srcMat2采用和srcMat1相同的图形,计算出的形状场景距离是:0.000375
在这里插入图片描述
因此记住它的特点:使用“距离”作为形状比较的度量标准,距离越小相似度越高


原创不易,请勿抄袭。共同进步,相互学习。

这篇关于【Emgu CV教程】10.13、利用形状场景算法比较轮廓的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/885443

相关文章

深入理解Mysql OnlineDDL的算法

《深入理解MysqlOnlineDDL的算法》本文主要介绍了讲解MysqlOnlineDDL的算法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小... 目录一、Online DDL 是什么?二、Online DDL 的三种主要算法2.1COPY(复制法)

全网最全Tomcat完全卸载重装教程小结

《全网最全Tomcat完全卸载重装教程小结》windows系统卸载Tomcat重新通过ZIP方式安装Tomcat,优点是灵活可控,适合开发者自定义配置,手动配置环境变量后,可通过命令行快速启动和管理... 目录一、完全卸载Tomcat1. 停止Tomcat服务2. 通过控制面板卸载3. 手动删除残留文件4.

Python的pandas库基础知识超详细教程

《Python的pandas库基础知识超详细教程》Pandas是Python数据处理核心库,提供Series和DataFrame结构,支持CSV/Excel/SQL等数据源导入及清洗、合并、统计等功能... 目录一、配置环境二、序列和数据表2.1 初始化2.2  获取数值2.3 获取索引2.4 索引取内容2

vue监听属性watch的用法及使用场景详解

《vue监听属性watch的用法及使用场景详解》watch是vue中常用的监听器,它主要用于侦听数据的变化,在数据发生变化的时候执行一些操作,:本文主要介绍vue监听属性watch的用法及使用场景... 目录1. 监听属性 watch2. 常规用法3. 监听对象和route变化4. 使用场景附Watch 的

python依赖管理工具UV的安装和使用教程

《python依赖管理工具UV的安装和使用教程》UV是一个用Rust编写的Python包安装和依赖管理工具,比传统工具(如pip)有着更快、更高效的体验,:本文主要介绍python依赖管理工具UV... 目录前言一、命令安装uv二、手动编译安装2.1在archlinux安装uv的依赖工具2.2从github

C#实现SHP文件读取与地图显示的完整教程

《C#实现SHP文件读取与地图显示的完整教程》在地理信息系统(GIS)开发中,SHP文件是一种常见的矢量数据格式,本文将详细介绍如何使用C#读取SHP文件并实现地图显示功能,包括坐标转换、图形渲染、平... 目录概述功能特点核心代码解析1. 文件读取与初始化2. 坐标转换3. 图形绘制4. 地图交互功能缩放

Java 缓存框架 Caffeine 应用场景解析

《Java缓存框架Caffeine应用场景解析》文章介绍Caffeine作为高性能Java本地缓存框架,基于W-TinyLFU算法,支持异步加载、灵活过期策略、内存安全机制及统计监控,重点解析其... 目录一、Caffeine 简介1. 框架概述1.1 Caffeine的核心优势二、Caffeine 基础2

SpringBoot集成redisson实现延时队列教程

《SpringBoot集成redisson实现延时队列教程》文章介绍了使用Redisson实现延迟队列的完整步骤,包括依赖导入、Redis配置、工具类封装、业务枚举定义、执行器实现、Bean创建、消费... 目录1、先给项目导入Redisson依赖2、配置redis3、创建 RedissonConfig 配

javacv依赖太大导致jar包也大的解决办法

《javacv依赖太大导致jar包也大的解决办法》随着项目的复杂度和依赖关系的增加,打包后的JAR包可能会变得很大,:本文主要介绍javacv依赖太大导致jar包也大的解决办法,文中通过代码介绍的... 目录前言1.检查依赖2.更改依赖3.检查副依赖总结 前言最近在写项目时,用到了Javacv里的获取视频

防止Linux rm命令误操作的多场景防护方案与实践

《防止Linuxrm命令误操作的多场景防护方案与实践》在Linux系统中,rm命令是删除文件和目录的高效工具,但一旦误操作,如执行rm-rf/或rm-rf/*,极易导致系统数据灾难,本文针对不同场景... 目录引言理解 rm 命令及误操作风险rm 命令基础常见误操作案例防护方案使用 rm编程 别名及安全删除