1: Build a test demo
- Add the OpenCVSharp installation package to the C# project as shown below (the picture is the VS2015 version)
- The NuGet tool adds OpenCvSharp3-AnyCPU to the project:
- Tools >> NuGet Package Manager >> Manage NuGet Packages for Solutions
2: Test Demo
- First, add the reference:
using OpenCvSharp
; - Second, add the following function code snippet
Preparations before using the template matching method
-
/// <summary> /// 模板匹配 /// </summary> /// <param name="srcImg">被匹配图像路径</param> /// <param name="tempImg">模板图像路径</param> /// <returns>当前匹配完成后 模板在匹配图像中左上角的坐标点</returns> public OpenCvSharp.Point TemplateMatch(string srcImg, string tempImg, out double matchVal) { OpenCvSharp.Point tempPoint = new OpenCvSharp.Point(); Mat srcImage = Cv2.ImRead(srcImg, ImreadModes.Grayscale); Mat tempImage = Cv2.ImRead(tempImg, ImreadModes.Grayscale); Bitmap bmp = MatchTemplate(tempImage, srcImage, out tempPoint, out matchVal); //保存图像路径 bmp.Save(System.AppDomain.CurrentDomain.BaseDirectory + @"ImgFile\processedImg" + DateTime.Now.ToString("yyMMddHHmmss") + ".bmp"); return tempPoint; }
template matching method
-
/// <summary> /// 模板匹配 /// </summary> /// <param name="tempalte">模板图片像</param> /// <param name="srcPic">被匹配图像</param> /// <param name="tempPoint">返回模板图像在匹配图像中的坐标位置</param> /// <returns>标注匹配区域的图像</returns> private Bitmap MatchTemplate(Mat tempalte, Mat srcPic, out OpenCvSharp.Point tempPoint, out double matchValue) { Mat result = new Mat(); //模板匹配 Cv2.MatchTemplate(srcPic, tempalte, result, TemplateMatchModes.CCoeffNormed);//CCoeffNormed 最好匹配为1,值越小匹配越差 Double minVul; Double maxVul; OpenCvSharp.Point minLoc = new OpenCvSharp.Point(0, 0); OpenCvSharp.Point maxLoc = new OpenCvSharp.Point(0, 0); OpenCvSharp.Point matchLoc = new OpenCvSharp.Point(0, 0); //归一化 Cv2.Normalize(result, result, 0, 1, NormTypes.MinMax, -1); //寻找极值 Cv2.MinMaxLoc(result, out minVul, out maxVul, out minLoc, out maxLoc); //最大值坐标 matchLoc = maxLoc; Mat mask = srcPic.Clone();//复制整个矩阵 //画框显示 :对角线画框,起点和终点,都用Point,线宽 Cv2.Rectangle(mask, matchLoc, new OpenCvSharp.Point(matchLoc.X + tempalte.Cols, matchLoc.Y + tempalte.Rows), Scalar.Green, 2);//2代表画的线条的宽细程度 //Console.WriteLine("最大值:{0},X:{1},Y:{2}", maxVul, matchLoc.Y, matchLoc.X); matchValue = maxVul; tempPoint.X = matchLoc.X; tempPoint.Y = matchLoc.Y; //循环查找画框显示 Double threshold = 0.91; Mat maskMulti = srcPic.Clone(); for (int i = 1; i < result.Rows - tempalte.Rows; i += tempalte.Rows) { for (int j = 1; j < result.Cols - tempalte.Cols; j += tempalte.Cols) { Rect roi = new Rect(j, i, tempalte.Cols, tempalte.Rows); //建立感兴趣 Mat RoiResult = new Mat(result, roi); Cv2.MinMaxLoc(RoiResult, out minVul, out maxVul, out minLoc, out maxLoc);//查找极值 matchLoc = maxLoc;//最大值坐标 if (maxVul > threshold) { //画框显示 Cv2.Rectangle(maskMulti, new OpenCvSharp.Point(j + maxLoc.X, i + maxLoc.Y), new OpenCvSharp.Point(j + maxLoc.X + tempalte.Cols, i + maxLoc.Y + tempalte.Rows), Scalar.Green, 2); string axis = '(' + Convert.ToString(i + maxLoc.Y) + ',' + Convert.ToString(j + maxLoc.X) + ')'; Cv2.PutText(maskMulti, axis, new OpenCvSharp.Point(j + maxLoc.X, i + maxLoc.Y), HersheyFonts.HersheyPlain, 1, Scalar.Red, 1, LineTypes.Link4); } } } //返回匹配后图像 return OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mask); }
3: Test results
- matched image
- template image
- matching result
- The effect can be dropped, but after many different experiments, the results show that there are still some errors
3: Learning materials
- OpenCv Chinese Website: OpenCV Chinese Website-Forum- Powered by Discuz!
- OpenCV official tutorial-Template Matching: OpenCV template matching_w3cschool