OpenCv案例(十二):基于OpenCVSharp学习之模板匹配寻找距离中心位置最近的目标

这篇具有很好参考价值的文章主要介绍了OpenCv案例(十二):基于OpenCVSharp学习之模板匹配寻找距离中心位置最近的目标。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1:需求:在原图中,有多个特征点和模板图像一模一样,因此,寻找原图中中心位置最近的特征点位(模板匹配详解);原图如下所示:

opencv 找离中心最近的点,OpenCVSharp视觉学习,OpenCv,C#,学习,计算机视觉,人工智能

模板图像:

                                                                        opencv 找离中心最近的点,OpenCVSharp视觉学习,OpenCv,C#,学习,计算机视觉,人工智能

2:现要求匹配找到距离原图中心位置最近的特征位置;例如,在下图中找到红色十字标记处。

opencv 找离中心最近的点,OpenCVSharp视觉学习,OpenCv,C#,学习,计算机视觉,人工智能

 3:模板匹配,全局搜索相似特征位置,并且标记出,结果如下:

opencv 找离中心最近的点,OpenCVSharp视觉学习,OpenCv,C#,学习,计算机视觉,人工智能

4:想要的结果位置,下图用红色方框标记:

 opencv 找离中心最近的点,OpenCVSharp视觉学习,OpenCv,C#,学习,计算机视觉,人工智能

 5:代码如下:

private Point MatchTemplate(Mat tempalte, Mat srcPic, double matchValue)
        {
            using (Mat result = new Mat()) //匹配结果
            {                             //模板匹配
                double minVul;
                double maxVul;
                Point tempPoint = new Point();
                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.MatchTemplate(srcPic, tempalte, result, TemplateMatchModes.CCoeffNormed);//CCoeffNormed  最好匹配为1,值越小匹配越差 xxxNormed的算法
                //Cv2.Normalize(result, result, 0, 1, NormTypes.MinMax, -1);//归一化
                Cv2.MinMaxLoc(result, out minVul, out maxVul, out minLoc, out maxLoc);//查找极值
                //matchLoc = maxLoc;//图像中左上角的坐标位置(应该叫min)
                //result.Set(matchLoc.Y, matchLoc.X, 0);//改变最大值为最小值  
                //Mat mask = srcPic.Clone();//复制整个矩阵
                //画框显示 :对角线画框,起点和终点,都用Point,线宽
                //if (maxVul > matchValue)
                //{
                //    Cv2.Rectangle(mask, matchLoc, new OpenCvSharp.Point(matchLoc.X + tempalte.Cols, matchLoc.Y + tempalte.Rows), Scalar.Green, 2);//2代表画的线条的宽细程度
                //}
                //循环查找 画框显示
                double minDistance = int.MaxValue;
                //double threshold = 0.71;
                int minLocX = int.MaxValue;
                int minLocY = int.MaxValue;
                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 > matchValue)
                        {
                            double dis = CalculateDistance((j + maxLoc.X), (i + maxLoc.Y), (result.Width / 2), (result.Height / 2));
                            if (dis < minDistance)
                            {
                                minDistance = dis;
                                minLocY = j + maxLoc.X;
                                minLocX = i + maxLoc.Y;
                                //    File.AppendAllText(System.AppDomain.CurrentDomain.BaseDirectory + @"Log\LogError\log" + DateTime.Now.ToString("yyyyMMdd")
                                //+ "imgInfo.txt", "minDistance:" + minDistance + "  maxLocX:" + minLocX + "  maxLocY" + minLocY + "\r\n");
                            }
                            //画框显示
                            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);
                        }
                    }
                }
                if (minDistance < int.MaxValue)
                {
                    tempPoint.X = minLocY;
                    tempPoint.Y = minLocX;
                }
                Cv2.ImWrite(@"save\" + DateTime.Now.ToString("yyyyMMddHHmmssfff") + ".png", maskMulti);
                return tempPoint;//OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mask);
            }
        }

double CalculateDistance(double x1, double y1, double x2, double y2)
        {
            double distance = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
            return distance;
        }

        如有不正确地方,欢迎指正。

附1:Cv2.MatchTemplate函数参数详解:

cv2.matchTemplate() 是模板匹配的函数之一,其参数如下:

