news 2026/4/17 22:48:40

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/4/16 6:15:37

终极指南:NVIDIA trt_pose实时姿态估计完全攻略

想要在边缘设备上实现毫秒级人体姿态检测吗&#xff1f;NVIDIA trt_pose项目正是为你量身打造的利器&#xff01;这个基于TensorRT加速的开源方案&#xff0c;让实时姿态估计在Jetson平台上变得触手可及。 【免费下载链接】trt_pose Real-time pose estimation accelerated wit…

作者头像 李华
网站建设 2026/4/16 14:19:59

VAP动画引擎技术革命:从硬件解码到视觉奇迹的完整解码

在移动互联网时代&#xff0c;动画效果已成为提升用户体验的关键因素。然而&#xff0c;传统动画方案始终在文件大小、解码性能和特效支持之间艰难平衡。VAP&#xff08;Video Animation Player&#xff09;作为腾讯开源的高性能动画播放引擎&#xff0c;通过突破性的技术架构彻…

作者头像 李华
网站建设 2026/4/16 12:12:53

C语言位运算

位运算的分类与详细说明一、基本位运算1、按位与&#xff08;&&#xff09;功能&#xff1a;两个操作数对应位都为1时&#xff0c;结果位才为1 嵌入式应用&#xff1a;• 掩码操作&#xff1a;提取特定位的值// 提取低4位 uint8_t value 0x5A; uint8_t lower_nibble val…

作者头像 李华
网站建设 2026/4/8 16:38:20

EmotiVoice能否生成带有地方戏曲腔调的特色语音?

EmotiVoice能否生成带有地方戏曲腔调的特色语音&#xff1f; 在数字内容不断演进的今天&#xff0c;AI语音合成早已不再满足于“能说话”——用户期待的是有性格、有情绪、有文化底色的声音。尤其是在中华文化的语境下&#xff0c;地方戏曲那独特的咬字、行腔与节奏&#xff0c…

作者头像 李华
网站建设 2026/4/17 15:36:30

Docker 权限问题:为什么容器里读不到文件?

Docker 权限问题&#xff1a;为什么容器里读不到文件&#xff1f;这是 Docker 使用过程中非常典型、但极具迷惑性的问题之一&#xff1a;文件明明存在&#xff0c;路径也没写错&#xff0c;但容器里就是读不到、写不了&#xff0c;甚至直接 Permission denied。本文将从 Linux …

作者头像 李华
网站建设 2026/4/17 7:01:42

COLMAP三维重建性能瓶颈突破:5个Eigen矩阵优化技巧实战指南

COLMAP三维重建性能瓶颈突破&#xff1a;5个Eigen矩阵优化技巧实战指南 【免费下载链接】colmap COLMAP - Structure-from-Motion and Multi-View Stereo 项目地址: https://gitcode.com/GitHub_Trending/co/colmap 在计算机视觉领域&#xff0c;COLMAP作为业界领先的三…

作者头像 李华