模板匹配(旋转缩放)旋转不好匹配+20201019

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)
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
OpenCV是一个流行的计算机视觉库,里面包含了许多图像处理和机器视觉算法。其中模板匹配是其中一种常用的图像相似性比较方法。它可以用于在一幅图像中寻找特定模式的位置。 在模板匹配中,通常需要考虑到图像的缩放旋转。对于缩放OpenCV提供了多种缩放方法,如最近邻插值、双线性插值和像素关系重采样等。通过使用这些缩放方法,可以将模板图像和目标图像统一到相同的尺寸,以便进行匹配缩放后的模板图像和目标图像的像素值将按照一定的插值规则进行重新计算,以保持图像的几何形状和内容的相对关系。 而对于旋转OpenCV中提供了相关的旋转函数,例如`getRotationMatrix2D`和`warpAffine`。`getRotationMatrix2D`可以根据给定的旋转角度、缩放因子和旋转中心点计算旋转矩阵,而`warpAffine`可以使用旋转矩阵将图像进行旋转变换。通过这些函数,可以实现对模板图像和目标图像进行旋转操作,以解决图像在不同角度上的匹配问题。 在使用模板匹配进行缩放旋转时,需要注意选择适当的匹配方法,例如平方差匹配、相关系数匹配或归一化互相关匹配等,以及确定合适的匹配阈值,以提高匹配的准确性和稳定性。 总而言之,通过OpenCV模板匹配方法,我们可以对图像进行缩放旋转,以便在不同尺度和角度上寻找特定模式的位置。这使得我们能够更好地处理图像的变形和旋转等问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值