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.hqwc.cn/news/412646.html

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

相关文章

ubuntu开放ssh服务

📑前言 本文主要是【ubuntu】——ubuntu开放ssh服务的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄每日一…

AIOps案例 | 携手擎创,中邮信科成功打造新一代IT智能运维平台,收益明显!

为推动邮政信息科技体制改革、提升信息科技自主供给能力,在原信息技术局、数据中心和软开中心基础上,中邮信息科技(北京)有限公司(简称“中邮信科公司”)经中国邮政集团有限公司于2019年5月被批准成立。 公司主要负责邮政各类信息…

【​电力电子在电力系统中的应用​】6 滞环电流控制的PWM整流器 + STATCOM整流器 + APF仿真

【仅供参考】 【2023.06西南交大电力电子在电力系统中的应用】 目录 步骤一:基于滞环电流控制的PWM整流器仿真 1.1 仿真要求 1.2 仿真电路原理及设计 1.2.1 主电路的搭建 1.2.2 控制电路的搭建 1.3 波形分析 步骤二:从PWM整流器到STATCOM仿真 2…

12.云原生之kubesphere中应用部署方式

云原生专栏大纲 文章目录 k8s中应用部署Kubernetes常用命令 kubesphere中可视化部署应用创建工作负载服务暴露 helm部署应用helm命令行部署应用kubesphere中使用应用仓库 k8s中应用部署 在k8s中要想部署应用,需要编写各种yaml文件,一旦应用依赖比较复杂…

第七在线荣获百灵奖 Buylink Awards 2023零售圈年度卓越服务商品牌

1月11日,由零售圈主办、20零售连锁协会协办、30零售行业媒体支持的中国零售圈大会暨2024未来零售跨年盛典在西安落下帷幕,在这个零售行业盛典中,第七在线凭借其高精尖产品和卓越的服务质量成功入选,并荣获了“百灵奖 Buylink Awar…

关于接口的安全性测试,这方法你学会了吗?

01、接口防刷 1.为什么会有人要刷接口? 牟利:黄牛在 12306 网上抢票再倒卖。 恶意攻击竞争对手:如短信接口被请求一次,会触发几分钱的运营商费用,当量级大了也很可观。 压测:用apache bench 做压力测试…

零基础也能轻松安装Linux系统,快速入门指南!

本章节我们将为大家介绍 Linux 的安装,安装步骤比较繁琐,现在其实云服务器挺普遍的,价格也便宜,如果自己不想搭建,也可以直接买一台学习用用,参考各大云服务器比较。 本章节以 centos6.4 为例。 centos 下…

Springboot智慧校园电子班牌统一管理平台源码

借助AIoT智能物联、云计算技术打造智慧绿色校园,助力实现校园教务管理、教师管理、学籍管理、考勤、信息发布、班级文明建设、校园风采、家校互通等场景功能,打造安全、便捷、绿色的智慧校园。 前后端分离架构 1、使用springbootvue2 2、数据库&#xff…

CAD随机锈坑_中空圆柱试件插件

插件介绍 CAD随机锈坑_中空圆柱试件插件可用于在AutoCAD软件内生成表面存在球形坑洞的中空圆柱体部件。插件在AutoCAD内生成的三维锈坑模型可导入COMSOL、Abaqus、ANSYS等有限元软件内进行仿真模拟,也可用于表面锈坑模型的科研绘图方面。 插件可控制中空圆柱体模…

信息之板:数据看板如何点亮我们的生活

数据看板,作为数据可视化的一种应用形式,已经逐渐渗透到我们的日常生活中,发挥着越来越重要的作用。这种集中呈现和分析信息的工具,不仅在企业管理中大放异彩,更在我们的日常生活中展现出了强大的价值。下面我就以可视…

如何在苹果手机上进行文件管理

摘要 苹果手机没有像安卓系统那样内置文件管理器,但是可以通过使用克魔开发助手来实现强大的文件管理功能。本文介绍了如何使用克魔开发助手在电脑上管理和传输苹果手机的文件。 引言 很多朋友都在使用苹果手机,但是当需要查看手机中的文件时&#xf…

springboot集成shiro+前端vue,前后端分离项目遇到跨域以及sessionid拿不到等问题

近期在写前后端分离的项目,由于前后端分离导致原来使用的shiro配置无法满足现有系统要求。同时在前后端分离项目中存在的一些问题。例如,一些用户信息需要存储在后端方便进行安全性判断,但这些存储在后端的session前端却获取不到(…