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.mzph.cn/web/74915.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥云客 最大和

问题描述 小蓝在玩一个寻宝游戏&#xff0c;游戏在一条笔直的道路上进行&#xff0c;道路被分成了 n 个方格&#xff0c;依次编号 1 至 n&#xff0c;每个方格上都有一个宝物&#xff0c;宝物的分值是一个整数&#xff08;包括正数、负数和零&#xff09;&#xff0c;当进入一…

【C++算法】49.分治_归并_计算右侧小于当前元素的个数

文章目录 题目链接&#xff1a;题目描述&#xff1a;解法C 算法代码&#xff1a;图解 题目链接&#xff1a; 315. 计算右侧小于当前元素的个数 题目描述&#xff1a; 解法 归并排序&#xff08;分治&#xff09; 当前元素的后面&#xff0c;有多少个比我小。&#xff08;降序&…

IPSec简单例子

实验说明 使用Ensp模拟器实现IPsec隧道实验。IPSec是一种VPN技术&#xff0c;配置的思路首先是两个网络先通&#xff0c;然后配置ACL、IEK和IPSec对等体&#xff0c;从而建立VPN隧道。 实验拓扑 配置过程 1 配置IP地址以及OSPF路由 # 配置中使用了简写命令&#xff0c;不熟…

车载联网终端4G汽车TBOX介绍定义与概述

汽车 TBOX&#xff08;Telematics Box&#xff09;是专为汽车设计的远程通信终端设备&#xff0c;属于车联网系统的关键组成部分。车联网系统一般包含主机、汽车 T - BOX、手机 APP 及后台系统。融合了车身网络和 4G 无线通信技术&#xff0c;为汽车提供丰富的 Telematics 服务…

《DeepSeek RAG 增强检索知识库系统》Ollama DeepSeek 流式应答页面对接之三

前言 自从有了 AI 工具以后&#xff0c;所有以前头疼前端页面开发的后端程序员&#x1f468;&#x1f3fb;‍&#x1f4bb;&#xff0c;都漏出了友善&#x1f60a;微笑&#xff01; 主要我们可以清楚地表达编写页面诉求&#xff0c;AI 工具就可以非常准确且迅速的完成代码的实…

【MyBatis】深入解析 MyBatis:关于注解和 XML 的 MyBatis 开发方案下字段名不一致的的查询映射解决方案

注解查询映射 我们再来调用下面的 selectAll() 这个接口&#xff0c;执行的 SQL 是 select* from user_info&#xff0c;表示全列查询&#xff1a; 运行测试类对应方法&#xff0c;在日志中可以看到&#xff0c;字段名一致&#xff0c;Mybatis 就成功从数据库对应的字段中拿到…

深入理解Java性能调优与JVM底层机制

Java作为一种广泛应用的编程语言&#xff0c;在企业级应用中占据着举足轻重的地位。随着系统规模的扩大和业务需求的复杂化&#xff0c;性能调优成为了开发过程中不可忽视的一环。Java的性能瓶颈往往并不直接来自代码本身&#xff0c;而是与JVM&#xff08;Java虚拟机&#xff…

odo18实施——销售-仓库-采购-制造-制造外包-整个流程自动化单据功能的演示教程

安装模块 安装销售 、库存、采购、制造模块 2.开启外包功能 在进入制造应用点击 配置—>设置 勾选外包&#xff0c;点击保存 添加信息 一、添加客户信息 点击到销售应用 点击订单—>客户 点击新建 创建客户1&#xff0c;及其他客户相关信息&#xff0c;点…

Logo语言的在线课程学习

Logo语言在线课程学习的探索 引言 在信息技术快速发展的今天&#xff0c;编程已经成为一门重要的技能。尤其随着人工智能、数据分析和互联网技术的普及&#xff0c;各种编程语言层出不穷&#xff0c;其中Logo语言以其独特的教育意义和学习优势&#xff0c;逐渐受到学校和教育…

情感语音的“开源先锋”!网易开源

语音合成技术近年来取得了显著进步&#xff0c;特别是在语音克隆、语音助手、配音服务和有声读物等领域。然而&#xff0c;如何让合成的语音更具情感&#xff0c;更贴近人类的真实表达&#xff0c;一直是这一领域的重要研究方向。今天&#xff0c;我们将为大家介绍一款由网易有…

