python数字图像处理基础(六)——模板匹配、直方图

目录

    • 模板匹配
      • 概念
      • 单对象模板匹配
      • 多对象模板匹配
    • 直方图
      • 1.查找直方图
      • 2.绘制直方图
      • 3.掩膜的应用

模板匹配

概念

模板匹配和卷积原理很像,模板在原图像上从原点开始滑动,计算模板与图像被模板覆盖的地方的差别程度,这个差别程度的计算方法在opencv里有6种,然后将每次计算的结果放入一个矩阵里,作为结果输出。假如原图是AxB大小,而模板是axb大小,则输出结果的矩阵是(A-a+1)x(B-b+1) (通过.shape查看验证)

匹配算法method
平方差匹配法:计算平方不同,计算出来的值越小,越相关cv2.TM_SQDIFF
归一化平方差匹配法:计算归一化平方不同,计算出来的值越接近0,越相关cv2.TM_SQDIFF_NORMED
相关匹配法:计算相关性,计算出来的值越大,越相关cv2.TM_CCORR
归一化相关匹配法:计算归一化相关性,计算出来的值越接近1,越相关cv2.TM_CCORR_NORMED
相关系数匹配法:计算相关系数,计算出来的值越大,越相关cv2.TM_CCOEFF
归一化相关系数匹配法:计算归一化相关系数,计算出来的值越接近1,越相关cv2.TM_CCOEFF_NORMED

通常来讲,随着从简单测量方法(平方差)到更复杂的测量方法(相关系数法),我们可以获得越来越准确的匹配。然而这同时也会以越来越大的计算量为代价。对于选取何种方法,针对不同的匹配情况进行对此分析比较,选取更适合自己应用场景同时兼顾速度和精度的最佳方案。一般使用归一化的。

cv2.minMaxLoc()函数会返回四个值——最小值及其位置、最大值及其位置(这里的位置是匹配框左上角顶点的坐标位置)

import cv2img = cv2.imread('./image/img1.jpg', 0)
template = cv2.imread('./image/template.png', 0)
h, w = template.shape[:2]
# print(img.shape)
# print(template.shape)
# (225, 203)
# (82, 100)
res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)
# print(res.shape) --> (144, 104)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

理解:利用这个函数找最大值最小值,以及从六种中选择出的匹配算法,两者结合,得到最匹配的点的坐标。由于这个点是匹配框的左上顶点,我们再求得模板图像的长和宽,有左上顶点、长、宽,即可得到与模板匹配的图像

单对象模板匹配

import cv2
from matplotlib import pyplot as pltimg = cv2.imread('./image/img1.jpg', 0)template = cv2.imread('./image/template.png', 0)
h, w = template.shape[:2] # 切片,取shape的前两个值代表模板长宽,不取第三个值(代表BGR)# 六种匹配方法
methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR','cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']for meth in methods:img2 = img.copy()  # 不然原图会被覆盖# eval 语句用来计算存储在字符串中的有效 Python 表达式method = eval(meth)# 模板匹配res = cv2.matchTemplate(img, template, method)# 寻找最值min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)# 使用不同的比较方法,对结果的解释不同# 如果是平方差匹配或归一化平方差匹配,取最小值if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:top_left = min_locelse:top_left = max_locbottom_right = (top_left[0] + w, top_left[1] + h)# 画矩形cv2.rectangle(img, top_left, bottom_right, 255, 2)# 展示plt.subplot(121), plt.imshow(res, cmap='gray')plt.title('Matching Result'), plt.xticks([]), plt.yticks([])  # 隐藏坐标轴plt.subplot(122), plt.imshow(img, cmap='gray')plt.title('Detected Point'), plt.xticks([]), plt.yticks([])plt.suptitle(meth)plt.show()

注意到其中有一个匹配算法的结果匹配的不好

多对象模板匹配

import cv2
import numpy as npimg_rgb = cv2.imread('./image/img1.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
template = cv2.imread('./image/template.png', 0)
h, w = template.shape[:2]# 选择的匹配算法是相关系数法
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
threshold = 0.4
# 取匹配程度大于%40的坐标
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):  # *号表示可选参数bottom_right = (pt[0] + w, pt[1] + h)# 画矩形cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)
cv2.imshow("img", img_rgb)
cv2.waitKey(0)


