OpenCV-Python(22):直方图的计算绘制与分析

目标

  • 了解直方图的原理及应用
  • 使用OpenCV 或Numpy 函数计算直方图
  • 使用Opencv 或者Matplotlib 函数绘制直方图
  • 学习函数cv2.calcHist()、np.histogram()等

原理及应用

        直方图是一种统计图形,是对图像的另一种解释,用于表示图像中各个像素值的频次分布。直方图的x 轴是灰度值(0 到255),y 轴是图片中具有同一个灰度值的点的数目。通过直方图你可以对整幅图像的灰度分布、对比度、亮度等有一个整体的了解。在计算机视觉中,直方图是一种常用的图像特征描述方法,可以用于图像处理、图像分割、图像匹配等应用,几乎所有的图像处理软件提供了直方图分析功能。

        在图像处理中,直方图可以用于对图像进行增强、对比度调整、色彩均衡等操作。通过分析图像的直方图,可以了解图像的亮度分布情况,进而进行亮度调整,使图像更加清晰、明亮或暗淡。

        在图像分割中,直方图可以用于选择合适的阈值进行图像分割。通过分析图像的直方图,可以找到合适的阈值,将图像分成不同的区域,达到目标检测和图像分割的目的。

        在图像匹配中,直方图可以用于计算图像之间的相似度。通过比较两幅图像的直方图,可以得到它们的相似程度,从而实现图像的匹配和检索。

        我们来分析上面幅图片和它的直方图(要记住:直方图是根据灰度图像绘制的,而不是彩色图像)。直方图的左边区域像是暗一点的像素数量,右侧显示了亮一点的像素的数量。从这幅图上你可以看到灰暗的区域比亮的区域大,而处于中间部分的像素点很少。 

参考以下连接获取更多相关信息:https://www.cambridgeincolour.com/tutorials/histograms1.htm

统计直方图 

        现在我们知道什么是直方图了,那么我们应该怎样获得一副图像的直方图呢?OpenCV 和Numpy 有内置函数做这件事。在使用这些函数之前我们有必要了解一下直方图相关的术语。

  • BINS

        上面的直方图显示了每个像素灰度值对应的像素数目。如果像素值为0到255,你就需要256 个数来显示上面的直方图。但是,如果你不需要知道每一个像素值的像素点数目,而只希望知道两个像素值之间的像素点数目怎么办呢?举例来说,我们想知道像素值在0 到15 之间的像素点的数目,接着是16 到31,....240 到255。我们只需要16 个值来绘制直方图即可。

        那么到底要怎么做呢?你只需要把原来的256 个值等分成16 小组,取每组的总和。而这里的每一个小组就就成为BIN。第一个例子中有256 个BIN,第二个例子中有16 个BIN。在OpenCV 的文档中用histSize 表示BINS。

  • DIMS

        表示我们收集数据的参数数目。在本例中,我们对收集到的数据只考虑一件事:灰度值。所以这里就是1。

  • RANGE

        就是要统的灰度值范围,一般来说为[0-256],也就是所有的灰度值。

cv2.calcHist()函数是OpenCV中用于计算图像直方图的函数。函数原型为:

cv2.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

参数解释:

  • images:输入图像(图像格式为uint8 或float32)。它应该是一个包含图像的列表,每个图像都是一个NumPy数组。
  • channels:指定要计算直方图的通道。它是以0为基础的索引,例如,对于灰度图像,它的值为[0],对于彩色图像,可以传递[0],[1]或[2]来计算蓝色、绿色或红色通道的直方图。
  • mask:眼膜图像,可选参数,用于指定要计算直方图的区域。如果不需要,则传递None。。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像并使用它。
  • histSize:指定直方图的大小。它表示直方图中有多少个BIN(柱子),即分成多少个区间,应该用中括号括起来,例如[256]
  • ranges:指定像素值的范围。一般情况下,它的值为[0, 256],表示像素值的范围为0到255。

返回值:

  • hist:计算的直方图。它是一个一维数组,表示每个bin的频次。

我们从一副简单图像开始吧,示例代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread('image.jpg')

# 将图像转换为灰度图像
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# 计算直方图,别忘了参数中的中括号,只有mask 没有中括号
hist = cv2.calcHist([gray_image], [0], None, [256], [0, 256])

# 绘制直方图
plt.plot(hist)
plt.show()

        上述代码中,首先使用cv2.imread()函数读取图像,然后使用cv2.cvtColor()函数将图像转换为灰度图像。接着,调用cv2.calcHist()函数计算灰度图像的直方图,其中channels参数为[0]表示只计算灰度通道的直方图,mask参数为None表示计算整个图像的直方图,histSize参数为[256]表示直方图分成256个bin,ranges参数为[0, 256]表示像素值的范围为0到255。最后,使用matplotlib库中的plt.plot()函数绘制直方图。