image 待匹配的图像,应该是一个灰度图像。
template 模板图像,应该是一个灰度图像。
method 匹配方法,有6种不同的方法可以选择,分别是:
cv2.TM_CCOEFF 相关系数匹配法。
cv2.TM_CCOEFF_NORMED 归一化的相关系数匹配法。
cv2.TM_CCORR 相关匹配法。
cv2.TM_CCORR_NORMED 归一化的相关匹配法。
cv2.TM_SQDIFF 平方差匹配法。
cv2.TM_SQDIFF_NORMED 归一化的平方差匹配法。
result 匹配结果数组,必须是单通道32位浮点数类型的数组。
mask 需要匹配的区域,可以不指定。
use_mask 是否要使用掩膜,可以不指定。

其中,匹配方法是最重要的参数,不同的方法适用于不同的情况。下面介绍各种匹配方法的具体作用:

cv2.TM_CCOEFF 相关系数匹配法。计算模板图像与待匹配图像的线性相关系数,该值越大则表示匹配度越高。适用于模板图像和待匹配图像的亮度差异较小的情况。
cv2.TM_CCOEFF_NORMED 归一化的相关系数匹配法。计算模板图像与待匹配图像的归一化线性相关系数,该值越大则表示匹配度越高。适用于模板图像和待匹配图像的亮度差异较大的情况。
cv2.TM_CCORR 相关匹配法。计算模板图像与待匹配图像的互相关系数,该值越大则表示匹配度越高。适用于模板图像和待匹配图像的亮度变化较小、平移变化较大的情况。
cv2.TM_CCORR_NORMED 归一化的相关匹配法。计算模板图像与待匹配图像的归一化互相关系数,该值越大则表示匹配度越高。适用于模板图像和待匹配图像的亮度变化较大、平移变化较大的情况。
cv2.TM_SQDIFF 平方差匹配法。计算模板图像与待匹配图像的平方差,该值越小则表示匹配度越高。适用于模板图像的亮度与待匹配图像有很大差异的情况。
cv2.TM_SQDIFF_NORMED 归一化的平方差匹配法。计算模板图像与待匹配图像的归一化平方差,该值越小则表示匹配度越高。适用于模板图像的亮度与待匹配图像有较大差异的情况。

使用不同的匹配方法,可以适应不同的场景,提高匹配的准确性。需要根据具体情况选择合适的匹配方法。

附2:Cv2.MinMaxLoc函数参数详解:

cv2.minMaxLoc()是OpenCV中用于查找图像中最小值和最大值位置的函数,其参数如下:

src 输入的单通道数组图像。
mask 可选的掩膜。如果传入了掩膜,则只会查找掩膜图像中非零像素处的最值。
minVal 返回最小值。
maxVal 返回最大值。
minLoc 返回最小值所在的位置。
maxLoc 返回最大值所在的位置。

该函数能够在图像中查找最大值和最小值,以及它们的位置。其中,最大值和最小值的位置分别被保存在maxLocminLoc中,可以结合这些位置进行后续的图像处理工作。

问:Cv2.MatchTemplate方法之后使用到Cv2.MinMaxLoc函数,为什么?

答:在使用cv2.matchTemplate()方法进行模板匹配时,可能会存在多个匹配位置或存在误匹配的情况。因此,在匹配结果中需要用cv2.minMaxLoc()函数寻找最大值/最小值和它们的位置,以保证匹配结果的准确性。

具体来说,在使用cv2.matchTemplate()方法匹配模板图像和待匹配图像后,会生成一个匹配矩阵,其中每个数值表示这个位置的匹配程度。最大或最小值出现在匹配矩阵中,需要通过cv2.minMaxLoc()函数获取这些值对应的坐标。

例如,我们可以通过将匹配矩阵进行归一化(即获取矩阵中数值最大/最小值处的位置),来获取匹配度最高/最低的位置。这样可以排除掉一些误匹配的位置,提高匹配的准确性。文章来源地址https://www.toymoban.com/news/detail-819695.html