直方图

  • 什么是直方图?你可以将直方图视为图形或绘图,从而为你提供有关图像强度分布的总体思路。它是X轴上的像素值(范围从0到255,并非总是)和Y轴上图像中相应像素数量的绘图。

  • 一些直方图相关的术语

    BINS:上面的直方图显示每个像素值的像素数量,即从0到255。也就是说,你需要256个值来显示上述的直方图。但是请考虑,如果您不需要分别查找所有像素值的像素数量,但是像素值的间隔中的像素数量是多少?例如,你需要找到位于10到15之间,然后是16到31,…,240到255之间的像素值。你只需要16个值来表示直方图。这就是OpenCV教程中关于直方图的例子。

    因此,你所做的只是将整个直方图拆分成16个子部分,每个子部分的值是其中所有像素数的总和。这个子部分被称为“BIN”。在第一种情况下,BINS中的每组的像素数目都是256,而在第二种情况下,它仅为16个。在OpenCV中,BINS由术语hitSize表示。

    DIMS:这是我们收集数据的参数数量。在这种情况下,我们只收集强度值的数量,所以这里是1.

    RANGE:这是你要测量的强度值的范围。通常,它是[0,256],即所有强度值。

1.查找直方图

1)OpenCV中的直方图计算

我们使用cv2.calcHist()函数来查找直方图。让我们熟悉这个函数及其参数:

Cv2.calcHist(image,channels,mask,hitSize,range[,hist[,accumulate]])

  • image(图像):它是类型为uint8或者float32的源图像。应该用方括号给出,即“[img]”.
  • .Channels(通道):它也是被放在方括号内。它是我们计算直方图的通道的索引。例如,如果输入是灰度图像,则其值为[0].对于彩色图像,可以分别通过[0],[1]或者[2]计算蓝色、绿色或者红色通道的直方图 。
  • Mask(掩膜):要查找完整图像的直方图,它会显示为“无”。但是,如果你想找到特定区域的图像直方图,你必须为此创建一个蒙版图像并将其作为蒙版
  • histSize:这代表我们的BIN数量。需要用方括号给出。对于全尺寸,我们传入[256].
  • Range(范围):通常情况下,它是[0,256].

img = cv2.imread('1.jpg', 0)
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
#hist是一个256*1的数组,每个值对应于图像中具有相应像素值的像素数
print(hist)

2)Numpy中的直方图计算

img = cv2.imread('1.jpg', 0)

hist, bins = np.histogram(img.ravel(), 256, [0, 256])

print("hist", hist)

print("bins", bins)

hist与我们之前计算的相同。但是bins将有257个元素因为Numpy计算bins为0-0.99,1-1.99,2-2.99等。为了表示这一点,他们还在bins的末尾加上256.但我们不需要高达256,255就够了。OpenCV函数比np.histogram()要快(大约40倍)。所以坚持使用OpenCV函数。

2.绘制直方图

两种方法:

Ø Shortway:使用matplotlib绘图函数

Ø Long way:使用OpenCV绘图函数

1)使用Matplotlib(主要)

Matplotlib带有一个直方图绘制函数:matplot.pyplot.hist()

它直接找到直方图并绘制它.不需要使用calcHist()或者np.histogram()函数来查找直方图。

`import cv2`
`from matplotlib import pyplot as plt`
`img = cv2.imread('home.jpg',0)`
`plt.hist(img.ravel(),256,[0,256]); plt.show()`

或者你可以使用matplotlib的正常绘制方式,这对BGR绘制是有利的.为此,你首先需要查找直方图数据。

`import cv2`
`from matplotlib import pyplot as plt``img = cv2.imread('8.jpg')`
`color = ('b', 'g', 'r')`
`for i, col in enumerate(color): # 枚举``histr = cv2.calcHist([img], [i], None, [256], [0, 256])``plt.plot(histr, color=col)``plt.xlim([0, 256])`
`plt.show()`

2)使用OpenCV

用OpenCV的话,你可以将直方图的值与其二进制一起调整为x,y坐标,以便你可以使用cv2.line()或cv2.polyline()函数绘制它以生成与上面相同的图像。这已经在OpenCV-Python2官方demo中可用。

3.掩膜的应用

我们使用cv2.calcHist()来查找完整图像的直方图。如果你想查找图像中某些区域的直方图,该怎么办?只需在想查找直方图的区域创建一个带白色的蒙版图像,否则就是黑色。然后将它作为掩膜。

例子:

img = cv2.imread('2.jpg')`#创建一个掩膜`mask = np.zeros(img.shape[:2], dtype='uint8')`
mask[100:300, 100:400] = 255`
masked_img = cv2.bitwise_and(img, img, mask=mask)`#计算有掩膜和没有掩膜时的直方图`#只需改变第三个参数`hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])`
hist_mask = cv2.calcHist([img], [0], mask, [256], [0, 256])`plt.subplot(221), plt.imshow(img, 'gray'), plt.title("origianl")`
plt.subplot(222), plt.imshow(mask, 'gray'), plt.title('mask')`
plt.subplot(223), plt.imshow(masked_img, 'gray'), plt.title('masked_img')`
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask), plt.title('hist')`plt.xlim([0, 256])`plt.show()`

解释代码:

  • mask = np.zeros(img.shape[:2], dtype=‘uint8’)

    用法:zeros(shape, dtype=float, order=‘C’)

    返回:返回来一个给定形状和类型的用0填充的数组;

    参数:shape:形状

    ​ dtype:数据类型,可选参数,默认np.float64

    ​ order:可选参数,c代表与c语言类似,行优先;F代表列优先

  • plt.title(‘hist’)

    将该figure对象的表头名命名为hist

  • plt.subplot(221)

    subplot()函数则用来实现,在一个大图中,出现多个小的子图。

    处理哪个figure,则选择哪个figure,再进行画图。

    221表示是一个两行两列布局的图,且现在画的是右上角的小图

    同理,236表示画的2行3列布局的最右下角的图

  • hist_full = cv2.calcHist([img], [0], None, [256], [0, 256])

    plt.plot(hist_full)

    hist_full是一个shape为(256,1)的数组,表示0-255每个像素值对应的像素个数,下标即为相应的像素值

    plt.plot()一般需要输入x,y,若只输入一个参数,那么默认x为range(n),n为y的长度,在这里即表示图像x轴为0-255像素点灰度值,y轴为对应灰度值的像素点数量

    一个plt.plot()代表该图像中的一条图线

  • plt.imshow()

    负责对图像进行处理,并显示其格式,但是不能显示。

  • plt.show()

    显示图像

  • plt.xlim([0,256])

    x轴上的值的取值范围为0-256


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/630605.shtml

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

相关文章

如何安装“Nextcloud 客户端”win10系统?

1、 下载 Nextcloud的官网 Download and install Nextcloud 2、安装 3、 Nextcloud登录

组件v-model(.sync)记录使用(vue3)

示例(演示地址) 以下是Vue3中使用v-model实现组件的双向数据绑定的示例代码: 首先,让我们来了解一下Vue3中v-model的用法。在Vue3中,v-model 指令可以用于自定义组件上,用于实现组件的双向数据绑定。与Vue2…

Alinx ZYNQ 7020 LED调试--in RAM

设置拨码开关为JTAG方式 烧写LED bit stream a. 点击“Program device”烧录程序到FPGA中(重新上电程序就丢失了) b. /01_led/led.runs/impl_1/led.bit 程序烧录到Flash中 ZYNQ与以往的直接烧录Flash不同,首先必须PS,然后烧…

spring-boot定时任务

org.springframework.boot jar包 内置定时任务注解 。生成定时任务有 * * * * * ? 表示秒分时日月周。 日和周的位置 必须某个位置用?代替*号用于区别。 定时任务规则:0 * * * ? * * 表示任意月的任意周的每天的每时的每分…

抖音矩阵云混剪系统源码(免授权版)多平台多账号一站式管理,附带系统搭建教程

搭建教程 MySQL 5.6 PHP 7.2 Apache 数据库名称 juzhen Nginx环境切换伪静态 1、解压安装包到项目根目录,找到application/database.php 更换自己的数据库密码 2、阿里云现有的配置不要动 其他按照文档进行添加 3、项目访问目录:public 4、域名…

Demo: 实现PDF加水印以及自定义水印样式

实现PDF加水印以及自定义水印样式 <template><div><button click"previewHandle">预览</button><button click"downFileHandle">下载</button><el-input v-model"watermarkText" /><el-input v-mo…

敏捷开发之Scrum

敏捷开发是什么 我们一般习惯用瀑布模型&#xff0c;它以文档为驱动&#xff0c;将软件生命周期划分为固定的六个基本活动&#xff0c;并且规定了它们自上而下、相互衔接的次序&#xff0c;如同瀑布流水&#xff0c;逐级下落。 那什么是敏捷开发呢&#xff1f; ​ 敏捷开发的核…

代码随想录算法训练营第五天| 总结数组专题

数组&#xff1a;二分查找、双指针&#xff08;包括快慢指针&#xff09;、滑动窗口、模拟 链表&#xff1a;双指针、三指针、虚拟头指针、复杂指针操作画图明确每一步&#xff08;标好次序&#xff09; 数组 代码随想录总结的很好&#xff0c;如下图。我再结合自己的一些理解…

AI 的未来是开源的

想象一下&#xff0c;在未来&#xff0c;人工智能不会被锁在公司的金库里&#xff0c;而是由全球创新者社区一砖一瓦地在开放中构建的。协作&#xff0c;而不是竞争&#xff0c;推动进步&#xff0c;道德考虑与原始绩效同等重要。这不是科幻小说&#xff0c;而是人工智能发展核…

C++I/O流——(4)格式化输入/输出(第二节)

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 含泪播种的人一定能含笑收获&#xff…

73.网游逆向分析与插件开发-背包的获取-物品数据的初步数据分析

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;72.网游逆向分析与插件开发-背包的获取-项目需求与需求拆解-CSDN博客 然后首先找切入点&#xff1a; 通过药物来当切入点&#xff0c;药物比较好使用&#xff0c;然后鼠标放到药物上它有名字、种类、…

【分布式技术】分布式存储ceph之RGW接口

目录 1、对象存储概念 2、创建 RGW 接口 //在管理节点创建一个 RGW 守护进程 #创建成功后默认情况下会自动创建一系列用于 RGW 的存储池 #默认情况下 RGW 监听 7480 号端口 //开启 httphttps &#xff0c;更改监听端口 #更改监听端口 ​ //创建 RadosGW 账户 …

【Go学习】macOS+IDEA运行golang项目,报command-line-arguments,undefined

写在前面的话&#xff1a;idea如何配置golang&#xff0c;自行百度 问题1&#xff1a;通过idea的terminal执行go test报错 ✘ xxxxxmacdeMacBook-Pro-3  /Volumes/mac/.../LearnGoWithTests/hello  go test go: go.mod file not found in current directory or any parent …

【LeetCode热题100】【子串】和为 K 的子数组

题目 给你一个整数数组 nums 和一个整数 k &#xff0c;请你统计并返回 该数组中和为 k 的子数组的个数 。 子数组是数组中元素的连续非空序列。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1], k 2 输出&#xff1a;2示例 2&#xff1a; 输入&#xff1a;nums [1,…

Jet Brains 2023 开发者生态系统现状

一、前言 今天刷到Jet Brains官方发布了2023 开发者生态系统现状&#xff0c;这个相信大家都不陌生&#xff0c;我们的开发工具IDEA就是它旗下的。 分析的蛮不错的&#xff0c;今天整理一下&#xff0c;和大家一起分享。 有想法大家可以一起交流一下哈&#xff01; 有兴趣的…

unity SqLite读取行和列

项目文件 链接&#xff1a;https://pan.baidu.com/s/1BabHvQ-y0kX_w15r7UvIGQ 提取码&#xff1a;emsg –来自百度网盘超级会员V6的分享 using System.Collections; using System.Collections.Generic; using UnityEngine; using Mono.Data.Sqlite; using System; using Syste…

一文读懂——如何把网站改成HTTPS访问

HTTPS&#xff08;全称为Hyper Text Transfer Protocol Secure&#xff09;是一种在计算机网络上进行安全通信的协议&#xff0c;它通过SSL/TLS证书对传输数据进行加密&#xff0c;确保了用户与服务器之间信息交换的私密性和完整性。 获取SSL/TLS证书 选择证书类型&#xff1a…

构建高效数据生态:数据库、数据仓库、数据湖、大数据平台与数据中台解析_光点科技

在数字化的浪潮中&#xff0c;一套高效的数据管理系统是企业竞争力的核心。从传统的数据库到现代的数据中台&#xff0c;每一种技术都在数据的旅程中扮演着关键角色。本文将深入探讨数据库、数据仓库、数据湖、大数据平台以及数据中台的功能和价值&#xff0c;帮助您构建一个符…

《C++入门篇》——弥补C不足

文章目录 前言一.命名空间二.缺省参数三.函数重载四.引用4.1引用做参数4.2引用做返回值 五.内联函数六.小语法6.1auto6.2范围for6.3空指针 前言 C是业内一门久负盛名的计算机语言&#xff0c;从C语言发展起来的它&#xff0c;不仅支持C语言的语法&#xff0c;还新添加了面向对…