OpenCv Case (8): Template Matching Based on OpenCVSharp Learning

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

Guess you like

Origin blog.csdn.net/qq_37835727/article/details/111315401
Recommended