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

C++ 基于 OpenCV 4.5 仿 Halcon 基于形状的模板匹配实现探索

C++ 基于opencv 4.5 仿halcon 基于形状的模板匹配 ,支持目标缩放以及旋转,支持亚像素精度,源码,支持C#。

在机器视觉领域,模板匹配是一项至关重要的技术,Halcon 强大的基于形状的模板匹配功能令人称赞。今天咱们就来看看如何使用 C++ 结合 OpenCV 4.5 去模仿实现类似的基于形状的模板匹配,而且要支持目标缩放、旋转以及亚像素精度,同时还会涉及如何让其支持 C#。

1. 准备工作

首先确保你已经安装好了 OpenCV 4.5 库,并且你的开发环境(如 Visual Studio)已经正确配置了 OpenCV。

2. 实现思路

OpenCV 中的模板匹配通常使用matchTemplate函数,但它不直接支持旋转和缩放。我们需要借助一些其他的技术,比如特征点匹配,轮廓匹配等。这里我们利用 OpenCV 的轮廓相关函数以及仿射变换来实现对目标缩放和旋转的支持,亚像素精度则可以通过一些细化算法来实现。

3. C++ 代码实现

#include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main(int argc, char** argv) { // 读取模板图像和待匹配图像 Mat templateImage = imread("template.jpg", IMREAD_GRAYSCALE); Mat targetImage = imread("target.jpg", IMREAD_GRAYSCALE); if (templateImage.empty() || targetImage.empty()) { cout << "Could not open or find the images" << endl; return -1; } // 查找模板图像的轮廓 vector<vector<Point>> templateContours; findContours(templateImage, templateContours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); // 查找待匹配图像的轮廓 vector<vector<Point>> targetContours; findContours(targetImage, targetContours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE); double maxMatch = 0; int bestIndex = -1; for (size_t i = 0; i < targetContours.size(); ++i) { // 使用轮廓匹配方法比较模板轮廓和待匹配图像的各个轮廓 double matchVal = matchShapes(templateContours[0], targetContours[i], CONTOURS_MATCH_I1, 0); if (matchVal < maxMatch || i == 0) { maxMatch = matchVal; bestIndex = i; } } if (bestIndex!= -1) { // 绘制出匹配到的轮廓 drawContours(targetImage, targetContours, bestIndex, Scalar(0, 255, 0), 2); } // 显示结果 imshow("Matched Image", targetImage); waitKey(0); return 0; }

代码分析

  1. 图像读取:首先使用imread函数读取模板图像和待匹配图像,并将它们转换为灰度图,这样在后续处理中会更简单高效。
  2. 轮廓查找:通过findContours函数分别在模板图像和待匹配图像中查找轮廓。RETREXTERNAL表示只检测外轮廓,CHAINAPPROX_SIMPLE表示压缩水平方向、垂直方向和对角线方向的元素,只保留该方向的终点坐标。
  3. 轮廓匹配:利用matchShapes函数比较模板轮廓和待匹配图像中的各个轮廓。CONTOURSMATCHI1是轮廓匹配的度量方式,这里它会返回一个越小越相似的值。通过遍历所有轮廓找到最匹配的那个。
  4. 结果绘制与显示:如果找到了匹配的轮廓,就用drawContours函数将其绘制在待匹配图像上,最后使用imshow显示结果。

4. 支持亚像素精度

要实现亚像素精度的匹配,可以在轮廓查找后对轮廓进行细化处理。比如使用approxPolyDP函数对轮廓进行多边形逼近,这样可以得到更精确的轮廓点,进而提高匹配精度。

// 对模板轮廓进行多边形逼近 vector<Point> approxTemplate; approxPolyDP(Mat(templateContours[0]), approxTemplate, 3, true); // 对目标轮廓进行多边形逼近 vector<Point> approxTarget; approxPolyDP(Mat(targetContours[bestIndex]), approxTarget, 3, true);

代码分析

approxPolyDP函数通过指定的精度对轮廓进行逼近,这里的精度设为 3。这个值越小,逼近的多边形越接近原始轮廓,从而实现亚像素精度的效果。

5. 支持目标缩放和旋转

为了支持缩放和旋转,可以对模板图像进行不同角度和缩放比例的变换,然后再进行匹配。