摄像头模块对焦方式的类型

摄像头模块的对焦方式直接影响成像清晰度和使用场景适应性&#xff0c;不同技术各有其优缺点。以下是常见对焦方式及其原理、特点和应用场景的详细说明&#xff1a; ‌1. 固定对焦&#xff08;Fixed Focus&#xff09;‌ ‌原理‌&#xff1a;镜头固定在特定距离&#xff08;…

使用Vue、Nodejs以及websocket搭建一个简易聊天室

简易聊天室 说在前面效果展示websocketwebsocket的由来websocket的特点 vue前端静态结构效果代码 点击切换用户以及该用户高亮实现思路效果展示 发送消息功能效果展示 连接服务端 Nodejs服务器端实现步骤代码 说在前面 在学习计算机网络的时候&#xff0c;看到了websocket这个…

【免费】2005-2019年各地级市绿色专利申请量数据

2005-2019年各地级市绿色专利申请量数据 1、时间2005-2019年 2、来源&#xff1a;国家知识产权局 3、指标&#xff1a;省份、城市、年份、绿色发明专利申请量、绿色实用新型专利申请量 4、范围&#xff1a;360地级市 5、指标解释&#xff1a;绿色专利是指涉及环保、新能源…

架构师面试(二十六):系统拆分

问题 今天我们聊电商系统实际业务场景的问题&#xff0c;考查对业务系统问题的分析能力、解决问题的能力和对系统长期发展的整体规划能力。 一电商平台在早期阶段业务发展迅速&#xff0c;DAU在 10W&#xff1b;整个电商系统按水平分层架构进行设计&#xff0c;包括【入口网关…

2. Qt界面文件原理

本节主要介绍ui文件如何与窗口关联&#xff0c;并通过隐式连接方式显示对话框 本文部分ppt、视频截图原链接&#xff1a;[萌马工作室的个人空间-萌马工作室个人主页-哔哩哔哩视频] 1 UI文件如何与窗口关联 1.1 mainwindow.cpp的头文件ui_mainwindow.h 根据编译原理的基本规…

雅思大作文写作——词伙、简单句、并列句的使用

词伙是一些可以表达我们常用观点的单词组合,这个组合可能不只是2-3个单词,也可能是很多单词组成的一个短句。 一、词伙使用 1. 不要中译英 2. 重视词伙,而非单词 如何替换表达 1. 如果要替换的是一个名词,如students,则有下面的一些方法: A. 使用替换词或者词组:y…

⭐算法OJ⭐滑动窗口最大值【双端队列(deque)】Sliding Window Maximum

文章目录 双端队列(deque)详解基本特性常用操作1. 构造和初始化2. 元素访问3. 修改操作4. 容量操作 性能特点时间复杂度&#xff1a;空间复杂度&#xff1a; 滑动窗口最大值题目描述方法思路解决代码 双端队列(deque)详解 双端队列(deque&#xff0c;全称double-ended queue)是…

电机的了解到调试全方面讲解

一、什么是电机 电机是一种将电能转换为机械能的装置,通常由定子、转子和电磁场组成。 当电流通过电机的绕组时,产生的磁场会与电机中的磁场相互作用,从而使电机产生旋转运动。电机广泛应用于各种机械设备和工业生产中,是现代社会不可或缺的重要设备之一。 常见的电机种…

分布式微服务系统架构第97集:JVM底层原理

加群联系作者vx&#xff1a;xiaoda0423 仓库地址&#xff1a;https://webvueblog.github.io/JavaPlusDoc/ https://1024bat.cn/ JVM 内存结构 Java 虚拟机的内存空间分为 5 个部分&#xff1a; 程序计数器 Java 虚拟机栈 本地方法栈 堆 方法区 JDK 1.8 同 JDK 1.7 比&…

制定大运维管理体系的标准、流程、机制、规范

规划并制定大运维管理体系的标准、流程、机制、规范&#xff0c;对于确保平台的可用性和稳定性至关重要。这一过程涉及从顶层设计到具体执行的全面考量&#xff0c;需要综合考虑业务需求、技术架构、团队能力等多方面因素。以下是一个基本框架&#xff0c;用于指导如何构建有效…