精华内容
下载资源
问答
  • 模板匹配算法可以支持平移缩放和旋转变化,采用对数极坐标的方法进行模板配准
  • 课程名称 数字图像处理 实验序号 实验 8 实验名称 图像匹配模板匹配 实验地点 综 B207 实验学时 2 实验类型 验证性 2017 年 10 月 16 日 1 一实验目的及要求 在机器识别物体的过程 常需把不同传感器或同一传感器在...
  • import cv2 import numpy as np # 加载原始RGB图像 img_rgb = cv2.imread("capture1.jpg") # 创建一个原始图像的灰度版本,所有操作在灰度版本中处理,然后在RGB图像中使用相同坐标还原 ...#模板2 3 筛选
    import cv2
    import numpy as np
    # 加载原始RGB图像
    img_rgb = cv2.imread("capture1.jpg")
    # 创建一个原始图像的灰度版本,所有操作在灰度版本中处理,然后在RGB图像中使用相同坐标还原
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
    # 加载将要搜索的图像模板
    #模板1 筛选图案1
    template1 = cv2.imread('template1.png', 0)
    #模板2 3 筛选图案2
    template2 = cv2.imread('template2.png', 0)
    template3 = cv2.imread('template3.png', 0)
    # 记录图像模板的尺寸
    w1, h1 = template1.shape[::-1]
    w2, h2 = template2.shape[::-1]
    w3, h3 = template3.shape[::-1]
    

    list[::-1]是将列表反过来,从序列的最后一个元素开始切片
    h1,w1 = template1.shape[::1] ----------- 有啥区别???????????????

    def rotate_bound(image, angle):#图片旋转但不改变大小,模板匹配中大小改变对匹配效果有影响
        (h, w) = image.shape[:2]                                          #取前两位
        (cX, cY) = (w // 2, h // 2)#//是向下取整                       #取中点x,y坐标
        M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
        cos = np.abs(M[0, 0])            #np.abs(x)、np.fabs(x):计算数组各元素的绝对值    
        sin = np.abs(M[0, 1])
        
        nW = int((h * sin) + (w * cos))
        nH = int((h * cos) + (w * sin))
        M[0, 2] += (nW / 2) - cX
        M[1, 2] += (nH / 2) - cY
     
        return cv2.warpAffine(image, M, (nW, nH))
    

    在这里插入图片描述
    但是单纯的这个矩阵是在原点处进行变换的,为了能够在任意位置进行旋转变换,opencv采用了另一种方式:
    在这里插入图片描述
    为了构造这个矩阵,opencv提供了一个函数:cv2.getRotationMatrix2D(),这个函数需要三个参数,旋转中心,旋转角度,旋转后图像的缩放比例,比如下例:
    center表示中间点的位置,-5表示逆时针旋转5度,1表示进行等比列的缩放
    M是2x3的矩阵

    #选出所有匹配旋转模板且不重复的图案
    def make_contour(template,w,h,angle,threshold):
        rects = []
        # 模板旋转匹配
        for i in range(0, 360, angle):
            new_rotate = rotate_bound(template, i)                        #注1
            # 把图片旋转后黑色的部分填充成白色
            new_rotate[new_rotate == 0] = 255
            # 使用matchTemplate对原始灰度图像和图像模板进行匹配
            res = cv2.matchTemplate(img_gray, new_rotate, cv2.TM_CCOEFF_NORMED)
            # 设定阈值
            loc = np.where(res >= threshold)                              #注2
            #x,y坐标对调打包
            for pt in zip(*loc[::-1]):
                point = np.array([[pt[0], pt[1]], [pt[0] + w, pt[1]],
                        [pt[0], pt[1] + h], [pt[0] + w, pt[1] + h]])
                rects.append(cv2.boundingRect(point))
        #模板匹配后符合要求的所有图案数量
        length = len(rects)
        #设定阈值
        threshold = 3
        i = 0
        #如果两个图案距离在阈值范围内,则等同,然后用集合去重
        while(i<length):
            print(i)
            for j in range(length):
                if j != i:
                    if np.abs(rects[j][0]-rects[i][0])<= threshold:
                        if np.abs(rects[j][1]-rects[i][1]) <= threshold:
                            rects[j] = rects[i]
            i = i+1
        return set(rects)
    

    注1:
    def rotate_bound1(image, angle):
    旋转图片
    param image opencv读取后的图像
    param angle (逆)旋转角度
    注2:
    np.where()
    numpy中能够返回符合某一条件的下标函数:np.where(),只不过np.where()并不接受list类型的参数。
    np.where()可用于接收3个参数,用于三目运算;也可用于接收1个参数,直接返回符合要求的下标。

    #在原图把匹配的模板框出来并输出坐标文档
    def draw_contour(contours,color):
        count = 0
        for contour in contours:
            cv2.rectangle(img_rgb, (contour[0], contour[1]), (contour[0] + contour[2], contour[1] + contour[3]),
                                 color, 1)
            cx = contour[0] + (contour[2] // 2)
            cy = contour[1] + (contour[3] // 2)
            count = count + 1
            cv2.putText(img_rgb, str(count), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1,color, 1, 1)                                               #注1
            with open("data.txt", "a+") as f:                    #注2
                f.write("contour" + '\t' + str(count) + '\t' + 'cx: ' + str(cx) + '  \t' + 'cy: ' + str(cy) + '\n')
                # 显示图像
        cv2.imwrite("after.png", img_rgb)
    

    注1:
    cv2.putText(img, str(i), (123,456)), font, 2, (0,255,0), 3)
    各参数依次是:图片,添加的文字,左上角坐标,字体,字体大小,颜色,字体粗细
    注2:
    with…as语句是简化版的try except finally语句
    1.as可以省略 2. 有一个句块要执行
    从文件中读取数据,然后关闭文件句柄
    file = open("/tmp/foo.txt")
    data = file.read()
    file.close()
    这里有两个问题。一是可能忘记关闭文件句柄;二是文件读取数据发生异常,没有进行任何处理。下面是处理异常的加强版本:
    file = open("/tmp/foo.txt")
    try:
    data = file.read()
    finally:
    file.close()
    虽然这段代码运行良好,但是太冗长了。这时候就是with一展身手的时候了。除了有更优雅的语法,with还可以很好的处理上下文环境产生的异常。下面是with版本的代码:
    with open("/tmp/foo.txt") as file:
    data = file.read()
    1.先执行expression,然后执行该表达式返回的对象实例的__enter__函数,然后将该函数的返回值赋给as后面的变量。(注意,是将__enter__函数的返回值赋给变量)
    2.然后执行with block代码块,不论成功,错误,异常,在with block执行结束后,会执行第一步中的实例的__exit__函数

    if __name__=='__main__':
        #a+可读可写覆盖
        with open("data.txt", "a+") as f:
            f.write('contour1'+'\n')
        threshold1 = 0.69
        contours1 = make_contour(template1,w1,h1,90,threshold1)
        color1 = (255, 0, 0)
        draw_contour(contours1,color1)
    
        img_rgb = cv2.imread("after.png")
        img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
        with open("data.txt", "a+") as f:
            f.write('\n'+'contour2'+'\n')
        color2 = (0,0,255)
        threshold2 = 0.53
        #合并轮廓
        contours2 = list(make_contour(template2, w2, h2,30,threshold2))+list(make_contour(template3, w3, h3, 30, threshold2))
        draw_contour(contours2,color2)
    
    展开全文
  • 旋转模板匹配算法,能够匹配带旋转角度的模板。VS 2015+OPENCV C++实现
  • 带微小缩放和旋转模板匹配

    千次阅读 2020-04-03 18:33:49
    OpenCV并不像Halcon一样提供带有旋转和缩放的的模板匹配。本文对带旋转和缩放的模板匹配问题进行限定,只针对的目标缩放范围为95%到105%,旋转角度为-5度到5度的情况,尝试用opencv解决。 问题分析: 带有旋转和缩放...

    问题提出:

    OpenCV并不像Halcon一样提供带有旋转和缩放的的模板匹配。本文对带旋转和缩放的模板匹配问题进行限定,只针对的目标缩放范围为95%到105%,旋转角度为-5度到5度的情况,尝试用opencv解决。

    问题分析:

    带有旋转和缩放,首先想到使用外轮廓进行Hu矩匹配,然后根据外轮廓周长比例和面积开方的比例确定缩放系数,根据轮廓最小包围旋转矩形的角度差确定旋转角度。这个思路要求目标外轮廓不能对称,比如圆,正方形,长方形这些,同时最小包围矩形也不能是长宽比较接近的长方形甚至正方形,否则无法确定旋转角度(或者多个可能角度一一使用灰度匹配去判断)。但是本文有个限制条件,缩放比例和旋转角度较小。所以另一个思路是搜索的方法,只要找到一个好的的搜索策略,那么算法的时间也是可以接受的。

    实现效果

    如下图所示,左边是模板,右边是待匹配的目标,有4度的旋转。
    在这里插入图片描述
    左边是带旋转和污损的目标,右边是匹配结果(叠加模板后找到污损区域)。
    在这里插入图片描述

    思路一:Hu矩

    使用Hu矩由于限制较多,不能对实现效果中的图进行处理,因此使用如下模板

    要从如下图中找出

    代码实现:

    Mat searchImage = imread("pic/contour/Search2.jpg");
    Mat searchImageResult = searchImage.clone();
    Mat graySearchImg;
    cvtColor(searchImage, graySearchImg, COLOR_RGB2GRAY);
    Mat templateImage = imread("pic/contour/Template2.jpg");
    Mat grayTemplateImg;
    cvtColor(templateImage, grayTemplateImg, COLOR_RGB2GRAY);
    
    //在Template2和Search2中找外轮廓
    Mat bin_search;
    threshold(graySearchImg, bin_search, 128, 255, THRESH_BINARY);
    vector<vector<Point>> contours_search;
    vector<Vec4i> hierarchy_search;
    findContours(bin_search, contours_search, hierarchy_search, RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0));
    
    Mat bin_template;
    threshold(grayTemplateImg, bin_template, 128, 255, THRESH_BINARY);
    vector<vector<Point>> contours_template;
    vector<Vec4i> hierarchy_template;
    findContours(bin_template, contours_template, hierarchy_template, RETR_TREE, CHAIN_APPROX_NONE, Point(0, 0));
    
    drawContours(searchImage, contours_search, -1, Scalar(255, 0, 0));
    drawContours(templateImage, contours_template, -1, Scalar(255, 0, 0));
    
    //对待检图中的每个轮廓进行判断,可以事先筛选再判断
    for (int i = 0; i < contours_search.size(); i++)
    {
    	double score = matchShapes(contours_template[0], contours_search[i], CONTOURS_MATCH_I3,0);
    	cout << "score" << score << endl;
    	if (score < 0.1)  //认为匹配成功
    	{
    		//计算重心偏移,缩放和旋转
    		double area_template = contourArea(contours_template[0]);
    		double area_search = contourArea(contours_search[i]);
    		float scale = sqrt(area_search/ area_template);
    		cout << "scale:" << scale << endl;
    
    		//由于先验目标最小包围矩形是长方形
    		//因此最小包围矩形的中心和重心的向量夹角为旋转
    		RotatedRect rect_template = minAreaRect(contours_template[0]);
    		RotatedRect rect_search = minAreaRect(contours_search[i]);
    		//两个旋转矩阵是否同向
    		int sign = (rect_template.size.width - rect_template.size.height) *
    			(rect_search.size.width - rect_search.size.height);
    		float angle;
    		if (sign > 0) //可以直接相减
    			angle = rect_search.angle - rect_template.angle;
    		else
    			angle = (90 + rect_search.angle) - rect_template.angle;
    		cout << "angle:" << angle << endl;
    
    		//对contours_template基于重心进行旋转和缩放,
    		//然后偏移contours_search[i],绘制到待检图中
    		Moments mom_template = moments(contours_template[0]);
    		Moments mom_search = moments(contours_search[i]);
    		Point gravity_template = Point(mom_template.m10 / mom_template.m00, mom_template.m01 / mom_template.m00);
    		Point gravity_search = Point(mom_search.m10 / mom_search.m00, mom_search.m01 / mom_search.m00);
    
    		//对模板轮廓进行平移,旋转和缩放
    		for (int j = 0; j < contours_template[0].size(); j++)
    		{
    			//重心平移到原点
    			int x = contours_template[0][j].x;
    			int y = contours_template[0][j].y;
    			x -= gravity_template.x;
    			y -= gravity_template.y;
    			//缩放
    			x *= scale;
    			y *= scale;
    			//旋转
    			float rad = angle / 180.0*3.1416;
    			contours_template[0][j].x = x*cos(rad) - y * sin(rad);
    			contours_template[0][j].y = x*sin(rad) + y * cos(rad);
    		}
    
    		//画带有偏移的从模板经过缩放和旋转生成的轮廓
    		drawContours(searchImageResult, contours_template, -1, Scalar(0, 255, 0),4,8,noArray(),LONG_MAX, gravity_search);
    	}
    }
    
    imshow("templateImage", templateImage);
    imshow("searchImage", searchImage);
    imshow("searchImageResult", searchImageResult);
    waitKey();
    

    匹配效果

    总结:

    该方法由于要找到反映目标外轮廓的曲线,因此对背景干扰较为敏感。但由于不使用灰度匹配滑动窗口的方法,算法复杂度降低,处理时间减少。

    思路二:搜索

    因为待匹配区域可能会有95%到105%的缩放,-5度到5度的旋转。经过观察(未证明),以缩放和旋转为自变量,匹配结果为函数值的函数在(0,0)附近超任一方向延伸大致上是单调函数,因此,使用梯度下降的思想,从(0,0)开始,每一步都找梯度最大的方向,直到找到最小值。
    如下图所示,在直角坐标系中,x代表旋转,y代表缩放。原点(0,0)代表无缩放和旋转。搜索时从原点开始。假设第一步在原点周围的8个点钟找到的最小值为A点,则从A点开始继续往后找,在数学上的标达是向量方向AB与当前路径方向OA成锐角,可以使用向量的点乘实现。找到B,B’,B’’中最小的点,如果小于A点,则从B点开始继续往后找,如果大于A点,则A点是最优匹配。以此类推。
    在这里插入图片描述
    使用以上策略,在最好的情况下需要进行8次匹配,最坏的情况下需要进行20(=8+4*3)次匹配。

    代码实现:

    vector<Point> path = { Point(0,0) }; //梯度下降路径
    Point current(0, 0); //x代表旋转,y代表缩放
    double currentmin = LLONG_MAX;
    while (1) //直到找到最小
    {
    	int minrindex = 0, minzindex = 0;
    	double minresult = LLONG_MAX;
    	for (int r = -1; r <= 1; r++)  //旋转rotate
    	{
    		for (int z = -1; z <= 1; z++)  //缩放zoom
    		{
    			if (path.size() > 1)  //第二次才对是否需要计算进行判断
    			{
    				Point v = path[path.size() - 1] - path[path.size() - 2];
    				//向量点乘小于0,代表是钝角,不是梯度方向的延伸,不进行计算
    				if (v.x * r + v.y*z < 0)  
    					continue;
    			}
    			//对subtemplates[j]进行缩放和旋转变换
    			Mat subtemplatesj = trans(subTemplates[j], current.x + r, current.y + z);
    			Mat result;
    			matchTemplate(subsearch, subtemplatesj, result, TM_SQDIFF); //匹配
    
    			//找到位置,做差
    			double minVal = -1;
    			double maxVal;
    			Point minLoc;
    			Point maxLoc;
    			Point matchLoc;
    			minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc, Mat());
    			//cout << "匹配度:" << minVal << endl;
    			if (minVal < minresult)
    			{
    				minresult = minVal;
    				minrindex = r;
    				minzindex = z;
    			}
    		}
    	}
    	if (minresult < currentmin) //如果当前计算结果小于前一次,则进行更新
    	{
    		current.x += minrindex;
    		current.y += minzindex;
    		path.push_back(current);
    		currentmin = minresult;
    	}
    	else
    	{
    		break;
    	}
    }
    
    
    展开全文
  • 解压到可以用C#直接调用,输入相关参数即可,功能是先画一条要找的边,自动会生成一条线,根据线与轴线自动旋转角度,并且可以创建模板和读取模板,并且匹配模板,有需要的赶紧下载吧!
  • OpenCV Error: Assertion failed (scn == 3 || scn == 4) in cv::cvtColor, file C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp, line 11111 ...模板匹配 import cv2 impor...
    OpenCV Error: Assertion failed (scn == 3 || scn == 4)
     in cv::cvtColor, file C:\projects\opencv-python\opencv\modules\imgproc\src\color.cpp, line 11111
    

    1 加载路径有错误
    2 参数0是灰度,再灰度化出错

    模板匹配
    import cv2
    import numpy as np
    
    #加载原始RGB图像
    img_rgb = cv2.imread("C:/Users/AEC/Desktop/1.png")
    #创建一个原始图像的灰度版本,所有操作在灰度版本中处理,然后在RGB图像中使用相同坐标还原
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
    
    #加载将要搜索的图像模板
    template = cv2.imread('C:/Users/AEC/Desktop/2.png',0)
    #记录图像模板的尺寸
    w, h = template.shape[::-1]
    
    """
    #查看三组图像(图像标签名称,文件名称)
    cv2.namedWindow("rgb")
    cv2.imshow('rgb',img_rgb)
    cv2.namedWindow("gray")
    cv2.imshow('gray',img_gray)
    cv2.namedWindow("template")
    cv2.imshow('template',template)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    """
    #使用matchTemplate对原始灰度图像和图像模板进行匹配
    res = cv2.matchTemplate(img_gray,template,cv2.TM_CCOEFF_NORMED)
    #设定阈值
    threshold = 0.7
    #res大于70%
    loc = np.where( res >= threshold)
    
    #使用灰度图像中的坐标对原始RGB图像进行标记
    for pt in zip(*loc[::-1]):
        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2)
    #显示图像
    cv2.namedWindow("Detected",0)
    cv2.imshow('Detected',img_rgb)
    cv2.imwrite("1_after.png",img_rgb)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    

    模板
    在这里插入图片描述

    原图原图
    原图

    在这里插入图片描述
    效果图

    问题1 如果图像旋转了就匹配不到,试着解决这个问题 解决方案:
    旋转模板匹配图案
    问题2 可以看到对同一个图有多个框标定,需要去重,只需要保留一个
    解决方案:对框边界值设置阈值,阈值范围内就当成一个框
    问题3 可能有漏检过检情况
    通过调节阈值解决

    经过差不多大半天的努力解决了以上一些问题
    下面这个程序实现对两个图案的匹配

    import cv2
    import numpy as np
    
    # 加载原始RGB图像
    img_rgb = cv2.imread("origin.png")
    # 创建一个原始图像的灰度版本,所有操作在灰度版本中处理,然后在RGB图像中使用相同坐标还原
    img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
    # 加载将要搜索的图像模板
    #模板1 筛选图案1
    template1 = cv2.imread('template1.png', 0)
    #模板2 3 筛选图案2
    template2 = cv2.imread('template2.png', 0)
    template3 = cv2.imread('template3.png', 0)
    # 记录图像模板的尺寸
    w1, h1 = template1.shape[::-1]
    w2, h2 = template2.shape[::-1]
    w3, h3 = template3.shape[::-1]
    
    def rotate_bound(image, angle):#图片旋转但不改变大小,模板匹配中大小改变对匹配效果有影响
        (h, w) = image.shape[:2]
        (cX, cY) = (w // 2, h // 2)#//是向下取整
        M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0)
        cos = np.abs(M[0, 0])
        sin = np.abs(M[0, 1])
        nW = int((h * sin) + (w * cos))
        nH = int((h * cos) + (w * sin))
        M[0, 2] += (nW / 2) - cX
        M[1, 2] += (nH / 2) - cY
        return cv2.warpAffine(image, M, (nW, nH))
    
    #选出所有匹配旋转模板且不重复的图案
    def make_contour(template,w,h,angle,threshold):
        rects = []
        # 模板旋转匹配
        for i in range(0, 360, angle):
            new_rotate = rotate_bound(template, i)
            # 把图片旋转后黑色的部分填充成白色
            new_rotate[new_rotate == 0] = 255
            # 使用matchTemplate对原始灰度图像和图像模板进行匹配
            res = cv2.matchTemplate(img_gray, new_rotate, cv2.TM_CCOEFF_NORMED)
            # 设定阈值
            loc = np.where(res >= threshold)
            #x,y坐标对调打包
            for pt in zip(*loc[::-1]):
                point = np.array([[pt[0], pt[1]], [pt[0] + w, pt[1]],
                        [pt[0], pt[1] + h], [pt[0] + w, pt[1] + h]])
                rects.append(cv2.boundingRect(point))
        #模板匹配后符合要求的所有图案数量
        length = len(rects)
        #设定阈值
        threshold = 3
        i = 0
        #如果两个图案距离在阈值范围内,则等同,然后用集合去重
        while(i<length):
            print(i)
            for j in range(length):
                if j != i:
                    if np.abs(rects[j][0]-rects[i][0])<= threshold:
                        if np.abs(rects[j][1]-rects[i][1]) <= threshold:
                            rects[j] = rects[i]
            i = i+1
        return set(rects)
    
    #在原图把匹配的模板框出来并输出坐标文档
    def draw_contour(contours,color):
        count = 0
        for contour in contours:
            cv2.rectangle(img_rgb, (contour[0], contour[1]), (contour[0] + contour[2], contour[1] + contour[3]),
                                 color, 1)
            cx = contour[0] + (contour[2] // 2)
            cy = contour[1] + (contour[3] // 2)
            count = count + 1
            cv2.putText(img_rgb, str(count), (cx, cy), cv2.FONT_HERSHEY_SIMPLEX, 1,color, 1, 1)
            with open("data.txt", "a+") as f:
                f.write("contour" + '\t' + str(count) + '\t' + 'cx: ' + str(cx) + '  \t' + 'cy: ' + str(cy) + '\n')
                # 显示图像
        cv2.imwrite("after.png", img_rgb)
    
    if __name__=='__main__':
        #a+可读可写覆盖
        with open("data.txt", "a+") as f:
            f.write('contour1'+'\n')
        threshold1 = 0.69
        contours1 = make_contour(template1,w1,h1,90,threshold1)
        color1 = (255, 0, 0)
        draw_contour(contours1,color1)
    
        img_rgb = cv2.imread("after.png")
        img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
        with open("data.txt", "a+") as f:
            f.write('\n'+'contour2'+'\n')
        color2 = (0,0,255)
        threshold2 = 0.53
        #合并轮廓
        contours2 = list(make_contour(template2, w2, h2,30,threshold2))+list(make_contour(template3, w3, h3, 30, threshold2))
        draw_contour(contours2,color2)
    

    匹配效果很好,阈值调节需要谨慎,0.01的差距可能会造成一个漏检
    在这里插入图片描述
    输出每个框的位置坐标
    在这里插入图片描述

    展开全文
  • 基于OpenCv实现了模板图像的旋转匹配,此代码基于matchTemplate函数封装实现可以得知旋转角度的模板匹配(vs2013+opencv2.4.9) 2.带旋转模板匹配的原理及算法实现(c++) 带旋转模板匹配算法,能够匹配带旋转...
  • 模板匹配

    2019-11-21 22:01:33
    首先介绍一下模板匹配的适用场景: 1、图像检索 2、目标跟踪 简单的说,模板匹配最...模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。 #inc...

    首先介绍一下模板匹配的适用场景:
    1、图像检索
    2、目标跟踪
    简单的说,模板匹配最主要的功能就是在一幅图像中去寻找和另一幅模板图像中相似度最高的部分,这就是模板匹配。

    它是研究某一特定对象物的图案位于图像的什么地方,进而识别对象物。是图像处理中最基本、最常用的匹配方法。模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。

     

    #include <iostream>
    #include <opencv2/core.hpp>
    #include <opencv2/highgui.hpp>
    #include <opencv2/imgproc.hpp>
    using namespace std;
    using namespace cv;
    
    void main()
    {
    //步骤一:读取图片
        cv::Mat img1 = cv::imread("C:\\Users\\Administrator\\Desktop\\temp.png");
        cv::Mat img2 = cv::imread("C:\\Users\\Administrator\\Desktop\\temp1.png");
        cv::imshow("【被查找的图像】", img1);
        cv::imshow("【模版图像】", img2);
    
    //步骤二:创建一个空画布用来绘制匹配结果
        cv::Mat dstImg;
        dstImg.create(img1.dims,img1.size,img1.type());
        cv::imshow("createImg",dstImg);
    
    //步骤三:匹配,最后一个参数为匹配方式,共有6种,详细请查阅函数介绍
        cv::matchTemplate(img1, img2, dstImg, 0);
    
    //步骤四:归一化图像矩阵,可省略
        cv::normalize(dstImg, dstImg, 0, 1, 32);
    
    //步骤五:获取最大或最小匹配系数
    //首先是从得到的 输出矩阵中得到 最大或最小值(平方差匹配方式是越小越好,所以在这种方式下,找到最小位置)
    //找矩阵的最小位置的函数是 minMaxLoc函数
        cv::Point minPoint;
        cv::Point maxPoint;
        double *minVal = 0;
        double *maxVal = 0;
        cv::minMaxLoc(dstImg, minVal, maxVal, &minPoint,&maxPoint);
    
    //步骤六:开始正式绘制
        cv::rectangle(img1, minPoint, cv::Point(minPoint.x + img2.cols, minPoint.y + img2.rows), cv::Scalar(0,255,0), 2, 8);
        cv::imshow("【匹配后的图像】", img1);
        cv::rectangle(dstImg, minPoint, cv::Point(minPoint.x + img2.cols, minPoint.y + img2.rows), cv::Scalar(0,0,0), 3, 8);
        cv::imshow("【匹配后的计算过程图像】", dstImg);
        cv::waitKey(0);
    

    参考

    https://blog.csdn.net/lz0499/article/details/69364871

    https://blog.csdn.net/KYJL888/article/details/81480670

    展开全文
  • 理论部分模板匹配的算法包括基于灰度的匹配,基于特征的匹配,基于组件的匹配,基于相关性的匹配以及局部变形匹配。基于灰度的匹配一般应用在没有缩放和旋转,颜色变化不大的场合。基于特征的匹配一般应用在具有...
  • matlab开发-使用与旋转匹配模板查找目标图像。使用与旋转匹配模板在图像中查找对象
  • 模板匹配最适用于工业场合(在一张...模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。简单来说,模板匹配就是在整个图像区域发现与给定子图像匹配...
  • 选择模板 旋转180度进行识别 继续旋转 ,依然可以识别 代码: * Searching the best matching of a template in an image (with rotation). * dev_close_window () read_image (For6, 'for6') get_image...
  • 1/模板匹配方法 /// <summary> /// 多角度模板匹配方法 /// </summary> /// <param name="srcImage">待匹配图像</param> /// <param name="modelImage">模板图像&l...
  • 模板匹配的原理 模板匹配可以说是一种最简单的模式识别方法,它的实现主要是通过模板图像在被匹配图像中的平移,在被匹配图像中逐个区域寻找和模板图像相似的区域,如果存在某区域的相似度大于一定的阈值,则表明该...
  • opencv之模板匹配

    2020-07-10 14:34:04
    模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。 模板匹配的工作方式? 工作原理:在待检测图像上,从左到右,从上向下计算模板图像与重叠子图像...
  • 模板匹配 ...模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。 普通的模板匹配方法属于暴力搜索法,通过将模板图像不断在搜索图上移动...
  • 多目标模板匹配.rar

    2020-05-22 12:00:31
    使用vs和opencv编写的多目标模板匹配代码,可以再图片中查找多个匹配目标模板的位置。...模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。
  • 对于工业应用来说,往往需要用到形状匹配来达到定位功能,VisionPro的PatMax算法,Halcon的形状匹配算法都是基于边缘的模版匹配。halcon中的形状匹配具有良好的鲁棒性,稳定,...对模板图像进行一系列旋转,缩放,以及
  • 模板匹配算法初识

    万次阅读 2018-08-07 14:38:48
    模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。 算法 相关法 以8位灰度图像为例,模板T(m,n)叠放在被搜索图S(W,H)上平移,模板覆盖被搜索图的...
  • 模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。 模板匹配就是在整个图像区域发现与给定子图像匹配的小块区域[/code] 工作原理:在待检测图像上,...
  • EmguCv模板匹配

    千次阅读 2019-01-21 22:51:49
    模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。 先贴上简陋的界面图   代码: Mat src = new Image&lt;Bgr, byte&gt;(ib_o...
  • 模板匹配-HALCON

    2018-07-04 20:16:19
    依赖于选择的方法不同,模板匹配可以处理各种情形下的变换,如照明、杂点、大小、位置以及旋转,甚至模版内部的相对移动。模版匹配的鲁棒性和灵活性都很高,而且很多参数可以自适应生成,只有极少的参数需要配置。在...

空空如也

空空如也

1 2 3 4 5 ... 14
收藏数 268
精华内容 107
关键字:

旋转模板匹配