OpenCv案例(八):基于OpenCVSharp学习之模板匹配

1:建好测试Demo

  •  C#项目中添加好OpenCVSharp安装包 如下图(图中是VS2015版本)
  •  NuGet工具给项目添加OpenCvSharp3-AnyCPU:
  • 工具>>NuGet包管理器>>管理解决方案的NuGet程序包

2:测试Demo

  • 首先,添加引用:using OpenCvSharp;
  • 其次,添加如下函数代码代码段

       对模板匹配方法使用前的准备

  •  /// <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;
            }

    模板匹配方法

  • /// <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:测试结果

  • 被匹配图像
  • 模板图像
  •  匹配结果
  • 效果可以滴,但是经过多次不同程度实验结果表明,误差还是有的

3:学习资料

猜你喜欢

转载自blog.csdn.net/qq_37835727/article/details/111315401