编辑
2025-09-26
C#
00

目录

安装 OpenCvSharp
实例一
加载图像和模板
代码
输出结果

OpenCvSharp是OpenCV库的C#封装,提供了丰富的图像处理功能。模板匹配是一种在大图像中查找小模板图像位置的技术。在这篇文章中,我们将介绍如何使用OpenCvSharp进行模板匹配,并考虑目标尺寸大小的匹配。

以下是实现模板匹配的详细步骤:

  1. 安装 OpenCvSharp
  2. 加载图像和模板
  3. 进行模板匹配
  4. 计算匹配结果的尺寸
  5. 在接受范围内绘制匹配结果

安装 OpenCvSharp

你可以通过NuGet包管理器来安装OpenCvSharp。运行以下命令:

Bash
Install-Package OpenCvSharp4 Install-Package OpenCvSharp4.runtime.win

实例一

加载图像和模板

目标图

image.png

模板

image.png

首先,我们需要加载包含目标图像和模板图像的文件。

代码

C#
using OpenCvSharp; namespace App1 { internal class Program { static void Main(string[] args) { // 读取待搜索的大图和模板小图 Mat targetImage = Cv2.ImRead("pcb_layout.png", ImreadModes.Color); Mat templateImage = Cv2.ImRead("template.png", ImreadModes.Color); // 确保图片正确加载 if (targetImage.Empty() || templateImage.Empty()) { Console.WriteLine("图像加载失败!"); return; } // 运行模板匹配 Mat result = new Mat(); Cv2.MatchTemplate(targetImage, templateImage, result, TemplateMatchModes.CCoeffNormed); // 设定匹配结果的阈值 double threshold = 0.8; // 找到所有匹配度高于阈值的匹配结果 List<Rect> matches = new List<Rect>(); for (int y = 0; y < result.Rows; y++) { for (int x = 0; x < result.Cols; x++) { if (result.At<float>(y, x) >= threshold) { Rect matchRect = new Rect(new Point(x, y), new Size(templateImage.Width, templateImage.Height)); matches.Add(matchRect); } } } // 计算匹配结果的尺寸并筛选有效匹配 List<Rect> validMatches = new List<Rect>(); foreach (var matchRect in matches) { double matchWidth = matchRect.Width; double matchHeight = matchRect.Height; double templateWidth = templateImage.Width; double templateHeight = templateImage.Height; double widthRatio = matchWidth / templateWidth; double heightRatio = matchHeight / templateHeight; bool isAcceptableMatch = widthRatio <= 1.2 && widthRatio >= 0.8 && heightRatio <= 1.2 && heightRatio >= 0.8; if (isAcceptableMatch) { validMatches.Add(matchRect); } } // 去除相互重叠的匹配结果 List<Rect> nonOverlappingMatches = FilterOverlappingMatches(validMatches); // 在目标图像上绘制矩形框以标注匹配区域 foreach (var match in nonOverlappingMatches) { Cv2.Rectangle(targetImage, match, Scalar.Red, 2); } Console.WriteLine($"{nonOverlappingMatches.Count} 个匹配找到!"); Cv2.ImShow("Matched Image", targetImage); Cv2.WaitKey(0); } // 函数用于去除重叠的匹配结果 static List<Rect> FilterOverlappingMatches(List<Rect> matches, double minOverlapRatio = 0.5) { List<Rect> filteredMatches = new List<Rect>(); foreach (var match in matches) { bool overlap = false; foreach (var filteredMatch in filteredMatches) { Rect intersection = match & filteredMatch; double intersectionArea = intersection.Width * intersection.Height; double matchArea = match.Width * match.Height; double filteredMatchArea = filteredMatch.Width * filteredMatch.Height; double overlapRatio = intersectionArea / Math.Min(matchArea, filteredMatchArea); if (overlapRatio > minOverlapRatio) { overlap = true; break; } } if (!overlap) { filteredMatches.Add(match); } } return filteredMatches; } } }

计算匹配结果尺寸并筛选有效的匹配。这里比较的是匹配区域与模板区域的宽高比,确保在接受的范围内(0.8到1.2之间)。

输出结果

image.png

本文作者:技术老小子

本文链接:

版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!