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

news2024/12/23 0:03:44

目录

    • 模板匹配
      • 概念
      • 单对象模板匹配
      • 多对象模板匹配
    • 直方图
      • 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 cv2

img = 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 plt

img = 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_loc
    else:
        top_left = max_loc
    bottom_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 np

img_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.coloradmin.cn/o/1394441.html

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

相关文章

CS8370错误,这是由于使用了C# 7.3中不支持的功能

目录 背景: 第一种方法: 第二种办法: 背景: 在敲代码的时候,程序提示报错消息提示:CS8370错误,那么这是什么原因导致的,这是由于使用了C# 7.3中不支持的功能,不支持该功能,那就是版本太低我们就需要升级更高的版本&…

DAY03_Spring—自动装配注解模式优化XML文件

目录 1 Spring注解模式1.1 自动装配1.1.1 说明1.1.2 配置规则 1.2 注解模式1.2.1 关于注解的说明1.2.2 注解使用原理1.2.3 编辑配置文件1.2.4 属性注解 1.3 实现MVC结构的纯注解开发1.3.1 编写java代码1.3.2 编辑xml配置文件1.3.3 编写测试类1.3.4 关于注解说明1.3.5 关于Sprin…

python对自动驾驶进行模拟

使用了 Pygame 库来创建一个简单的游戏环境,模拟了一辆自动驾驶汽车在道路上行驶。汽车的位置和速度通过键盘控制,可以左右移动和加速减速。道路的宽度和颜色可以根据需要进行调整。 import pygame import random # 游戏窗口大小 WINDOW_WIDTH 800 WINDOW_HEIG…

3dmax中怎么在模型上开洞?

3dmaxS是Autodesk公司开发的基于PC系统的三维动画渲染和制作软件。我们可以使用它来做各种模型。那么怎么在模型上开洞呢?我们一起来看看吧! 1、首先我们打开我们的3damx,这里面我使用的版本为3damxs2012,虽然版本可能各不相同。但是功能并没…

原生SSM整合(Spring+SpringMVC+MyBatis)案例

SSM框架是Spring、Spring MVC和MyBatis三个开源框架的整合,常用于构建数据源较简单的web项目。该框架是Java EE企业级开发的主流技术,也是每一个java开发者必备的技能。下面通过查询书籍列表的案例演示SSM整合的过程. 新建项目 创建文件目录 完整文件结…

拼多多无货源中转仓项目真的靠谱吗?发展前景如何?

阿阳最近一直在关注无货源电商这一块,尤其是拼多多无货源中转仓, 现如今也有了自己的运营团队和交付团队,整体来看这个项目还算不错! 说实话,在考察这个项目的时候,看到市面上很多人在做,包括我…

JavaScript 类型判断及类型转换规则

文章目录 JavaScript 类型及其判断使用 typeof 判断类型使用 instanceof 判断类型使用 constructor 和 Object.prototype.toString 判断类型JavaScript 类型及其转换JavaScript 函数参数传递cannot read property of undefined 问题解决方案分析一道网红题目JavaScript 类型判断…

【GAMES101】Lecture 08 着色-Blinn-Phong反射模型

目录 Blinn-Phong反射模型-高光 Blinn-Phong反射模型-环境光照 Blinn-Phong反射模型 Blinn-Phong反射模型-高光 我们在lecture7的时候讲了这个Blinn-Phong反射模型的漫反射部分,现在我们继续讲Blinn-Phong反射模型的高光部分 这个高光是怎么产生的呢&#xff0…

} expected.Vetur(1005)

