当前位置: 首页 > news >正文

OpenCv(七)——模板匹配、打包、图像的旋转

目录

一、模板匹配

模板匹配原理

1、单模板之间的匹配

(1)读取并显示待匹配的图片和模板图片

(2)模板匹配并绘制匹配位置的外接矩形

(3)显示最终的效果 

2、模板与多个对象匹配,仅匹配当前的模板

(1)读取并显示待匹配的图片和模板灰度图片

(2) 模板匹配

(3)设置阈值

3、匹配相同模板的全角度

(1)读取并显示待匹配的图片和模板灰度图片,旋转模板得到所有的能匹配到的模板。

(2)模板匹配并绘制外接矩形

二、打包与np.where()函数

1、np.where()函数

(1) 作为条件选择器(类似三元表达式)

(2) 作为条件索引获取器(省略 x 和 y)

2、打包与解包

(1)打包

(2)解包

3、反转列表

三、图像的旋转

1、使用numpy方法实现旋转

(1)顺时针旋转90度

(2)逆时针旋转90度

2、使用opencv的方法实现图像旋转

(1)顺时针旋转90度

(2)逆时针旋转90度

(3)旋转180度


一、模板匹配

模板匹配是一种用于查找与模板图像(补丁)匹配(相似)的图像区域的技术。

为了识别匹配区域,我们必须通过滑动来将模板图像与源图像进行比较:

         一次移动一个像素(从左到右,从上到下)。在每个位置,都会计算一个度量(度量计算公式),以便它表示该位置的匹配“好”或“坏”程度

模板匹配原理

 

匹配原理:模板从图片的左上角逐一进行匹配,针对每一个匹配位置(位置坐标是模板左上角坐标),都会根据matchTemplate()函数设置的计算方法得到一个对应的得分值,不同的匹配方法数值大小的效果是不同的,找到最优的匹配结果返回。

函数API:

        cv2.matchTemplate(image, templ, method, result=None, mask=None)
                image:待搜索图像
                templ:模板图像
                method:计算匹配程度的方法,可以有:
          TM_SQDIFF 平方差匹配法:该方法采用平方差来进行匹配;匹配越好,值越小;匹配越差,值越大。
          TM_CCORR 相关匹配法:该方法采用乘法操作;数值越大表明匹配程度越好。
          TM_CCOEFF 相关系数匹配法:数值越大表明匹配程度越好。
          TM_SQDIFF_NORMED 归一化平方差匹配法,匹配越好,值越小;匹配越差,值越大。
          TM_CCORR_NORMED 归一化相关匹配法,数值越大表明匹配程度越好。
          TM_CCOEFF_NORMED 归一化相关系数匹配法,数值越大表明匹配程度越好。

        返回匹配结果的矩阵,其中每个元素表示该位置与模板的匹配程度

如果想了解matchTemplate的method的具体计算方法和matchTemplate的基础知识,可以前往OpenCv的官网查看更详细的知识OpenCV: Template Matching。

1、单模板之间的匹配

可乐模板匹配代码

(1)读取并显示待匹配的图片和模板图片

kele = cv2.imread('kele.png')
template = cv2.imread('template.png')
cv2.imshow('kele',kele)
cv2.imshow('template',template)
cv2.waitKey(0)

(2)模板匹配并绘制匹配位置的外接矩形

cv2.minMaxLoc()可以获取矩阵中的最小值和最大值,以及最小值的索引号和最大值的索引号

h, w = template.shape[:2]    #获取模板图片的高和宽

res = cv2.matchTemplate(kele, template, cv2.TM_CCOEFF_NORMED)   #返回匹配结果的矩阵,其中每个元素表示该位置与模板的匹配程度
# cv2.minMaxLoc可以获取矩阵中的最小值和最大值,以及最小值的索引号和最大值的索引号
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 最小值、最大值、最小值位置、最大值位置
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)    #获得图片右下角坐标
kele_template = cv2.rectangle(kele, top_left, bottom_right, (0, 255, 0), 2)  # 绘制矩形

(3)显示最终的效果 

cv2.imshow('kele_template', kele_template)
cv2.waitKey(0)

2、模板与多个对象匹配,仅匹配当前的模板

 模板:

待匹配对象: 

(1)读取并显示待匹配的图片和模板灰度图片

