模板匹配算法实现
- 格式:doc
- 大小:30.50 KB
- 文档页数: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;}}}运⾏效果正常光照光照⾮常暗改进:不需要全局匹配,可以对⽬标图像先做⼀个⼩梯度阈值,然后再进⾏匹配,提升速度、构造⽬标图像⾦字塔,实现多分辨率模板匹配⽀持!。
基于深度学习的模板匹配算法研究深度学习技术近年来在计算机视觉领域取得了巨大的进展,而模板匹配算法作为一种常见的图像识别和目标检测方法,在这一进展中也得到了广泛的应用和研究。
本文将主要介绍基于深度学习的模板匹配算法的研究进展和应用。
一、引言随着计算机性能和存储能力的不断提升,以及大规模数据集的建立,深度学习技术为模板匹配算法的发展提供了有力的支持。
模板匹配算法作为一种基于模板和待匹配图像之间相似性度量的方法,在目标检测、目标追踪等领域有着广泛的应用。
二、传统模板匹配算法的局限性传统的模板匹配算法通常基于特征提取和相似性度量来实现,然而在面对复杂的场景、光照变化和视角变化等问题时,传统算法的性能会受到限制。
而深度学习技术的出现为解决这些问题提供了可能。
三、基于深度学习的模板匹配算法方法1. 卷积神经网络(CNN)卷积神经网络是深度学习中最常用的一种模型,其通过多层卷积和池化操作实现了对图像特征的提取。
在模板匹配算法中,可以将输入图像与预训练好的CNN模型进行特征提取,然后使用相似性度量方法进行匹配。
2. 循环神经网络(RNN)循环神经网络通过网络中的循环连接来实现对序列数据的建模,因此在处理时域信息较重要的任务中具有优势。
在模板匹配算法中,可以使用循环神经网络来对图像序列或视频序列进行特征提取,然后进行匹配。
3. 生成对抗网络(GAN)生成对抗网络是深度学习中的一种模型,其通过生成器和判别器的对抗训练来生成具有逼真度的样本。
在模板匹配算法中,可以使用生成对抗网络生成与待匹配图像相似度高的样本,然后通过相似性度量进行匹配。
四、基于深度学习的模板匹配算法应用1. 目标检测基于深度学习的模板匹配算法在目标检测任务中具有较高的准确度和鲁棒性。
通过使用卷积神经网络提取图像特征,并使用分类器对特征进行判别,可以实现对目标的准确检测。
2. 目标追踪基于深度学习的模板匹配算法在目标追踪任务中能够有效地处理目标的形变、光照变化等问题。
模板匹配的原理一、模板匹配的概念和应用模板匹配是一种常见的图像处理技术,它可以在一幅图像中寻找与给定模板相似的区域。
模板匹配在很多领域都有广泛的应用,比如物体识别、人脸识别、指纹识别等。
二、模板匹配的原理1. 像素级比较模板匹配最基本的原理就是对两个图像进行像素级比较。
首先将模板图像和待匹配图像分别转化为灰度图像,然后将它们按照一定的步长进行滑动,每次计算两个图像之间的差异,并记录下最小误差值。
2. 相关系数法相关系数法是一种常见的模板匹配算法。
它通过计算两个图像之间的相关系数来判断它们之间的相似度。
具体来说,相关系数越大,则两个图像之间越相似;反之,则差异越大。
3. 归一化互相关法归一化互相关法也是一种常见的模板匹配算法。
它通过计算两个图像之间的归一化互相关函数来判断它们之间的相似度。
具体来说,归一化互相关函数越大,则两个图像之间越相似;反之,则差异越大。
三、模板匹配的实现步骤1. 加载图像和模板首先需要加载待匹配的图像和模板图像,并将它们转化为灰度图像。
2. 定义匹配算法根据需要选择合适的匹配算法,比如相关系数法或归一化互相关法。
3. 设置滑动窗口根据需要设置滑动窗口的大小和步长,以便在待匹配图像中搜索与模板相似的区域。
4. 计算误差值对于每个滑动窗口位置,计算它与模板之间的误差值,并记录下最小误差值和对应的位置坐标。
5. 绘制匹配结果将最小误差值和对应位置坐标绘制在待匹配图像上,以便观察匹配结果。
四、模板匹配的优缺点1. 优点:(1) 简单易懂:模板匹配原理简单易懂,容易实现;(2) 实时性好:模板匹配可以实时处理大量数据;(3) 适用范围广:模板匹配可以应用于很多领域,比如物体识别、人脸识别等。
2. 缺点:(1) 效果受限:模板匹配的效果受到模板图像的质量和待匹配图像的复杂度影响;(2) 复杂度高:对于大规模数据或者复杂场景,模板匹配的计算复杂度会很高;(3) 鲁棒性差:对于光照变化、噪声等干扰因素,模板匹配的鲁棒性较差。
1.4利⽤Opencv进⾏模板匹配(templatematching)-在图⽚中查找图⽚原理:利⽤相关匹配的算法(cv2.TM_COEFF_NORMED), 简单讲就是⽤此算法把模板计算出来,再计算出图⽚的值,从图⽚中查找出最相近的位置。
import cv2import numpy as npimport imutilsdef template_matching(image_full_path, tmpl_full_path, min_confidence=0.93, ):""":param image_full_path: 输⼊图⽚路径,在该图⽚中查找模板图像:param tmpl_full_path: 模板图⽚,在输⼊图⽚中查找此模板:param min_confidence: 最⼩信⼼度,该⽅法返回⼤于此信⼼度的结果:return: 返回result_dic ==> {信⼼度:(坐标Tuple)}, sorted(confidence_list,reverse=True)==>信⼼度降序排列列表"""img = cv2.imread(image_full_path) # 读取输⼊图⽚gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度图,采⽤CV_BGR2GRAY,转换公式Gray = 0.1140*B + 0.5870*G + 0.2989*R# template = cv2.imread(tmpl_full_path, cv2.IMREAD_GRAYSCALE) # 读取模板图⽚的灰度图template = cv2.imread(tmpl_full_path) # 为保证输⼊图⽚与模板⼀致性,两张图⽚⽤相同⽅法读取灰度图⽚template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)# w, h = template.shape[::-1] # 获取模板的宽和⾼(绘图时使⽤,本函数内⽆意义)res = cv2.matchTemplate(gray_img, template, cv2.TM_CCOEFF_NORMED) # TM_CCOEFF_NORMED 标准相关匹配loc = np.where(res >= min_confidence) # 在结果中筛选⼤于最⼩信⼼度的结果result_dic = {}confidence_list = []for pt in zip(*loc[::-1]):result_dic[res[pt[1]][pt[0]]] = ptconfidence_list.append(res[pt[1]][pt[0]])# cv2.rectangle(img, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 3) # 在⽬标位置绘制⼀个红⾊矩形框,边宽3pxreturn result_dic, sorted(confidence_list, reverse=True)def diff_size_template_matching(image_full_path, tmpl_full_path, min_confidence=0.95, ):""":param image_full_path: 输⼊图⽚路径,在该图⽚中查找模板图像:param tmpl_full_path: 模板图⽚,在输⼊图⽚中查找此模板:param min_confidence: 最⼩信⼼度,该⽅法返回⼤于此信⼼度的结果:return: 返回result_dic ==> {信⼼度:(坐标Tuple)}, sorted(confidence_list,reverse=True)==>信⼼度降序排列列表"""template = cv2.imread(tmpl_full_path)template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY) # 获得灰度模板image = cv2.imread(image_full_path)gray_img = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 获得灰度图⽚result_dic = {}confidence_list = []for scale in np.linspace(0.2, 1.0, 100)[::-1]: # 1倍到0.2倍分100级变化(级数越⾼,可能获得的匹配精度越⾼,处理越慢)resized = imutils.resize(template, width=int(template.shape[1] * scale)) # 以scale 为倍数改变模板⼤⼩# (w, h) = resized.shape[::-1] # 求改变后的模板宽⾼result = cv2.matchTemplate(gray_img, resized, cv2.TM_CCOEFF_NORMED) # 每次改变都进⾏⼀次匹配loc = np.where(result >= min_confidence) # 在结果中筛选⼤于最⼩信⼼度的结果for pt in zip(*loc[::-1]):result_dic[result[pt[1]][pt[0]]] = ptconfidence_list.append(result[pt[1]][pt[0]])# cv2.rectangle(image, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 3)return result_dic, sorted(confidence_list, reverse=True)if__name__ == '__main__':pass。
亚像素模板匹配算法-回复1. 什么是亚像素模板匹配算法?亚像素模板匹配算法是一种用于图像处理和计算机视觉领域的算法,用于定位和识别图像中的目标物体。
它基于模板匹配的原理,通过对图像进行多次迭代,以亚像素级别的精度来确定目标物体的位置和姿态。
在图像匹配中,常用的方法是使用离散像素级别的匹配来确定目标物体的位置。
但是,由于图像像素的有限分辨率限制,这种方法可能无法达到所需的精度水平。
亚像素模板匹配算法在此基础上进行了改进,通过对目标物体进行子像素级的平移和旋转变换,提高了匹配的精度。
2. 亚像素模板匹配算法的原理是什么?亚像素模板匹配算法的原理是通过计算图像中目标物体的灰度值差异,寻找最佳匹配位置。
具体而言,算法将参考图像中的模板与待测图像进行比较,计算它们之间的相似度。
算法首先在整数像素级别通过平移和旋转对待测图像进行对齐,然后将待测图像与参考图像进行比较。
通过计算两个图像之间每个像素的灰度值差异,可以确定图像的匹配程度。
这个差异值通常称为相关性度量,通过最大化相关性度量,可以找到最佳匹配位置。
为了提高匹配的精度,亚像素模板匹配算法引入了插值的概念。
在整数像素级别的对齐后,算法在像素之间进行插值,计算出亚像素级别的差异值。
通过对亚像素级别进行迭代计算,可以得到更为精确的目标物体位置。
3. 亚像素模板匹配算法的步骤是什么?亚像素模板匹配算法的步骤如下:1. 准备参考图像和待测图像,确保它们包含目标物体的完整信息。
2. 选择目标物体的模板,并在参考图像中确定一个初始的猜测位置。
3. 根据猜测位置,将待测图像进行平移和旋转变换,以使其与参考图像对齐。
4. 在整数像素级别对齐后,使用插值方法计算出亚像素级别的差异值。
5. 计算目标物体在当前猜测位置的相关性度量,作为匹配程度的指标。
6. 根据相关性度量选择下一个猜测位置,并重复步骤3至步骤5,直到找到最佳匹配位置。
7. 根据匹配位置的精度要求,可以进行多次迭代,进一步提高匹配的精度。
基于模板匹配的目标跟踪算法研究1. 引言目标跟踪是计算机视觉领域的一个重要研究方向,它的主要任务是根据先前的观测结果,预测和追踪目标在接下来的时间内的位置、速度和方向等运动状态。
在很多应用中,如视频监控、无人机飞行、汽车驾驶辅助等领域,目标跟踪都扮演着至关重要的角色。
本文主要围绕基于模板匹配的目标跟踪算法展开研究,介绍模板匹配的基本原理和常见算法,分析现有算法的优缺点,并探讨未来的研究方向。
2. 模板匹配原理模板匹配是一种基于相似性度量的图像配准方法,它的基本思想是将已知目标模板与待跟踪的图像进行比对,找到最相似的位置,从而完成目标的定位和跟踪。
模板匹配方法通常包括以下步骤:(1)目标模板的构建:选择一张清晰、具有代表性的目标图像,根据需要对目标进行裁剪或预处理,得到目标模板。
(2)相似性度量:根据不同的相似性度量标准,计算目标模板与图像像素之间的相似度。
通常采用欧式距离、相关系数、相似性度量等方法。
(3)匹配策略:根据相似性度量值,选择最合适的匹配策略,如最小二乘法、局部分割法、马尔可夫随机场等方法。
(4)目标定位:根据匹配到的位置,完成目标的定位和跟踪。
3. 常见的模板匹配算法目前,关于模板匹配的研究方向主要分为两类:第一种是基于灰度信息的传统方法,第二种是基于深度学习的现代方法。
3.1 基于灰度信息的传统方法(1)均值漂移法(Mean Shift Algorithm)均值漂移法是一种典型的平滑直方图的无参数密度估计算法,它主要是通过将概率密度函数进行平滑化,寻找最大值对应的峰值位置作为目标区域的中心点。
优点是对目标尺寸、形状、颜色等参数不敏感,缺点是需要大量的计算量。
(2)相关滤波法(Correlation Filter)相关滤波法是一种基于相关性的滤波器,其主要思想是将目标模板和图像进行自适应的滤波处理,得到相应的响应图,然后通过最大响应值所对应的位置实现目标跟踪。
相较于均值漂移法,相关滤波法具有更高的计算效率和更好的跟踪精度。
mediapipe facemesh 模板匹配原理
Mediapipe Facemesh是一个面部关键点检测技术,使用了模板匹配原理。
模板匹配原理是通过将一个已知的模板图像和输入图像进行比较,来寻找相似的模式或特征。
Facemesh使用模板匹配来检测人脸中的关键点,如眼睛、眉毛、嘴巴等。
具体原理如下:
1. 获取模板图像:首先,Facemesh使用大量的人脸数据集,其中包括了人脸的关键点信息。
这些关键点信息被提取出来,形成一个模板图像,包含了人脸的关键点位置。
2. 特征提取:接下来,Facemesh使用计算机视觉算法来提取输入图像中的特征信息。
这些特征信息可能包括边缘、颜色、纹理等。
3. 模板匹配:使用模板图像和输入图像的特征信息进行匹配。
Facemesh使用一种称为归一化互相关(Normalized Cross-Correlation)的方法来计算匹配度。
4. 关键点定位:匹配度最高的区域被认为是人脸的关键点所在的位置。
Facemesh根据匹配结果定位人脸的关键点,并返回其坐标。
需要注意的是,模板匹配原理在进行人脸关键点检测时可能存在一些问题。
例如,当人脸出现部分遮挡或旋转时,匹配算法
可能会失败。
为了提高检测的准确性,Mediapipe Facemesh还
结合了其他技术,如深度学习和图像处理,以实现更好的性能。
opencv 模板匹配角度计算OpenCV 提供了cv2.matchTemplate() 函数用于模板匹配,但是它不直接提供计算匹配模板旋转角度的功能。
为了计算旋转角度,你可以使用其他方法或结合一些算法。
一种常用的方法是使用霍夫变换(Hough Transform)来检测线条,然后根据模板匹配的结果和这些线条来推断旋转角度。
这种方法的一个前提是,你的模板图像中存在可以检测到的线条。
下面是一个简单的示例代码,展示了如何使用OpenCV 进行模板匹配,并使用霍夫变换来检测线条,从而推断旋转角度:python复制代码:import cv2import numpy as np# 读取图像和模板image = cv2.imread('image.jpg')template = cv2.imread('template.jpg', 0) # 转为灰度图像# 执行模板匹配res = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)threshold = 0.8loc = np.where(res >= threshold)# 在匹配的位置周围提取矩形区域for pt in zip(*loc[::-1]):cv2.rectangle(image, pt, (pt[0] + template.shape[1], pt[1] + template.shape[0]), (0, 0, 255), 2)# 使用霍夫变换检测线条edges = cv2.Canny(image, 50, 150, apertureSize=3)lines = cv2.HoughLines(edges, 1, np.pi/180, 100)# 计算角度并显示for rho, theta in lines[0]:a = np.cos(theta) * rhob = np.sin(theta) * rhox0 = ay0 = bx1 = int(x0 + 1000*(-b))y1 = int(y0 + 1000*(a))x2 = int(x0 - 1000*(-b))y2 = int(y0 - 1000*(a))cv2.line(image, (x1, y1), (x2, y2), (0, 0, 255), 2)angle_radians = np.arctan2(y2 - y1, x2 - x1)angle_degrees = angle_radians * (180 / np.pi) # 将弧度转换为角度print(f"Angle: {angle_degrees:.2f} degrees")cv2.imshow('image', image)cv2.waitKey(0)cv2.destroyAllWindows()这个示例代码首先执行模板匹配,然后在匹配的位置周围绘制矩形框。
opencv模板匹配原理,亚像素精度OpenCV模板匹配原理和亚像素精度引言:计算机视觉在现代科学和技术领域中起着至关重要的作用,其中模板匹配是一种常用的图像处理技术。
OpenCV(Open Source Computer Vision)是一个开源的计算机视觉库,提供了许多图像处理函数和算法。
在本文中,我们将探讨OpenCV模板匹配的原理以及其中的一个重要概念——亚像素精度。
第一部分:模板匹配原理1.1概述模板匹配是一种基于像素值的局部特征匹配方法,用于在大图像中寻找与给定模板最相似的子图像。
它在图像处理、目标检测、目标跟踪等领域具有广泛的应用。
1.2基本流程模板匹配的基本流程可以分为以下几个步骤:-选择一张待搜索的大图像作为目标图像。
-选择一个相对较小的模板图像作为待匹配的对象。
-找到目标图像中与模板最相似的部分。
-输出匹配结果,通常是标记或者提取匹配区域。
1.3常用的匹配度量方法在模板匹配中,常用的匹配度量方法有以下几种:-平方差匹配(Sum of Squared Differences,SSD):计算模板图像与目标图像的每个像素之间的差值的平方和。
-相关系数匹配(Normalized Cross-Correlation,NCC):计算模板与目标图像的亮度差异度量。
-归一化相互匹配(Normalized Mutual Information,NMI):通过信息熵分析来衡量两幅图像之间的相似性。
1.4OpenCV中的模板匹配函数OpenCV提供了cv::matchTemplate函数来实现模板匹配。
该函数接受目标图像和模板图像作为输入,并返回匹配结果的矩阵。
第二部分:亚像素精度2.1问题引入在模板匹配中,常见的像素级匹配只能提供粗略的匹配结果,无法满足一些需要更高精度的应用。
为了克服这一问题,亚像素精度被引入模板匹配中。
2.2亚像素精度原理亚像素精度通过在像素之间进行插值计算,提高匹配的精度。
opencv中缩放旋转模板匹配原理-回复opencv中缩放旋转模板匹配是一种基于图像处理的算法,主要用于在一幅图像中寻找与给定模板最相似的区域。
这个算法被广泛地应用于计算机视觉领域,例如人脸识别、目标检测等。
首先,我们来介绍一下缩放旋转模板匹配的基本原理。
在这个算法中,我们假设模板在图像中的位置是未知的,但是我们已经拥有了模板的形状和大小信息。
算法的目标是找到一个位置和大小与模板最匹配的图像区域。
首先,我们需要对模板进行预处理。
这包括将模板转换为灰度图像,以及对其进行归一化,以消除尺度和亮度变化的影响。
接下来,我们需要对模板进行旋转和缩放,以使其能够适应不同的图像场景。
这一步可以通过使用旋转矩阵和缩放系数来实现。
一旦我们完成了模板的预处理,我们就可以开始在图像中寻找匹配的区域。
在opencv中,有几种方法可以实现这个目标。
其中最常用的方法是使用模板匹配函数`matchTemplate()`。
这个函数可以计算图像中每个可能位置的与模板的相似度,从而找到最匹配的位置。
`matchTemplate()`函数的原理是通过对图像和模板进行卷积,计算它们之间的相似度。
卷积的计算过程可以通过使用离散傅里叶变换(DFT)来加速。
具体而言,算法计算了每个图像窗口与模板之间的差异,并将其存储在一个相似度矩阵中。
最后,我们可以根据相似度矩阵找到最匹配的位置。
在opencv中,`matchTemplate()`函数提供了几种匹配方法,包括平方差匹配、相关匹配和归一化平方差匹配等。
这些方法根据计算图像窗口与模板之间的差异的方式有所不同。
例如,平方差匹配计算了图像窗口与模板之间的均方误差,相关匹配计算了它们之间的相关系数。
一旦我们得到了相似度矩阵,我们就可以根据阈值将相似度高于某个阈值的位置作为匹配结果。
通常,我们可以根据实际需求选择合适的阈值。
此外,我们还可以对匹配结果进行进一步的后处理,例如使用非极大值抑制来排除重复的匹配结果。
模板匹配算法实现
在机器视觉识别的过程中,常常需要把不同的待测图像和标准图像进行比较,一种最常用的图像识别技术就
是模板匹配.下面是具体实现的过程:
/*************************************************************************
*
* 函数名称:
* TemplateMatchDIB()
*
* 参数:
* LPSTR lpDIBBits - 指向源DIB图像指针
* LPSTR lpDIBBitsBK - 指向背景DIB图像指针
* LONG lWidth - 源图像宽度(象素数)
* LONG lHeight - 源图像高度(象素数)
* LONG lTemplateWidth - 模板图像宽度(象素数)
* LONG lTemplateHeight - 模板图像高度(象素数)
*
* 返回值:
* BOOL - 运算成功返回TRUE,否则返回FALSE。
*
* 说明:
* 该函数用于对图像进行模板匹配运算。
*
* 要求目标图像为255个灰度值的灰度图像。
************************************************************************/
BOOL WINAPI TemplateMatchDIB (LPSTR lpDIBBits, LPSTR lpTemplateDIBBits, LONG lWidth, LONG
lHeight,
LONG lTemplateWidth,LONG l T emplateHeight)
{
// 指向源图像的指针
LPSTR lpSrc,lpTemplateSrc;
// 指向缓存图像的指针
LPSTR lpDst;
// 指向缓存DIB图像的指针
LPSTR lpNewDIBBits;
HLOCAL hNewDIBBits;
//循环变量
long i;
long j;
long m;
long n;
//中间结果
double dSigmaST;
double dSigmaS;
double dSigmaT;
//相似性测度
double R;
//最大相似性测度
double MaxR;
//最大相似性出现位置
long lMaxWidth;
long lMaxHeight;
//像素值
unsigned char pixel;
unsigned char templatepixel;
// 图像每行的字节数
LONG lLineBytes,lTemplateLineBytes;
// 暂时分配内存,以保存新图像
hNewDIBBits = LocalAlloc(LHND, l W idth * lHeight);
if (hNewDIBBits == NULL)
{
// 分配内存失败
return FALSE;
}
// 锁定内存
lpNewDIBBits = (char * )LocalLock(hNewDIBBits);
// 初始化新分配的内存,设定初始值为255
lpDst = (char *)lpNewDIBBits;
memset(lpDst, (BYTE)255, l W idth * lHeight);
// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(l W idth * 8); lTemplateLineBytes = WIDTHBYTES(lTemplateWidth * 8);
//计算dSigmaT
dSigmaT = 0;
for (n = 0;n < lTemplateHeight ;n++)
{
for(m = 0;m < lTemplateWidth ;m++)
{
// 指向模板图像倒数第j行,第i个象素的指针lpTemplateSrc = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m;
templatepixel = (unsigned char)*lpTemplateSrc;
dSigmaT += (double)templatepixel*templatepixel;
}
}
//找到图像中最大相似性的出现位置
MaxR = 0.0;
for (j = 0;j < lHeight - lTemplateHeight +1 ;j++)
{
for(i = 0;i < lWidth - lTemplateWidth + 1;i++)
{
dSigmaST = 0;
dSigmaS = 0;
for (n = 0;n < lTemplateHeight ;n++)
{
for(m = 0;m < l T emplateWidth ;m++)
{
// 指向源图像倒数第j+n行,第i+m个象素的指针
lpSrc = (char *)lpDIBBits + lLineBytes * (j+n) + (i+m);
// 指向模板图像倒数第n行,第m个象素的指针lpTemplateSrc = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m;
pixel = (unsigned char)*lpSrc;
templatepixel = (unsigned char)*lpTemplateSrc;
dSigmaS += (double)pixel*pixel;
dSigmaST += (double)pixel*templatepixel;
}
}
//计算相似性
R = dSigmaST / ( sqrt(dSigmaS)*sqrt(dSigmaT));
//与最大相似性比较
if (R > MaxR)
{
MaxR = R;
lMaxWidth = i;
lMaxHeight = j;
}
}
}
//将最大相似性出现区域部分复制到目标图像
for (n = 0;n < lTemplateHeight ;n++)
{
for(m = 0;m < lTemplateWidth ;m++)
{
lpTemplateSrc = (char *)lpTemplateDIBBits + lTemplateLineBytes * n + m; lpDst = (char *)lpNewDIBBits + lLineBytes * (n+lMaxHeight) + (m+lMaxWidth);
*lpDst = *lpTemplateSrc;
}
}
// 复制图像
memcpy(lpDIBBits, lpNewDIBBits, lWidth * lHeight);
// 释放内存
LocalUnlock(hNewDIBBits);
LocalFree(hNewDIBBits);
// 返回
return TRUE;
}。