模板匹配——GeoMatch 源码解析

网址:https://www.codeproject.com/Articles/99457/Edge-Based-Template-Matching
其算法思路与流程,在网址下方也有说明。以下为个人配合其说明与源码的一些理解。


可以下载到,src和demo两个文件包。
其中demo是需要opencv2.0的库才可以运行。



打开GeoMatch_src工程,工程版本实在太老了。只能强制升级到高版本的工程文件。
此时工程属性也是缺失环境的。在解决方案管理器中右键属性-》清除掉依赖的opencv库,然后替换上自己的opencv环境(注:必须是2.xx 版本的)
我这里用的是64位的2.4.10

然后编译。正常通过了。
运行:

在这个位置把我抛出来了,看了下demo中的readme。
发现是通过外部传入字符串组调用的。
打开demo中的run,bat中可以找到具体调用的指令


其中最前面的 GeoMatch 是指运行“GeoMatch.exe”所以跳过。

为了方便测试在void WrongUsage();下插入以下代码

	char*ppChar[12];
	char*Param = "-t template.jpg -l 10 -h 100 -s search1.jpg -m 0.7 -g 0.9";
	for (int i = 0; i < 12; i++)
	{
		ppChar[i] = new char[512];//测试用,懒得删
		memset(ppChar[i], 0, 512);
		int idx = 0;
		while (*Param!=' ')
		{
			ppChar[i][idx++] = *Param++;
		}
		Param++;
	}

	CommandParser cp(12,ppChar); // object to parse command line

现在代码就可以正常跑了。

 

创建模板过程:

     1.使用Sobel 获取8bit原图的x y 向一阶导(灰度变化速率) 并存储到16bit的图中。(此处为什么是16bit?)

    2.获得每个点位置的梯度大小和方向的矩阵 (注:gx,gy 分别为某点上 的横向,纵向一阶导的值)
           大小:Magnitude = Sqrt(gx^2 +gy^2)
           方向:Direction = invtan (gy / gx) 再把方向规范化到 0,45,90,135 四个方向(此处的方向仅用作非极大值抑制)

   3.对整图做非极大值抑制

          详细:通过矢量方向,判断该矢量方向上的前后值是小于当前值。

          eg: 方向为 45° 那么将会检查该像素 右上 左下 两个位置的值。如果当前值均大于该两个值,则保留。

4、滞后阈值处理
        详细:

                           阈值《minContrast                                        移除该点

                            maxContrast》阈值》minContrast            其八邻域内无  任何点 大于 maxContrast  则移除该点。

                            阈值》maxContrast                                     直接保留该点

  5.以数组的方式 记录成功保留的矢量数据 (x,y, gx,gy, 根号( 1/Magnitude) )(为什么使用根号,看匹配得分定义)

 

6.规范化中心,其中 中心位置为所有矢量x,y的均值。

由此,创建模板结束。

 

匹配部分
1.求目标图片x,y向一阶导(同创建)

2.求得梯度大小图片,matGradMag为存储梯度数据的图像.
(其大小,计数为 根号(1/(dx^2+dy^2))
 

3.滑窗匹配

得分:累计每个特征矢量对应位置的(Temp_gx*Img_gx )+(Temp_gy*Img_gy)*

(  1/(Temp_gx^2+Temp_gy^2)  *  1/(Img_gx^2+Img_gy^2) )

其核心参考为,对应点位,dx,dy方向的综合梯度,是否与模板相近。

 

其中有个得分不足 判定,能够提早结束特征点遍历。

退出条件为:当前总得分《 min(贪心后得分和,理论最低得分和)

其中此处贪心值设置不合理。完全没用。

注意滑窗位置,以模板中心,从(0,0)开始滑,意味着窗口是超出目标图像区域的。



总结:
亮点1.使用了贪心值和不足分方式提前判定失败结果。
亮点2.匹配滑窗位置是以中心为基点匹配全图(得分图与原图大小一致)

问题1.太慢了!!!!!
问题2.x y向的梯度混淆了,使得匹配得分会整体偏高
问题3.未使用任何矢量,无法区分黑白。

阅读终点,创作起航,您可以撰写心得或摘录文章要点写篇博文。去创作
  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
OpenCV模版匹配是一种在图像中寻找给定模板的技术。该技术在多个领域中都有应用,如数字图像处理、计算机视觉等。 在OpenCV中,模版匹配的函数为`matchTemplate()`。其主要步骤如下: 1. 首先,我们需要加载原始图像和待匹配的模板图像。 2. 然后,使用模版图像和原始图像进行匹配。这一步骤中,我们可以选择多种匹配方法,如平方差匹配、相关性匹配和归一化相关性匹配。 3. 匹配后,我们可以使用`minMaxLoc()`函数找到匹配结果的最小值和最大值。 4. 最后,我们可以绘制矩形框来标记匹配的位置。 下面是一份简单的OpenCV模版匹配的源码示例: ```cpp #include <opencv2/opencv.hpp> int main() { // 加载原始图像和模版图像 cv::Mat img = cv::imread("original.png", cv::IMREAD_COLOR); cv::Mat templ = cv::imread("template.png", cv::IMREAD_COLOR); // 进行模版匹配 cv::Mat result; cv::matchTemplate(img, templ, result, cv::TM_CCOEFF_NORMED); // 寻找匹配结果中的最小值和最大值 double minVal, maxVal; cv::Point minLoc, maxLoc; cv::minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); // 绘制矩形框来标记匹配的位置 cv::rectangle(img, maxLoc, cv::Point(maxLoc.x + templ.cols, maxLoc.y + templ.rows), cv::Scalar(0, 255, 0), 2); // 显示结果图像 cv::imshow("Matched Image", img); cv::waitKey(0); return 0; } ``` 上述代码展示了一个简单的OpenCV模版匹配的流程。通过加载原始图像和模版图像,并使用`matchTemplate()`函数进行匹配,然后使用`minMaxLoc()`函数找到匹配结果的最大值位置,最后使用`rectangle()`函数绘制矩形框标记匹配位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

木穗

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值