使用Numpy 中的函数np.histogram() 也可以帮我们统计直方图。你也可以尝试以下代码:

#img.ravel() 将图像转换成一维数组,这里没有中括号。
hist,bins = np.histogram(img.ravel(),256,[0,256])

hist 与上面计算的一样。但是这里的bins 是257,因为Numpy 计算bins 的方式为:0-0.99,1-1.99,2-2.99 等。所以最后一个范围是255-255.99。为了显示它,所以在bins 的结尾加上了256。但是我们不需要256,到255就够了。 

绘制直方图

有两种方法来绘制直方图:

  • 1. Short Way(简单方法):使用Matplotlib 中的绘图函数。
  • 2. Long Way(复杂方法):使用OpenCV 绘图函数

Matplotlib 中有直方图绘制函数matplotlib.pyplot.hist()它可以直接统计并绘制直方图。你应该使用函数calcHist() 或np.histogram()统计直方图。代码如下:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('home.jpg',0)
plt.hist(img.ravel(),256,[0,256]);

plt.show()

或者使用如下的方式:

mport cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取图像
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 计算灰度直方图
hist = cv2.calcHist([image], [0], None, [256], [0, 256])

# 绘制直方图
plt.figure()
plt.title('Grayscale Histogram')
plt.xlabel('Bins')
plt.ylabel('# of Pixels')
plt.plot(hist)
plt.xlim([0, 256])
plt.show()

你会得到如下的图:

或者你可以只使用matplotlib 的绘图功能,这在同时绘制多通道(BGR)的直方图很有用。但是你要先告诉绘图函数你的直方图数据在哪。

import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('home.jpg')
color = ('b','g','r')
# 对一个列表或数组既遍历索引又遍历历元素时
# 使用内置enumerrate 函数会有更加直接
#enumerate 会将数组或列表组成一个索引序列。
# 使我们再获取索引和索引内容的时候更加方便
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()

从上面的直方图你可以推断出蓝色曲线右侧的最多,很明显那些就是天空。 使用OpenCV 自带函数绘制直方图比较麻烦,可以单独研究。 

使用掩模绘制直方图

        要统计图像某个局部区域的直方图只需要构建一副掩模图像。将要统计的部分设置成白色,其余部分为黑色就构成了一副掩模图像。然后把这个掩模图像传给函数就可以了。

img = cv2.imread('home.jpg',0)
# create a mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv2.bitwise_and(img,img,mask = mask)
# Calculate histogram with mask and without mask
# Check third argument for 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.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0,256])
plt.show()

结果如下:其中蓝线是整幅图像的直方图,绿线是使用掩模之后的直方图。 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器学习归一化和标准化

1. 为什么做归一化和标准化 样本中有多个特征,每一个特征都有自己的定义域和取值范围,他们对距离计算也是不同的,如取值较大的影响力会盖过取值较小的参数。因此,为了公平,样本参数必须做一些归一化处理,将…

UI演示双视图立体匹配与重建

相关文章: PyQt5和Qt designer的详细安装教程:https://blog.csdn.net/qq_43811536/article/details/135185233?spm1001.2014.3001.5501Qt designer界面和所有组件功能的详细介绍:https://blog.csdn.net/qq_43811536/article/details/1351868…

如何理解李克特量表?选项距离相等+题目权重相等!

在学术研究中,通过开展问卷调查获取数据时,调查问卷分为量表题和非量表题。量表题就是测试受访者的态度或者看法的题目,大多采用李克特量表。 李克特量表是一种评分加总式态度量表(attitude scale),由美国…

论文阅读——Slide-Transformer(cvpr2023)

Slide-Transformer: Hierarchical Vision Transformer with Local Self-Attention 一、分析 1、改进transformer的几个思路: (1)将全局感受野控制在较小区域,如:PVT,DAT,使用稀疏全局注意力来…

山西电力市场日前价格预测【2023-12-28】

日前价格预测 预测说明: 如上图所示,预测明日(2023-12-28)山西电力市场全天平均日前电价为814.30元/MWh。其中,最高日前电价为1500.00元/MWh,预计出现在08:00~08:45,17:00~20:15。最低日前电价为394.61元/…

FairyGUI-Cocos Creator官方Demo源码解读

博主在学习Cocos Creator的时候,发现了一款免费的UI编辑器FairyGUI。这款编辑器的能力十分强大,但是网上的学习资源比较少,坑比较多,主要学习方式就是阅读官方文档和练习官方Demo。这里博主进行官方Demo的解读。 从gitee上克隆项目…

Java多线程<二>多线程经典场景

leetcode 多线程刷题 上锁上一次,还是上多次? 同步的顺序。 1. 交替打印字符 使用sychronize同步锁使用lock锁使用concurrent的默认机制使用volitale关键字 Thread.sleep() / Thread.yield机制使用automic原子类 方式1 :使用互斥访问st…

Linux上管理不同版本的 JDK

