精华内容
下载资源
问答
  • 模板匹配算法可以支持平移缩放和旋转变化,采用对数极坐标的方法进行模板配准
  • 匹配是通过旋转模板并将其以各种角度与图像匹配来完成的,返回最佳匹配。 模板与图像的匹配可以通过各种模板匹配方法来完成,包括互相关和广义霍夫变换。 有关更多详细信息,请参阅代码 zip 文件中提供的自述文件
  • 课程名称 数字图像处理 实验序号 实验 8 实验名称 图像匹配模板匹配 实验地点 综 B207 实验学时 2 实验类型 验证性 2017 年 10 月 16 日 1 一实验目的及要求 在机器识别物体的过程 常需把不同传感器或同一传感器在...
  • 旋转的简单模板匹配在图像中找到适合模板的对象。图像中对象的方向不必与模板相同。 模板以各种旋转与图像匹配,并选择最佳匹配。 该函数使用模板和图像的canny边缘图像之间的互相关来确定最佳匹配。 MAIN_find_...
  • 带微小缩放和旋转模板匹配

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

    问题提出:

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

    问题分析:

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

    实现效果

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

    思路一:Hu矩

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

    展开全文
  • 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++实现
  • 解压到可以用C#直接调用,输入相关参数即可,功能是先画一条要找的边,自动会生成一条线,根据线与轴线自动旋转角度,并且可以创建模板和读取模板,并且匹配模板,有需要的赶紧下载吧!
  • 基于OpenCv实现了模板图像的旋转匹配,此代码基于matchTemplate函数封装实现可以得知旋转角度的模板匹配(vs2013+opencv2.4.9) 2.带旋转模板匹配的原理及算法实现(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模板匹配

    2017-06-03 13:25:02
    模板匹配
  • 模板匹配

    千次阅读 2019-03-07 21:50:39
    模板匹配 模板匹配是数字图像处理的重要组成部分之一。把不同传感器或同一传感器在不同时间、不同成像条件下对同一景物获取的两幅或多幅图像在空间上对准,或根据已知模式到另一幅图中寻找相应模式的处理方法就...

    一. 模板匹配

    模板匹配是数字图像处理的重要组成部分之一。把不同传感器或同一传感器在不同时间、不同成像条件下对同一景物获取的两幅或多幅图像在空间上对准,或根据已知模式到另一幅图中寻找相应模式的处理方法就叫做模板匹配。

    简单而言,模板就是一幅已知的小图像。模板匹配就是在一幅大图像中搜寻目标,已知该图中有要找的目标,且该目标同模板有相同的尺寸、方向和图像,通过一定的算法可以在图中找到目标,确定其坐标位置。

    二. 单目标模板匹配

    这里的模板匹配的方法其实并不复杂,利用目标的边缘信息用于搜索目标图像的模板所在位置。先上模板图像,利用一定的方法提取模板图像的边缘,提取边缘中做了一定的优化,如最大值抑制,双滞滤波器等等,使得边缘信息足够精确,提取出的边缘图像与模板图像放一起好对比。这里请忽略边缘图像中的蓝色十字架,和边缘图像的大小,这里是经过处理的,方便定位以及金字塔图像的处理。


    这里贴张目标图像,就是需要匹配的图像,先从简单到复杂讲解,对单目标匹配完才能进行多目标匹配嘛,如下图所示为目标图像,由于太大了,缩放下,哈哈,模板图像其实是从红色框框里抠出来的。


    这里需要提取目标图像的梯度图,先分别提取水平和垂直的梯度图像,在计算出梯度的模的图像:



    好了,目标图像的梯度信息有了,模板图像的边缘信息也有了,这时候可以进行简单的单目标模板匹配了。这里利用如下公式进行模板匹配:


    也就是在目标梯度图像中逐像素进行搜索,利用NCC匹配度进行判断,大于一定的匹配度,我们就认为这个就是模板图像,找到最大的匹配度,单目标匹配就完成了。哈哈,是不是很简单。接下来说说多目标模板匹配吧。

    三. 多目标模板匹配

    有了之前的基础,这里要说说多目标模板匹配,目标图像中很有可能出现需要匹配的目标处于旋转一定角度的,就是说,目标与模板的摆放角度并不相同,如下图所示:


    这里红色的框为模板图像,白色的框框就是其他目标图像,看出角度相差蛮大的吧。怎么解决呢?

    这里很容易就联想到,可以将模板图像的边缘图像旋转1°就生成一个模板图像,再在图中进行寻找,确实是这么做的,但是呢,有一个问题,直接这样计算,计算复杂度相当高,对于一张大图,耗时可是相当可怕的。

    图像金字塔刚好可以解决这个问题,我们可以利用图像金字塔的由粗糙到精细以达到加速的作用,利用模板图像进行下采样,然后提取边缘后进行旋转,进行金字塔的最底层的图像粗匹配。


    读者这时候一定会觉得,我的天哪,怎么误匹配这么多,其实这是因为缩小后图像的噪声导致匹配的目标多了,别担心这是正常现象,可是有没有发现,这里虽然很多,但相比于原来的逐点匹配,到下一层匹配的区域就缩小了很多,时间就提上去了很多,这里贴张下一层金子塔的匹配结果。有没有很兴奋?完全把目标图像中的目标提取出来了。


    接下来金字塔的任务就是对目标图像中的目标进行精确提取就可以了,任务基本上完工了,贴张最终效果图吧。



    文章来自:https://blog.csdn.net/x454045816/article/details/52638528
    展开全文
  • 综合利用图像梯度幅值统计...仿真试验结果显示:本文算法在模板图像发生任意角度旋转的情况下匹配性能好。该算法时间复杂度小,并且在模板图像灰度发生一定程度的非线性变换、缩放、遮挡等情况时仍具有良好的鲁棒性能。
  • 针对工业自动装配产品过程中异形工件出现旋转后的定位问题,提出一种新的异形目标识别方法,设计基于目标轮廓的同心等势线异形模板,并结合圆投影方法,能快速有效地实现计算机对异形目标的自动识别与定位。...
  • 目前对图像的旋转,缩放情况下的轮廓匹配的方法一般是,对模板图像和待匹配的图像均进行金字塔下采样,缩小图像的大小,减小计算量。然后穷举法暴力匹配,就是每旋转一个角度,缩放一个尺寸,就匹配一次。在上层的...
  • OpenCV模板匹配

    2021-06-28 14:57:59
    OpenCV模板匹配模板匹配的含义 Fu Xianjun. All Rights Reserved 模板匹配的含义 模板匹配是指在当前图像A内寻找图像B最相似的部分,一般将图像A称为输入图像,将图像B称为模板图像。模板匹配的操作方法是将模板图像...
  • 选择模板 旋转180度进行识别 继续旋转 ,依然可以识别 代码: * Searching the best matching of a template in an image (with rotation). * dev_close_window () read_image (For6, 'for6') get_image...
  • 模板匹配算法

    万次阅读 2016-03-31 20:33:56
    模板匹配(Template Matching)算法
  • OpenCV 模板匹配

    2021-06-30 16:45:28
    模板匹配就是在大图中找小图,也就说在一幅图像中寻找另一幅模板图像的位置。 案例来源于傅老师。 模板匹配的操作方法是将模板图像B在图像A上滑动,遍历所有像素以完成匹配。 工作原理:在带检测图像上,从左到右...
  • 模板匹配 ...模板匹配具有自身的局限性,主要表现在它只能进行平行移动,若原图像中的匹配目标发生旋转或大小变化,该算法无效。 普通的模板匹配方法属于暴力搜索法,通过将模板图像不断在搜索图上移动...
  • EmguCv模板匹配

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

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,561
精华内容 5,024
关键字:

旋转模板匹配