news 2026/9/1 9:22:59

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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# 调用,希望对大家在机器视觉开发中有所帮助。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/1 5:44:19

Cuberite服务器日志分析完全指南:从入门到实战

Cuberite作为一款轻量级、快速且可扩展的Minecraft游戏服务器&#xff0c;其日志系统是诊断服务器健康状况的"诊断报告"。通过系统性的日志分析&#xff0c;管理员能够快速识别性能瓶颈、插件冲突和系统错误&#xff0c;确保玩家获得流畅的游戏体验。本指南将从基础概…

作者头像 李华
网站建设 2026/9/1 5:48:09

EmotiVoice语音合成服务灰度日志采集规范

EmotiVoice语音合成服务灰度日志采集规范 在虚拟主播直播中突然变调的愤怒语气&#xff0c;在有声书朗读里恰到好处的悲伤停顿——这些不再是预录音轨的简单播放&#xff0c;而是由AI实时生成的情感化语音。当用户开始期待机器声音也能“动情”时&#xff0c;传统TTS系统那种千…

作者头像 李华
网站建设 2026/8/31 22:54:54

EmotiVoice语音自然度评分达到MOS 4.5以上

EmotiVoice语音自然度评分达到MOS 4.5以上 在智能语音助手越来越“能说会道”的今天&#xff0c;我们是否还记得那些机械生硬、毫无情绪起伏的TTS&#xff08;文本转语音&#xff09;声音&#xff1f;它们曾是车载导航、电子书朗读的标准配置&#xff0c;也正是因为这些体验&am…

作者头像 李华
网站建设 2026/9/1 8:16:44

GISBox教你快速获取建筑数据并生成可发布的3D模型

本文主要介绍了GISBox软件的核心操作流程&#xff0c;通过地图选框、经纬度调整或跳转城市获取建筑SHP矢量数据&#xff0c;支持2D/3D模式切换预览&#xff0c;随后可选择白模、城市、徽派三种风格一键生成建筑&#xff0c;还能对建筑进行高度调节、颜色修改、贴图替换及风格切…

作者头像 李华
网站建设 2026/9/1 6:37:28

EmotiVoice情感语音合成API接口调用详细说明

EmotiVoice情感语音合成API接口调用深度解析 在虚拟主播深夜与粉丝互动、游戏NPC因剧情转折发出愤怒呐喊、有声书中角色哽咽落泪的瞬间——这些不再依赖真人配音&#xff0c;而是由AI生成却充满情绪张力的声音正在悄然改变人机交互的边界。传统TTS系统常被诟病“像读说明书”&a…

作者头像 李华
网站建设 2026/8/31 20:43:49

SenseVoice多语言语音理解:突破传统ASR局限的专业术语识别方案

SenseVoice多语言语音理解&#xff1a;突破传统ASR局限的专业术语识别方案 【免费下载链接】SenseVoice Multilingual Voice Understanding Model 项目地址: https://gitcode.com/gh_mirrors/se/SenseVoice 在语音识别应用中&#xff0c;专业术语识别一直是技术痛点。传…

作者头像 李华