模板匹配算法介绍与代码
- 格式:pdf
- 大小:392.41 KB
- 文档页数:4


亚像素模板匹配算法是一种用于图像处理和计算机视觉的技术,用于在图像中寻找与给定模板匹配的子图像,并确定其位置和方向。
该算法可以在像素级别上提供更高的精度,以处理图像中的微小变化和细节。
亚像素模板匹配算法通常基于以下步骤:
1. 定义模板:首先,需要定义一个与要搜索的子图像相似的模板。
模板可以是一个固定大小的矩形区域,也可以是根据特定特征(如边缘、纹理等)定义的自定义区域。
2. 滑动模板:将模板在目标图像上滑动,并计算模板与图像之间的相似度。
相似度通常通过计算模板和图像之间的像素差平方和(SSIM)或结构相似性度量(SSIM)来计算。
3. 寻找最佳匹配:在滑动过程中,记录每个位置的相似度值。
通过比较相似度值,可以确定与模板最匹配的子图像的位置。
4. 细化匹配位置:为了进一步提高精度,可以对匹配位置进行细化。
这可以通过在匹配位置周围进行插值或使用其他优化技术来实现。
亚像素模板匹配算法可以应用于许多领域,如目标跟踪、图像拼接、全景拼接等。
它可以帮助提高图像处理的精度和性能,特别是在需要处理微小变化和细节的场景中。
模板匹配加速⽅法——opencv背景概述OpenCV中⾃带的模板匹配算法,完全是像素基本的模板匹配,特别容易受到光照影响,光照稍微有所不同,该⽅法就会歇菜了!搞得很多OpenCV初学者刚学习到该⽅法时候很开⼼,⼀⽤该⽅法马上很伤⼼,悲喜交加,充分感受到了理想与现实的距离,不过没关系,这⾥介绍⼀种新的模板匹配算法,主要是基于图像边缘梯度,它对图像光照与像素迁移都有很强的抗⼲扰能⼒,据说Halcon的模板匹配就是基于此的加速版本,在⼯业应⽤场景中已经得到⼴泛使⽤。
算法原理该算法主要是基于图像梯度,实现基于梯度级别的NCC模板匹配,基于Sobel梯度算⼦得到dx, dy, magnitude通过Canny算法得到边缘图像、基于轮廓发现得到所有的轮廓点集,基于每个点计算该点的dx、dy、magnitude(dxy)三个值。
⽣成模板信息。
然后对输⼊的图像进⾏Sobel梯度图像之后,根据模型信息进⾏匹配,这样的好处有两个:梯度对光照有很强的抗⼲扰能⼒,对模板匹配的抗光照⼲扰基于梯度匹配,可以对⽬标图像上出现的微⼩像素迁移进⾏抵消。
算法实现代码详解梯度图像计算Mat gx, gy;Sobel(gray, gx, CV_32F, 1, 0);Sobel(gray, gy, CV_32F, 0, 1);Mat magnitude, direction;cartToPolar(gx, gy, magnitude, direction);long contoursLength = 0;double magnitudeTemp = 0;int originx = contours[ 0][ 0].x;int originy = contours[ 0][ 0].y;模板⽣成// 提取dxdymaglog信息vector<vector<ptin>> contoursInfo;// 提取相对坐标位置vector<vector<Point>> contoursRelative;// 开始提取for(int i = 0; i < contours.size(); i++) {int n = contours[i].size();contoursLength += n;contoursInfo.push_back(vector<ptin>(n));vector<Point> points(n);for(int j = 0; j < n; j++) {int x = contours[i][j].x;int y = contours[i][j].y;points[j].x = x - originx;points[j].y = y - originy;ptin pointInfo;pointInfo.DerivativeX = gx.at<float>(y, x);pointInfo.DerivativeY = gy.at<float>(y, x);magnitudeTemp = magnitude.at<float>(y, x);pointInfo.Magnitude = magnitudeTemp;if(magnitudeTemp != 0)pointInfo.MagnitudeN = 1/ magnitudeTemp;contoursInfo[i][j] = pointInfo;}contoursRelative.push_back(points);}计算⽬标图像梯度// 计算⽬标图像梯度Mat grayImage;cvtColor(src, grayImage, COLOR_BGR2GRAY);Mat gradx, grady;Sobel(grayImage, gradx, CV_32F, 1, 0);Sobel(grayImage, grady, CV_32F, 0, 1);Mat mag, angle;cartToPolar(gradx, grady, mag, angle);NCC模板匹配double partialScore = 0;double resultScore = 0;int resultX = 0;int resultY = 0;double start = (double)getTickCount();for(int row = 0; row < grayImage.rows; row++) {for(int col = 0; col < grayImage.cols; col++) {double sum = 0;long num = 0;for(int m = 0; m < contoursRelative.size(); m++) {for(int n = 0; n < contoursRelative[m].size(); n++) {num += 1;int curX = col + contoursRelative[m][n].x;int curY = row + contoursRelative[m][n].y;if(curX < 0|| curY < 0|| curX > grayImage.cols - 1|| curY > grayImage.rows - 1) { continue;}// ⽬标边缘梯度double sdx = gradx.at<float>(curY, curX);double sdy = grady.at<float>(curY, curX);// 模板边缘梯度double tdx = contoursInfo[m][n].DerivativeX;double tdy = contoursInfo[m][n].DerivativeY;// 计算匹配if((sdy != 0|| sdx != 0) && (tdx != 0|| tdy != 0)){double nMagnitude = mag.at<float>(curY, curX);if(nMagnitude != 0)sum += (sdx * tdx + sdy * tdy) * contoursInfo[m][n].MagnitudeN / nMagnitude;}// 任意节点score之和必须⼤于最⼩阈值partialScore = sum / num;if(partialScore < min((minScore - 1) + (nGreediness * num), nMinScore * num))break;}}// 保存匹配起始点if(partialScore > resultScore){resultScore = partialScore;resultX = col;resultY = row;}}}运⾏效果正常光照光照⾮常暗改进:不需要全局匹配,可以对⽬标图像先做⼀个⼩梯度阈值,然后再进⾏匹配,提升速度、构造⽬标图像⾦字塔,实现多分辨率模板匹配⽀持!。
4.OpenCV-Python——模版匹配、直⽅图⼀、模版匹配1、模版匹配 模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与(图像被模板覆盖的地⽅)的差别程度,这个差别程度的计算⽅法在opencv⾥有6种,然后将每次计算的结果放⼊⼀个矩阵⾥,作为结果输出。
假如原图形是AxB⼤⼩,⽽模板是axb⼤⼩,则输出结果的矩阵是(A-a+1)x(B-b+1)。
TM_SQDIFF:计算平⽅不同,计算出来的值越⼩,越相关TM_CCORR:计算相关性,计算出来的值越⼤,越相关TM_CCOEFF:计算相关系数,计算出来的值越⼤,越相关TM_SQDIFF_NORMED:计算归⼀化平⽅不同,计算出来的值越接近0,越相关TM_CCORR_NORMED:计算归⼀化相关性,计算出来的值越接近1,越相关TM_CCOEFF_NORMED:计算归⼀化相关系数,计算出来的值越接近1,越相关1# *******************模版匹配**********************开始2import cv23import numpy as np4import matplotlib.pyplot as plt56# 模板匹配7 img = cv2.imread('lena.jpg', 0)8 template = cv2.imread('face.jpg', 0)910 h, w = template.shape[:2]1112 methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',13'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']1415# 匹配⽅法16 res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)17print(res.shape)18# 匹配结果返回19 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)20print(min_val,max_val,min_loc,max_loc)2122# 6种不同⽅法⽐较23for meth in methods:24 img2 = img.copy()2526# 匹配⽅法的真值27 method = eval(meth)28print (method)29 res = cv2.matchTemplate(img, template, method)30 min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)3132# 如果是平⽅差匹配TM_SQDIFF或归⼀化平⽅差匹配TM_SQDIFF_NORMED,取最⼩值33if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:34 top_left = min_loc35else:36 top_left = max_loc37 bottom_right = (top_left[0] + w, top_left[1] + h)3839# 画矩形40 cv2.rectangle(img2, top_left, bottom_right, 255, 2)4142 plt.subplot(121), plt.imshow(res, cmap='gray')43 plt.xticks([]), plt.yticks([]) # 隐藏坐标轴44 plt.subplot(122), plt.imshow(img2, cmap='gray')45 plt.xticks([]), plt.yticks([])46 plt.suptitle(meth)47 plt.show()48# *******************模版匹配**********************结束六种⽅法的匹配结果:2、多个匹配1# *******************膜版匹配-多个匹配**********************开始2import cv23import numpy as np4import matplotlib.pyplot as plt56 img_rgb = cv2.imread('mario.jpg')7 img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)8 template = cv2.imread('mario_coin.jpg', 0)9 h, w = template.shape[:2]1011 res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)12 threshold = 0.813# 取匹配程度⼤于%80的坐标14 loc = np.where(res >= threshold)15for pt in zip(*loc[::-1]): # *号表⽰可选参数16 bottom_right = (pt[0] + w, pt[1] + h)17 cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)1819 cv2.imshow('img_rgb', img_rgb)20 cv2.waitKey(0)21# *******************膜版匹配-多个匹配**********************结束⼆、直⽅图cv2.calcHist(images,channels,mask,histSize,ranges)images: 原图像图像格式为 uint8 或 float32。
模板匹配匹配率minmaxloc函数-回复什么是模板匹配?模板匹配是一种在图像处理领域中常用的技术,用于在一幅图像中寻找与给定模板最相似的图像区域。
也可以理解为在一张图片中寻找一个特定的目标物体。
模板匹配是计算机视觉中的基本问题,应用广泛,例如在目标识别、物体追踪、图像对齐等方面都有重要作用。
为了实现模板匹配,需要使用一种测量方法来描述图像的相似程度。
常用的测量方法包括均方差方法、相关系数方法和相似性度量方法等。
其中,均方差方法是最常见的一种,其核心思想是计算模板图像与待匹配图像之间像素值的差异,并得出一个相似度分数。
通过遍历整个图像,将模板与图像中的每一块区域进行比对,并计算出每一块区域与模板的相似度分数,最终找到与模板最相似的区域。
在OpenCV中,提供了一个方便易用的模板匹配函数——cv2.matchTemplate()。
这个函数接受两个参数:待匹配图像和模板图像。
函数返回一个和待匹配图像相同大小的输出图像,其中每个像素表示该位置与模板的匹配程度。
可以通过比较像素值来判断相似度的高低,以及找到最合适的匹配位置。
接下来介绍一个在模板匹配中常用的函数——cv2.minMaxLoc()。
这个函数用于在给定的图像中找到最大和最小像素值及其对应的位置。
在模板匹配的场景下,我们可以利用这个函数找到最相似的区域。
cv2.minMaxLoc()函数的使用方式相对简单。
首先,我们需要将模板匹配输出的图像传入该函数,得到最大和最小像素值及其位置。
具体代码如下:pythonmin_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)其中,result为模板匹配输出的图像,min_val和max_val分别为最小和最大的像素值,min_loc和max_loc分别为最小和最大像素值所对应的位置信息。
通过使用cv2.minMaxLoc()函数,我们可以实现对模板匹配结果的简单分析。