当在 Linux 上管理不同版本的 JDK 时,使用 yum 和 dnf 可以方便地安装和切换不同的 JDK 版本。本文将介绍如何通过这两个包管理工具安装 JDK 1.8 和 JDK 11,并利用软连接动态关联这些版本。 安装 JDK 1.8 和 JDK 11 使用 yum 安装 JDK 1.8 打开终端并…

Linux 内存数据 Metrics 指标解读

过去从未仔细了解过使用 free、top 等命令时显式的内存信息,只关注了已用内存 / 可用内存。本文我们详解解读和标注一下各个数据项的含义,同时和 Ganglia 显式的数据做一个映射。开始前介绍一个小知识,很多查看内存的命令行工具都是 cat /pro…

Pytorch框架基础

参考资料 pytorch框架基础 Pycharm 页面卡住解决方案 使用ps命令结合grep来查找PyCharm相关的进程 ps aux | grep pycharm kill -9 [PID]关于怎么找这个卡住的进程,据初步观察,卡住进程打印的信息是最长的,此外,在卡住进程的打…

贪心算法—会议安排

与其明天开始,不如现在行动! 文章目录 1 安排会议1 题目描述2 解决思路3 代码实现 💎总结 1 安排会议 1 题目描述 一些项目要占用一个会议室宣讲,会议室不能同时容纳两个项目的宣讲。 给你每一个项目开始的时间和结束的时间 你来…

MendelianRandomization | 孟德尔随机化神包更新啦!~(一)(小试牛刀)

1写在前面 今天发现MendelianRandomization包更新v0.9了。😜 其实也算不上更新。🫠 跟大家一起分享一下这个包做MR的用法吧。🤩 还有一个包就是TwoSampleMR,大家有兴趣可以去学一下。😅 2用到的包 rm(list ls())# ins…

壮志酬筹>业务被裁>副业转正>收入回正。一个前黑马程序员老师的2023

从年初时的踌躇满志,到年中时整个业务线被砍。全职做前端训练营,四个多月的时间帮助100多名同学拿到了满意的offer,同时也让我的收入重归正轨。仅以这个视频记录我,一个普通程序员的 2023 。 视频版可直接访问 Hello,大…

【年度征文】回顾2023,迎接2024

转眼一年~~2023又到年底了,CSDN年度征文如约而至!不知不觉又在CSDN平台写了488篇博文,非常感谢CSDN提供的平台,同时也感谢关注和支持博主的粉丝们,在马上到来新的一年里,我会继续努力!也非常感谢…

mysql突然找不到,任务管理器里也没有了(图文详细解决)

右键开始键,选终端(管理员) 2.点↓的命令提示符,进到以管理员打开命令指示符 3.输入命令: mysqld.exe -install 如果出现这个Service successfully installed. 就代表成功了 4.输入: net start mysql MySO…

如何解决“电脑缺失msvcp110.dll”错误,msvcp110.dll文件解决方法

“msvcr110.dll丢失”。那么,msvcr110.dlll丢失到底是什么意思呢?它对我们的电脑有什么影响?本文将详细介绍msvcr110.dll的作用以及msvcr110.dll丢失对电脑的影响,并提供5个解决方案来解决这个问题。 一、msvcr110.dll的作用 ms…

【三维目标检测/自动驾驶】IA-BEV:基于结构先验和自增强学习的实例感知三维目标检测(AAAI 2024)

系列文章目录 论文:Instance-aware Multi-Camera 3D Object Detection with Structural Priors Mining and Self-Boosting Learning 地址:https://arxiv.org/pdf/2312.08004.pdf 来源:复旦大学 英特尔Shanghai Key Lab /美团 文章目录 系列文…

交互式笔记Jupyter Notebook本地部署并实现公网远程访问内网服务器

最近,我发现了一个超级强大的人工智能学习网站。它以通俗易懂的方式呈现复杂的概念,而且内容风趣幽默。我觉得它对大家可能会有所帮助,所以我在此分享。点击这里跳转到网站。 文章目录 1.前言2.Jupyter Notebook的安装2.1 Jupyter Notebook下…

Java guava partition方法拆分集合自定义集合拆分方法

日常开发中&#xff0c;经常遇到拆分集合处理的场景&#xff0c;现在记录2中拆分集合的方法。 1. 使用Guava包提供的集合操作工具栏 Lists.partition()方法拆分 首先&#xff0c;引入maven依赖 <dependency><groupId>com.google.guava</groupId><artifa…

Leetcode算法系列| 10. 正则表达式匹配

目录 1.题目2.题解C# 解法一&#xff1a;分段匹配法C# 解法二&#xff1a;回溯法C# 解法三&#xff1a;动态规划 1.题目 给你一个字符串 s 和一个字符规律 p&#xff0c;请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。 1.‘.’ 匹配任意单个字符 2.‘.’ 匹配任意单个字…
最新文章