到了这里,关于OpenCv案例(十二):基于OpenCVSharp学习之模板匹配寻找距离中心位置最近的目标的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 基于OpenCV的模板匹配算法探索与实践

    目录 一、模板匹配能够做什么? 二、六种模板匹配算法解析 1、平方差匹配法method=TM_SQDIFF 2、归一化平方差匹配法method=TM_SQDIFF_NORMED 3、相关匹配法method=TM_CCORR 4、归一化相关匹配法method=TM_ CCORR_NORMED 5、系数匹配法method=TM_CCOEFF 6、化相关系数匹配法 method=TM_CCOEFF_NORMED 三、模板

    2024年04月13日
    浏览(46)
  • 基于 NCC/灰度信息 的模板匹配算法(QT + Opencv + C++),10ms内获取匹配结果,部分源码

    文后代码,优化效果图结尾处,最快3ms得到匹配结果 NCC,全称为Normalized Cross Correlation,即归一化互相关系数, 在模板匹配中使用的非常非常广泛,也是众多模板匹配方法中非常耀眼的存在, 这个匹配的理论核心基础公式如下: 其实Opencv的matchTemplate函数使用的就是这个公式

    2024年02月08日
    浏览(47)
  • 基于opencv4.5多目标/多角度与多尺度模板匹配(含源码)

    在OpenCV中有个用于模板匹配的基本函数matchTemplate(),该函数使用某模板在搜索图像中进行搜索时,只能搜索到和模板完全一样的地方,一旦在搜索图像中要搜索的区域相较于模板是旋转了、放大缩小了或者部分遮掩了就无法匹配到结果了,实际项目应用不太友好. 本文主要介绍

    2024年02月02日
    浏览(57)
  • opencv案例06-基于opencv图像匹配的消防通道障碍物检测与深度yolo检测的对比

    技术背景 消防通道是指在各种险情发生时,用于消防人员实施营救和被困人员疏散的通道。消防法规定任何单位和个人不得占用、堵塞、封闭消防通道。事实上,由于消防通道通常缺乏管理,导致各种垃圾,物品以及车辆等障碍物常常出现在消防通道中,堵塞消防通道,当险

    2024年02月03日
    浏览(44)
  • OpenCV 笔记:cv2.matchTemplate() 单模板匹配和多模板匹配

            模板匹配是用来在一副大图中搜寻查找模版图像位置的方法。         模板匹配实现简单(2~3行代码),计算效率高,不需要执行阈值化、边缘检测等操作来生成二值化图像。 但是: 如果输入图像中存在变化的因素,包括旋转、缩放、视角变化等,模板匹配很容

    2024年02月05日
    浏览(48)
  • opencv#27模板匹配

         例如给定一张图片,如上图大矩阵所示,然后给定一张模板图像,如上图小矩阵。      我们在大图像中去搜索与小图像中相同的部分或者是最为相似的内容。比如我们在图像中以灰色区域给出一个与模板图像尺寸大小一致的区域,通过比较灰色区域中的内容与模板中

    2024年01月23日
    浏览(46)
  • Opencv——图像模板匹配

    什么是模板匹配呢? 看到这里大家是否会觉得很熟悉的感觉涌上心头!在人脸识别是不是也会看见 等等。 模板匹配可以看作是对象检测的一种非常基本的形式。使用模板匹配,我们可以使用包含要检测对象的“模板”来检测输入图像中的对象。 参数:(img: 原始图像、

    2024年02月16日
    浏览(43)
  • 用OpenCV进行模板匹配

    今天我们来研究一种传统图像处理领域中对象检测和跟踪不可或缺的方法——模板匹配,其主要目的是为了在图像上找到我们需要的图案,这听起来十分令人兴奋。 所以,事不宜迟,让我们直接开始吧! 模板匹配的算法的核心十分简单:它将模板与源图像中的每个部分进行

    2024年02月10日
    浏览(45)
  • OpenCV 模板匹配 matchTemplate

    模板匹配是一项在一副图像中寻找与另一幅模板图像最匹配(相似)部分的技术。模板匹配不是基于直方图的,而是通过在输入图像上滑动图像块(模板)同时对比相似度,来对模板和输入图像进行匹配的一种方法。 应用: (1)目标查找定位 (2)运动物体跟踪 image:待搜

    2024年02月04日
    浏览(66)
  • OpenCV(十九):模板匹配

    1.模板匹配:      OpenCV提供了一个模板匹配函数,用于在图像中寻找给定模板的匹配位置。 2.图像模板匹配函数matchTemplate  void matchTemplate( InputArray image, InputArray templ, OutputArray result, int method, InputArray mask = noArray() ); image:待模板匹配的原图像,图像数据类型为CV 8U和CV 32F两者中

    2024年02月09日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包