typescript TS 错误码大全!收藏了 - 环信 } expected.Vetur(1005) 没有补齐} 虽然他给的是最后代码出错了,但可以看看之前的代码有没有红色的{,补齐即可以

Air780E开发板开发环境搭建

开发板原理图 开发软件 下载网站 https://luatos.com/luatools/download/last 使用教程 烧录教程 - LuatOS 文档 开发流程 首先下载最新版本的Luatools 然后新建一个Luatools文件夹,将下载的exe文件放入其中后,再打开exe文件(会生成目…

MB51选择屏幕与报表增强

1、文档说明 如之前文档《MIGO新增页签增强》,在MIGO中增强自定义字段,那么在查询MB51时,想通过自定义字段进行筛选,并将数据展示到报表中,就需要对MB51进行增强。 此处需要说明,文档 《MIGO新增页签增强…

Leetcode刷题笔记题解(C++):200. 岛屿数量

思路&#xff1a;利用深度优先搜索的思路来查找1身边的1&#xff0c;并且遍历之后进行0替换防止重复dfs&#xff0c;代码如下所示 class Solution { public:int numIslands(vector<vector<char>>& grid) {int row grid.size();int col grid[0].size();int n…

【从0上手cornerstone3D】如何加载nifti格式的文件

在线演示 支持加载的文件格式 .nii .nii.gz 代码实现 npm install cornerstonejs/nifti-volume-loader// ------------- 核心代码 Start------------------- // 注册一个nifti格式的加载器 volumeLoader.registerVolumeLoader("nifti",cornerstoneNiftiImageVolu…

Ubuntu 安装Python3.8

安装Python3.8 一、安装环境 Ubuntu2004Python2.7 目标是将python版本从 2.7 更新到3.8 二、安装步骤 2.1 下载python3.8安装包 wget https://www.python.org/ftp/python/3.8.0/Python-3.8.0.tar.xz2.2 安装 依次执行如下步骤&#xff1a; tar Jxf Python-3.8.0.tar.xz…

红队打靶练习:NULLBYTE: 1

目录 信息收集 1、arp 2、nmap 3、nikto 4、whatweb 目录探测 1、dirsearch 2、gobuster WEB web信息收集 图片信息收集 hydra爆破 sql注入 闭合 爆库 爆表 爆列 爆字段 hashcat SSH登录 提权 信息收集 1、arp ┌──(root㉿ru)-[~/kali] └─# arp-scan…

梳理从MVP变换到光栅化的过程

1.梳理从MVP变换到光栅化的过程 相关博客&#xff1a; 1.MVP变换 2.Rasterization&#xff08;光栅化&#xff09; 1.1 View/Camera transformation 此例中相机初始位置为&#xff08;0,0,5&#xff09;【备注&#xff1a;详见主函数中输入的值】经过 M view M_{\text{view}}…

shell编程-uname命令详解(超详细)

文章目录 前言一、介绍二、语法格式三、常见选项四、示例用法1. 输出所有信息2. 查看内核名称3. 查看主机名4. 查看内核发行号5. 查看内核版本6. 查看硬件架构名称7. 查看处理器类型8. 查看硬件平台9. 查看操作系统名称10. 查看版本信息 总结 前言 在本文中&#xff0c;我们将…

智能小程序开发项目步骤流程

快速开始 在开发小程序之前&#xff0c;请确保电脑上已经安装node运行环境。可前往Node.js官网(opens in a new tab)下载安装。智能小程序环境搭建和面板小程序一致&#xff0c;请参考面板小程序搭建环境指南。 开发小程序的流程&#xff1a; 使用涂鸦开发者 IoT 账号登录 T…

鸿蒙千帆起~ 是转? 还是留?

近期鸿蒙系统相关行业热度一度高涨&#xff0c;像今天2024年1月18日 鸿蒙OS Next开发者预览版正式发布引起了不少业内人士关注&#xff0c;再度冲上了热榜。余承东老余之前就说过2024年是鸿蒙关键的一年&#xff0c;从这句话就可以看出后一定有大的动作。 就像去年有业内人士网…

Unreal Engine(UE5)中构建离线地图服务

1. 首先需要用到3个软件&#xff0c;Unreal Engine&#xff0c;gis office 和 bigemap离线服务器 Unreal Engine下载地址:点击前往下载页面 Gis office下载地址:点击前往下载页面 Bigemap离线服务器 下载地址: 点击前往下载页面 Unreal Engine用于数字孪生项目开发&#x…