import cv2
import numpy as np
#(这里用到了两种方法来将彩色图片转化为灰度图)

img_rgb=cv2.imread('../data/tuall.jpg')
img_gray=cv2.cvtColor(img_rgb,cv2.COLOR_BGRA2GRAY)
tuone=cv2.imread('../data/tuone.jpg',0)

(2) 模板匹配

h,w=tuone.shape[:2]
# 使用模板匹配方法进行模板匹配
res=cv2.matchTemplate(img_gray,tuone,cv2.TM_CCOEFF_NORMED)

(3)设置阈值

np.where()函数:过滤出符合条件的数值。

阈值设置原理:

在进行多对象匹配时,常常要设置阈值保证能够完全框选到对象,当阈值设置为0.9时,所有满足大于0.9的外接矩形都会被绘制出来,如果这个阈值数据设置的更小,那么符合条件的位置就越多,表现在图上的特征就是有更多的框,框的线更粗。

反转:

loc的数据,下面表示的是行和列,但是在opencv中行时用y表示,列时用x表示,所以按照x,y表示的话,下面给出的数据是,(y,x),绘制矩形时应该是x和y,所以这里要做反转。

# 设置匹配阈值
threshold=0.9
#获取匹配结果中所有符合阈值的点的坐标
loc=np.where(res>=threshold)    #如果得分大于阈值,返回大于阈值的索引

for pt in zip(*loc[::-1]):    #反转打包
    #在原图上绘制矩形框
    cv2.rectangle(img_rgb,pt,(pt[0]+w,pt[1]+h),(0,255,0),1)

cv2.imshow('1',img_rgb)
cv2.waitKey(0)

3、匹配相同模板的全角度

待匹配的图像上有很多个可以匹配上的图,但是匹配的模板需要旋转才能匹配上

将图片上的所有的图像模板都匹配上

(1)读取并显示待匹配的图片和模板灰度图片,旋转模板得到所有的能匹配到的模板。

import cv2
import numpy as np

img_rgb=cv2.imread('../data/tuall.jpg')
img_gray=cv2.cvtColor(img_rgb,cv2.COLOR_BGRA2GRAY)

tuone=cv2.imread('../data/tuone.jpg',0)
tuone1=cv2.rotate(tuone,cv2.ROTATE_90_CLOCKWISE)    #顺时针旋转90度
tuone2=cv2.rotate(tuone,cv2.ROTATE_90_COUNTERCLOCKWISE)    #逆时针旋转90度
tuone3=cv2.rotate(tuone,cv2.ROTATE_180)    #旋转180度
tuones=[tuone,tuone1,tuone2,tuone3]    

(2)模板匹配并绘制外接矩形

h,w=tuone.shape[:2]
# 使用模板匹配方法进行模板匹配
for tu in tuones:
    res=cv2.matchTemplate(img_gray,tu,cv2.TM_CCOEFF_NORMED)
    # 设置匹配阈值
    threshold=0.9
    #获取匹配结果中所有符合阈值的点的坐标
    loc=np.where(res>=threshold)

    for pt in zip(*loc[::-1]):
    #在原图上绘制矩形框
        cv2.rectangle(img_rgb,pt,(pt[0]+w,pt[1]+h),(0,0,255),1)

cv2.imshow('1',img_rgb)
cv2.waitKey(0)

二、打包与np.where()函数

1、np.where()函数

(1) 作为条件选择器(类似三元表达式)

语法

np.where(condition, x=None, y=None)
  • condition:布尔数组或表达式,用于指定条件。
  • x, y(可选):当条件为 True 时返回 x 对应位置的元素,为 False 时返回 y 对应位置的元素。
  • 返回值:形状与 condition 相同的数组,元素来自 x 或 y

示例:

import numpy as np

a = np.array([1, 2, 3, 4, 5])
# 将大于 3 的元素替换为 10,否则保持原值
result = np.where(a > 3, 10, a)
print(result)  # 输出: [ 1  2  3 10 10]

