跨平台基于形状的模板匹配:OpenCV 在 C++/C# 中的实践
基于形状的模板匹配旨在通过比较模板和图像中对象的形状特征来寻找匹配区域。与基于灰度值的匹配不同,它对光照变化、噪声等因素有更好的鲁棒性。在 OpenCV 中,有多种方法可以实现基于形状的模板匹配,比如使用轮廓匹配等。
模板匹配,C++/C#,Windows,linux,arm下都可用,基于形状的模板匹配,基于openCV
在计算机视觉领域,模板匹配是一项极为重要的技术,它可以帮助我们在一幅图像中找到与给定模板最匹配的区域。今天咱们就来聊聊基于形状的模板匹配,并且看看如何利用 OpenCV 在 C++ 和 C# 中实现,同时确保在 Windows、Linux 和 ARM 平台下都能顺利运行。
什么是基于形状的模板匹配
基于形状的模板匹配旨在通过比较模板和图像中对象的形状特征来寻找匹配区域。与基于灰度值的匹配不同,它对光照变化、噪声等因素有更好的鲁棒性。在 OpenCV 中,有多种方法可以实现基于形状的模板匹配,比如使用轮廓匹配等。
C++ 实现
首先来看 C++ 版本。我们需要引入 OpenCV 的头文件:
#include <opencv2/opencv.hpp>
#include <iostream>
接下来,我们读取模板图像和待搜索的图像:
cv::Mat templateImage = cv::imread("template.png", cv::IMREAD_GRAYSCALE);
cv::Mat inputImage = cv::imread("input.png", cv::IMREAD_GRAYSCALE);
if (templateImage.empty() || inputImage.empty()) {
std::cout << "Could not open or find the images" << std::endl;
return -1;
}
这里先简单检查下图像是否读取成功,如果没成功就输出提示并退出程序。

然后进行模板匹配操作,OpenCV 提供了 matchTemplate 函数。这里我们用 TMCCOEFFNORMED 方法,它是一种基于归一化互相关的匹配方式:
cv::Mat result;
cv::matchTemplate(inputImage, templateImage, result, cv::TM_CCOEFF_NORMED);
matchTemplate 函数会在 inputImage 上滑动 templateImage,计算每个位置的匹配程度,并将结果存储在 result 中。result 的大小是 (inputImage.cols - templateImage.cols + 1, inputImage.rows - templateImage.rows + 1)。
接下来找到匹配度最高的位置:
double minVal, maxVal;
cv::Point minLoc, maxLoc;
cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);
cv::Point matchLoc = maxLoc;
minMaxLoc 函数可以帮我们找到 result 矩阵中的最小值、最大值及其位置。这里我们认为最大值对应的位置就是模板匹配的最佳位置。

最后,我们在原图上标记出匹配区域:
cv::rectangle(inputImage, matchLoc, cv::Point(matchLoc.x + templateImage.cols, matchLoc.y + templateImage.rows), cv::Scalar(0, 255, 0), 2);
cv::imshow("Matched Image", inputImage);
cv::waitKey(0);
通过 rectangle 函数在 inputImage 上绘制矩形框,imshow 函数显示结果图像,waitKey(0) 等待用户按键关闭窗口。
C# 实现
C# 中使用 OpenCV 也很方便,借助 EmguCV 库(它是 OpenCV 的.NET 包装)。先添加 EmguCV 的引用。
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using System;
读取图像的代码如下:
Image<Gray, byte> templateImage = new Image<Gray, byte>("template.png");
Image<Gray, byte> inputImage = new Image<Gray, byte>("input.png");
if (templateImage == null || inputImage == null)
{
Console.WriteLine("Could not open or find the images");
return;
}
同样先检查图像是否读取成功。
模板匹配,C++/C#,Windows,linux,arm下都可用,基于形状的模板匹配,基于openCV

接着进行模板匹配:
Image<Gray, float> result = inputImage.MatchTemplate(templateImage, TemplateMatchingType.CcoeffNormed);
MatchTemplate 方法在 EmguCV 中同样实现了模板匹配功能,这里同样使用 CcoeffNormed 类型。
找到最佳匹配位置:
double[] minMax = result.MinMax();
Point matchLoc = result.Maximum;
MinMax 方法获取匹配结果图像中的最小值和最大值,Maximum 属性获取最大值对应的位置。

最后标记并显示结果:
inputImage.Draw(new Rectangle(matchLoc, templateImage.Size), new Gray(0), 2);
CvInvoke.Imshow("Matched Image", inputImage);
CvInvoke.WaitKey(0);
Draw 方法在 inputImage 上绘制矩形,Imshow 和 WaitKey 与 C++ 中的功能类似,用于显示图像和等待用户按键。
跨平台性
OpenCV 本身是跨平台的,无论是在 Windows、Linux 还是 ARM 平台下,只要安装好相应的 OpenCV 库(或 EmguCV 库),并进行正确的配置,上述代码基本无需修改就能运行。在 Linux 下,安装 OpenCV 库通常可以通过包管理器完成。在 ARM 平台上,比如树莓派,也可以编译安装 OpenCV 来使用这些功能。
通过以上代码示例,我们看到了如何在不同编程语言(C++ 和 C#)中,利用 OpenCV 实现跨平台的基于形状的模板匹配。这一技术在诸如目标检测、图像识别等众多领域都有着广泛的应用,希望大家可以根据自己的需求进一步探索和拓展。

更多推荐
所有评论(0)