当前位置: 首页 > 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 npimg_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 npa = 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)
loc = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]# 1. loc[::-1]:反转列表
reversed_loc = loc[::-1]
print(reversed_loc)  # 输出: [[7, 8, 9], [4, 5, 6], [1, 2, 3]]# 2. *reversed_loc:解包列表
# 此时相当于 zip([7, 8, 9], [4, 5, 6], [1, 2, 3])# 3. zip(*reversed_loc):使用 zip 函数进行打包
zipped = zip(*reversed_loc)
for pt in zipped:print(pt)
# 输出:
# (7, 4, 1)
# (8, 5, 2)
# (9, 6, 3)

 

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 npimg=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)


http://www.mrgr.cn/news/97507.html

相关文章:

  • 【UnityEditor扩展】如何在 Unity 中创建棱柱体(用作VR安全区检测),同时在编辑器插件中实现与撤销/恢复功能
  • HTTP 教程 : 从 0 到 1 全面指南 教程【全文三万字保姆级详细讲解】
  • WEB安全-CTF中的PHP反序列化漏洞
  • 2018年真题
  • SQL:Primary Key(主键)和Foreign Key(外键)
  • 【加密算法】SM4国密算法原理、C++跨平台实现(含完整代码和示例)
  • TCP/IP五层协议
  • 网易运维面试题及参考答案
  • 激光干涉仪学习
  • Linux-CentOS-7—— 安装MySQL 8
  • 设计模式 四、行为设计模式(1)
  • AI烘焙大赛中的算法:理解PPO、GRPO与DPO最简单的方式
  • Python 之 Pandas 常用操作
  • 项目难点亮点
  • 大数据(5)Spark部署核弹级避坑指南:从高并发集群调优到源码级安全加固(附万亿级日志分析实战+智能运维巡检系统)
  • 英语学习 4.7
  • 红宝书第三十一讲:通俗易懂的包管理器指南:npm 与 Yarn
  • C#结合SQLite数据库使用方法
  • C++11实现一个自旋锁
  • 压测工具开发实战篇(四)——client子窗口功能