# 更复杂的条件(结合逻辑运算)
b = np.array([10, 20, 30, 40])
condition = (a > 2) & (b < 35)  # 同时满足两个条件
result = np.where(condition, a * 2, b // 2)
print(result)  # 输出: [ 2  4  6 20](仅前3个元素满足条件,最后一个不满足,取 b//2=20)

(2) 作为条件索引获取器(省略 x 和 y)

  语法

np.where(condition)
  • 作用:返回满足条件 condition 的元素的索引(以元组形式表示,每个元素对应数组的一个维度)。
  • 返回值:元组 (ind1, ind2, ..., indn),其中 indi 是第 i 维满足条件的索引数组

示例:

a = np.array([1, 2, 3, 4, 4, 5])
# 获取值为 4 的元素的索引
indices = np.where(a == 4)
print(indices)  # 输出: (array([3, 4]),)(一维数组,索引为 3 和 4)

# 二维数组示例
b = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
condition = b > 5
indices = np.where(condition)
print(indices)  # 输出: (array([1, 2, 2]), array([2, 0, 1, 2])),对应行和列的索引

2、打包与解包

(1)打包

a=[1,2,3]
b=[4,5,6]

# 使用zip将他们按位置进行配对
zipped=zip(a,b)
print(list(zipped))
# 输出:[(1,4),(2,5),(3,6)]

(2)解包

        zip(*iterables)将多个可迭代对象(列表、元组)进行解压操作

# 假设我们已经有了一个打包好的zip对象
zipped=zip(a,b)

# #使用*运算符解包,得到转置的结果
unzipped=zip(*zipped)

3、反转列表

假设 loc = [(1, 2), (3, 4), (5, 6)](3 个坐标点):

  1. 反转列表loc[::-1] = [(5, 6), (3, 4), (1, 2)]

三、图像的旋转

1、使用numpy方法实现旋转

读取图片并重设图片大小

import cv2
import numpy as np

img=cv2.imread("../data/kele.png")
img=cv2.resize(img,dsize=None,fx=0.5,fy=0.5)
 cv2.imshow('yuantu',img)

(1)顺时针旋转90度

# 旋转90度,k=-1,表示顺时针旋转90度
rotated_image1=np.rot90(img,k=-1)
cv2.imshow('totated_image1',rotated_image1)

(2)逆时针旋转90度

# 旋转90度,k=1,表示逆时针旋转90度
rotated_image2=np.rot90(img,k=1)
cv2.imshow('retated_image',rotated_image2)
cv2.waitKey(0)
cv2.destroyAllWindows()

2、使用opencv的方法实现图像旋转

(1)顺时针旋转90度

rotated_image=cv2.rotate(img,cv2.ROTATE_90_CLOCKWISE)   #顺时针旋转90
cv2.imshow('shun90',img)

(2)逆时针旋转90度

rotated_image1=cv2.rotate(img,cv2.ROTATE_90_COUNTERCLOCKWISE)   #逆时针旋转90度
cv2.imshow('ni90',rotated_image1)

(3)旋转180度

rotated_image2=cv2.rotate(img,cv2.ROTATE_180)   #旋转180度
cv2.imshow('180',rotated_image2)
cv2.waitKey(0)

相关文章:

  • 在Unity中实现《幽灵行者》风格的跑酷动作
  • Linux 递归查找并删除目录下的文件
  • HTML基础教程:创建双十一购物狂欢节网页
  • VUE中数据绑定之OptionAPI
  • C语言基础17
  • ebpf: CO-RE, BTF, and Libbpf(一)
  • 我的第一个正式开源小项目:内网文件传输工具
  • 2025 年上海保安员职业资格考试深度剖析​
  • 大模型RAG项目实战-知识库问答助手v1版
  • PDF 中提取数学公式
  • 通过安装Windows 11英文版 解决组件问题解决中文版中无法修复组件的问题
  • AI前端组件库Ant DesIgn X
  • Cribl 新建Datatype
  • 人工智能 和 线性代数
  • Skyeye 云智能制造办公系统 - 云校园 VUE 版本 v3.15.16 发布
  • C++11QT复习 (十五)
  • Elixir语言的移动应用安全
  • 谈谈我所了解的hash
  • 哑铃图:让数据对比一目了然【Dumbbell Chart】
  • Java【多线程】(7)常见的锁策略
  • 企业网站管理的含义及内容/互动营销名词解释
  • 国务院关于网站建设/百度一下百度搜索百度一下
  • 如何用凡科做网站/重庆网站设计
  • 网站价格套餐/seo待遇
  • 做网站时点击显示/seo竞价培训
  • 汽车网站模板/酒店机票搜索量暴涨