Mat rotatedScaledTemplate; Mat rotationMatrix = getRotationMatrix2D(Point2f(templateImage.cols / 2, templateImage.rows / 2), angle, scale); warpAffine(templateImage, rotatedScaledTemplate, rotationMatrix, Size(templateImage.cols * scale, templateImage.rows * scale));

代码分析

getRotationMatrix2D函数生成一个旋转缩放矩阵,angle是旋转角度,scale是缩放比例。warpAffine函数利用这个矩阵对模板图像进行仿射变换,得到旋转缩放后的模板图像,然后再使用上述轮廓匹配方法进行匹配。

6. 支持 C#

要让上述功能支持 C#,可以使用 C++/CLI 桥接。首先创建一个 C++/CLI 项目,将上述 C++ 代码封装成一个类库。

// C++/CLI 封装代码示例 using namespace System; using namespace cv; namespace TemplateMatchingLib { public ref class TemplateMatcher { public: static void Match(String^ templatePath, String^ targetPath) { Mat templateImage = imread(Marshal::StringToHGlobalAnsi(templatePath).ToPointer(), IMREAD_GRAYSCALE); Mat targetImage = imread(Marshal::StringToHGlobalAnsi(targetPath).ToPointer(), IMREAD_GRAYSCALE); // 后续匹配代码同上述C++ 代码... } }; }

然后在 C# 项目中引用这个 C++/CLI 生成的类库,就可以调用其中的匹配方法了。

using System; using TemplateMatchingLib; class Program { static void Main() { TemplateMatcher.Match("template.jpg", "target.jpg"); } }

代码分析

在 C++/CLI 代码中,使用Marshal::StringToHGlobalAnsi将 C# 的字符串转换为 C++ 能处理的 ANSI 字符串,从而读取图像。在 C# 中,只需要简单引用类库并调用封装好的方法即可使用基于形状的模板匹配功能。

通过以上步骤,我们就实现了基于 OpenCV 4.5 的仿 Halcon 基于形状的模板匹配,并且支持目标缩放、旋转、亚像素精度以及 C# 调用,希望对大家在机器视觉开发中有所帮助。

http://www.cnnetsun.cn/news/107009.html

相关文章:

  • Cuberite服务器日志分析完全指南:从入门到实战
  • EmotiVoice语音合成服务灰度日志采集规范
  • EmotiVoice语音自然度评分达到MOS 4.5以上
  • GISBox教你快速获取建筑数据并生成可发布的3D模型
  • EmotiVoice情感语音合成API接口调用详细说明
  • SenseVoice多语言语音理解:突破传统ASR局限的专业术语识别方案
  • Redash数据可视化:让枯燥数据秒变商业洞察
  • Pyfa舰船配置工具:5个高效技巧助你成为EVE Online配置高手
  • 洛谷 P1892 [BalticOI 2003] 团伙
  • 洛谷 P2024 [NOI2001] 食物链
  • Animeko跨平台动漫追番神器:从入门到精通的完整指南
  • 中级软件设计师英语部分备考攻略:完形填空高频考点与解题技巧
  • 2025年下半年软件设计师易混淆知识点
  • Headscale配置终极指南:从零到精通的环境变量管理技巧
  • 测试架构师的成长路径:从技术执行到质量战略的跨越
  • 多人姿态估计终极指南:从零开始构建实时人体分析系统
  • 【ACWing】150. 括号画家
  • 如何快速掌握Vim插件管理:VAM的完整使用指南
  • 文献分区及影响因子批量查询
  • APKMirror安卓应用下载平台深度解析:从源码到实践
  • 终极FreeMarker模板调试工具:3分钟解决模板语法问题
  • QQScreenShot独立版技术解析:基于模块化架构的屏幕捕捉解决方案
  • 快速掌握SCPI Parser终极指南:构建专业仪器控制系统的完整解决方案
  • 自定义算子的“诞生记”:基于CANN Kernel自调工程的完整CI/CD流水线
  • 高效、稳定、可定制——EmotiVoice开源TTS优势全解析
  • 大模型应用开发(十八)_向量检索
  • NVIDIA显卡设置终极指南:从问题诊断到性能优化的完整解决方案
  • 聚星成链,蓝卓牵头成立“工厂操作系统生态联盟”共建产业新生态
  • 每天一道面试题之架构篇|可靠订单状态机与事务消息架构设计
  • 10分钟掌握开源美颜SDK核心技术:从算法原理到商业应用实战