opencv进阶01-直方图的应用及示例cv2.calcHist()

直方图是什么?

直方图是一种图形表示方法,用于显示数据中各个数值或数值范围的分布情况。它将数据划分为一系列的区间(也称为“箱子”或“bin”),然后统计每个区间中数据出现的频次(或频率)。直方图可以帮助我们更好地理解数据的分布特征,包括集中趋势、离散程度等。

直方图的主要特点包括:

1. 横轴(X 轴): 横轴表示数据的数值范围或区间。每个区间通常由两个数值来表示,例如,0-10、10-20 等。

2. 纵轴(Y 轴): 纵轴表示每个区间中数据的频次(或频率),也就是该区间内数据出现的次数。

3. 条形图: 直方图的图形由一系列的矩形条组成,每个矩形条的宽度表示区间的宽度,高度表示该区间内数据的频次。

4. 连续数据直方图适用于连续型数据,例如测量数据、时间数据等。对于离散型数据,柱状图可能更为适合

直方图在许多领域有重要的应用,包括统计学、图像处理、数据分析等。在图像处理中,直方图可以用来分析图像的像素值分布,从而进行图像增强、对比度调整、图像分割等操作。在统计学中,直方图可以帮助我们了解数据的分布情况,如正态分布、偏态分布等。通过观察直方图,我们可以对数据的特征有更深入的了解,从而做出更准确的决策和分析

直方图在图像中的含义

从统计的角度讲,直方图是图像内灰度值的统计特性与图像灰度值之间的函数,直方图统计图像内各个灰度级出现的次数。从直方图的图形上观察,横坐标是图像中各像素点的灰度级,纵坐标是具有该灰度级(像素值)的像素个数。

例如,有一幅图像如图 13-1 所示。该图中只有 9 个像素点,存在 1、2、3、4、5,共 5 个灰度级。

在这里插入图片描述

统计各个灰度级出现的次数,如表 13-1 所示

在这里插入图片描述
在绘制直方图时,将灰度级作为 x 轴处理,该灰度级出现的次数作为 y 轴处理,则可知:

  • x 轴的数据为 x=[1 2 3 4 5]。
  • y 轴的数据为 y=[3 1 2 1 2]。

根据上述关系,可以绘制出如图 13-2 所示的折线图(左图)和直方图(右图)。一般情况下,我们把左侧的直线图和右侧直方图都称为直方图。

在这里插入图片描述

在实际处理中,图像直方图的 x 轴区间一般是[0, 255],对应的是 8 位位图的 256 个灰度级;y 轴对应的是具有相应灰度级的像素点的个数。

例如在图 13-3 中,上图是一张图像,下图则是其对应的直方图。图中圆点表示这些像素点会被统计到对应的灰度级上。

在这里插入图片描述

虽然 8 位的图像都具有 256 个灰度级(每一个像素可以有 256 个灰度值),但是属于不同灰度级的像素数量是很不一样的。

例如图 13-4,从图中可以看出,图像的不同部分直方图是不一样的。
在这里插入图片描述

有时为了便于表示,也会采用归一化直方图。在归一化直方图中,x 轴仍然表示灰度级;y轴不再表示灰度级出现的次数,而是灰度级出现的频率。
例如,针对图 13-1,统计各个灰度级出现的频率:

灰度级出现的频率 = 灰度级出现的次数/总像素数

在图 13-1 中共有 9 个像素,所以统计结果如表 13-2 所示。

在这里插入图片描述

在归一化直方图中,各个灰度级出现的频率之和为 1。例如,本例中:

在这里插入图片描述
在绘制直方图时,将灰度级作为 x 轴数据处理,将其出现的频率作为 y 轴数据处理,则可知:

  • x 轴的数据为 x=[1 2 3 4 5]
  • y 轴的数据为 y=[3/9 1/9 2/9 1/9 2/9]

根据上述关系,可以绘制出如图 13-5 所示的归一化直方图。对比图 13-4 与图 13-5,可以看到,归一化直方图与直方图在外观上是一致的,只是 y 轴的标签不同而已。

本例中,在直方图内,y 轴显示的标签是 1、2、3;在归一化直方图中,y 轴显示的标签是 1/9、2/9、3/9。

在这里插入图片描述
在 OpenCV 的官网上,特别提出了要注意三个概念:DIMS、BINS、RANGE。

  • DIMS:表示在绘制直方图时,收集的参数的数量。一般情况下,直方图中收集的数据只有一种,就是灰度级。因此,该值为 1。
  • RANGE:表示要统计的灰度级范围,一般为[0, 255]。0 对应的是黑色,255 对应的是白色。
  • BINS:参数子集的数目。在处理数据的过程中,有时需要将众多的数据划分为若干个组,再进行分析。

例如,针对图 13-1 中的灰度级,你可能希望将两个像素值作为一组讨论。这样,整个灰度级被划分为三组,具体为{ {1,2} , {3,4} , {5} }。图 13-6 所示的是划分前后的直方图情况。

在这里插入图片描述

也可以按照上述方式对灰度图像进行划分。例如,在灰度图像中,将[0, 255]区间内的 256个灰度级,按照每 16 个像素一组划分为子集:

[0, 255] = [0, 15] ∪ [16, 31] ∪…∪[240, 255]

按照上述方式,整个灰度级范围可以划分为 16 个子集,具体为:

整个灰度级范围 = bin1 ∪ bin2 ∪…∪ bin16

子集划分完以后,某灰度图像生成的直方图如图 13-7 所示(图中的 b1 代表 bin1,b2 代表bin2,以此类推)。

在这里插入图片描述
下面讨论 BINS 的值:

  • 针对图 13-1,在原始图像中,共有 5 个灰度级,其 BINS 值为 5。在以 2 个灰度级为一个小组划分子集后,得到 3 个子集,其 BINS 值为 3。
  • 针对灰度图像,灰度级区间为[0, 255],共有 256 个灰度级,其 BINS 值为 256;在以 16个灰度级为一个小组划分子集后,其 BINS 值为 16。

说白了就是柱子的数量

绘制直方图

Python 的模块 matplotlib.pyplot 中的 hist()函数能够方便地绘制直方图,我们通常采用该函数直接绘制直方图(机器学习也用的这个)。除此以外,OpenCV 中的cv2.calcHist()函数能够计算统计直方图,还可以
在此基础上绘制图像的直方图。下面分别讨论这两种方式。

使用Numpy绘制直方图

模块 matplotlib.pyplot 提供了一个类似于 MATLAB 绘图方式的框架,可以使用其中的matplotlib.pyplot.hist()函数(以下简称为 hist()函数)来绘制直方图。

此函数的作用是根据数据源和灰度级分组绘制直方图。其基本语法格式为:

matplotlib.pyplot.hist(X,BINS)

其中两个参数的含义如下:

  • X:数据源,必须是一维的。图像通常是二维的,需要使用 ravel()函数将图像处理为一维数据源以后,再作为参数使用。

  • BINS:BINS 的具体值,表示灰度级的分组情况

函数 ravel()的作用是将二维数组降维成一维数组。例如,有图像 a,其值为:

在这里插入图片描述
使用函数 ravel()对 a 进行处理:

b = a.ravel()

可以得到 b 为:
在这里插入图片描述

示例:使用 hist()函数绘制一幅图像的直方图。

在这里插入图片描述
代码如下:

import cv2
import matplotlib.pyplot as plt
o=cv2.imread("boat.jpg")
plt.hist(o.ravel(),256)
plt.show()

运行结果:

在这里插入图片描述

示例:使用函数 hist()将一幅图像的灰度级划分为 16 组后,绘制该图像的直方图。

将上面的255改成了16

import cv2
import matplotlib.pyplot as plt
o=cv2.imread("boat.jpg")
plt.hist(o.ravel(),16)
plt.show()

在这里插入图片描述

使用OpenCV绘制直方图

OpenCV 提供了函数 cv2.calcHist()用来计算图像的统计直方图,该函数能统计各个灰度级的像素点个数。利用matplotlib.pyplot 模块中的 plot()函数,可以将函数 cv2.calcHist()的统计结果绘制成直方图

1.用cv2.calcHist()函数统计图像直方图信息
函数 cv2.calcHist()用于统计图像直方图信息,其语法格式为:

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

函数中返回值及参数的含义为:

  • hist:返回的统计直方图,是一个一维数组,数组内的元素是各个灰度级的像素个数。

  • images:原始图像,该图像需要使用“[ ]”括起来。

  • channels:指定通道编号。通道编号需要用“[ ]”括起来,如果输入图像是单通道灰度图像,该参数的值就是[0]。对于彩色图像,它的值可以是[0]、[1]、[2],分别对应通道B、G、R。

  • mask:掩模图像。当统计整幅图像的直方图时,将这个值设为 None。当统计图像某一部分的直方图时,需要用到掩模图像。

  • histSize:BINS 的值,该值需要用“[ ]”括起来。例如,BINS 的值是 256,需要使用“[256]”作为此参数值。

  • ranges:即像素值范围。例如,8 位灰度图像的像素值范围是[0, 255]。

  • accumulate:累计(累积、叠加)标识,默认值为 False。如果被设置为 True,则直方图在开始计算时不会被清零,计算的是多个直方图的累积结果,用于对一组图像计算直方
    图。该参数允许从多个对象中计算单个直方图,或者实时更新直方图。该参数是可选的,一般情况下不需要设置。

示例:使用 cv2.calcHist()函数计算一幅图像的统计直方图结果,并观察得到的统计直方图信息。

代码如下:


import cv2
img=cv2.imread("boat.jpg")
hist = cv2.calcHist([img],[0],None,[16],[0,255])
print(type(hist))
print(hist.shape)
print(hist.size)
print(hist)

运行结果如下:
需要注意,在本例的 cv2.calcHist()函数中:

  • 第 1 个参数“[img]”表示要绘制直方图的原始图像,是使用“[ ]”括起来的。
  • 第 2 个参数表示要统计哪个通道的直方图信息。本例中读取的 img 是灰度图像,所以使
    用“[0]”来表示。
  • 第 3 个参数是掩模图像,在本例中的值为“None”,表示计算整幅图像的直方图。
  • 第 4 个参数“[16]”表示 BINS 的值是 16,也就是分了16组
  • 第 5 个参数“[0, 255]”表示灰度级的范围是[0, 255]。
<class 'numpy.ndarray'>
(16, 1)
16
[[ 12575.]
 [ 39591.]
 [ 56651.]
 [ 38932.]
 [ 29997.]
 [ 33472.]
 [ 46033.]
 [ 74555.]
 [199718.]
 [288966.]
 [136663.]
 [ 44440.]
 [ 20355.]
 [ 20691.]
 [  5578.]
 [   344.]]

示例:绘制统计直方图

import cv2
from matplotlib import pyplot as plt

img=cv2.imread("boat.jpg")
hist = cv2.calcHist([img],[0],None,[16],[0,255])


plt.plot(hist,color='b')
plt.show()

运行结果:
在这里插入图片描述

以上都是将图像进行直方图展示函数,下面来讲下直方图在图像处理中的应用函数。

直方图均衡化

如果一幅图像拥有全部可能的灰度级,并且像素值的灰度均匀分布,那么这幅图像就具有高对比度和多变的灰度色调,灰度级丰富且覆盖范围较大。在外观上,这样的图像具有更丰富的色彩,不会过暗或过亮。

图 13-22 展示了对一幅图像进行直方图均衡化前后的对比,左图是原始图像,比较暗;右图是均衡化后的图像,色彩比较均衡。

在这里插入图片描述

在 OpenCV 的官网上,对图像均衡化(即直方图均衡化)前后的直方图进行了对比,如图13-23 所示。其中,左图是原始图像的直方图,可以看到灰度级集中在中间,图像中没有较暗和较亮的像素点;右图是对原图均衡化后的直方图,像素分布更均衡。

在这里插入图片描述

直方图均衡化的主要目的是将原始图像的灰度级均匀地映射到整个灰度级范围内,得到一个灰度级分布均匀的图像。这种均衡化,既实现了灰度值统计上的概率均衡,也实现了人类视觉系统(Human Visual System,HVS)上的视觉均衡。

直方图均衡化函数

OpenCV 使用函数 cv2.equalizeHist()实现直方图均衡化。该函数的语法格式为:

dst = cv2.equalizeHist( src )

式中:

  • dst 是直方图均衡化处理的结果。
  • src 是 8 位单通道原始图像。

示例:使用函数 cv2.equalizeHist()实现直方图均衡化。

原图:
在这里插入图片描述
代码如下:

#-----------导入使用的模块---------------
import cv2
import matplotlib.pyplot as plt
#-----------读取原始图像---------------
img = cv2.imread('equ.bmp',cv2.IMREAD_GRAYSCALE)
#-----------直方图均衡化处理---------------
equ = cv2.equalizeHist(img)
#-----------显示均衡化前后的图像---------------
cv2.imshow("original",img)
cv2.imshow("result",equ)
#-----------显示均衡化前后的直方图---------------
plt.figure("原始图像直方图") #构建窗口
plt.hist(img.ravel(),256)
plt.figure("均衡化结果直方图") #构建新窗口
plt.hist(equ.ravel(),256)
plt.show()
#----------等待释放窗口---------------------
cv2.waitKey()
cv2.destroyAllWindows()

在这里插入图片描述
结果中可以看到对比很明显:在直方图均衡化之前,图像整体比较
亮;均衡化以后,图像的亮度变得比较均衡。而两幅图像的直方图的对比,则不太明显。这实际上体现了,均衡化是指综合考虑了统计概率和 HVS 的结果。

在这里插入图片描述
在这里插入图片描述
下面做简单的说明:

  • 原始图像的直方图,大部分的像素值集中在右侧(线条密集)。这说明图像中位于[200,255]区间的像素点很多,图像比较亮。

  • 在均衡化后的直方图中,左侧的像素点比较密集而右侧的相对比较稀疏。但是,实际上人眼并不能明显感受到像素值的细微差别,所以我们可以将相近的像素值看成同一个像素值,这样就会得到类似于图 13-29 的直方图。此时,直方图内灰度级的分布就比较均衡了,是均衡一致的直方图。

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

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

相关文章

Floyd(多源汇最短路)

Floyd求最短路 给定一个 n 个点 m 条边的有向图&#xff0c;图中可能存在重边和自环&#xff0c;边权可能为负数。 再给定 k 个询问&#xff0c;每个询问包含两个整数 x 和 y&#xff0c;表示查询从点 x 到点 y 的最短距离&#xff0c;如果路径不存在&#xff0c;则输出 impo…

rabbitmq的持久化

目录 队列实现持久化 如何删除队列​编辑 消息实现持久化 不公平分发 如何保障当 RabbitMQ 服务停掉以后消息生产者发送过来的消息不丢失。默认情况下 RabbitMQ 退出或由于某种原因崩溃时&#xff0c;它忽视队列和消息&#xff0c;除非告知它不要这样做。确保消息不会丢失需…

桂林小程序https证书

现在很多APP都相继推出了小程序&#xff0c;比如微信小程序、百度小程序等&#xff0c;这些小程序的功能也越来越复杂&#xff0c;不可避免的和网站一样会传输数据&#xff0c;因此小程序想要上线就要保证信息传输的安全性&#xff0c;也就是说各种类型的小程序也需要部署https…

SAP MM学习笔记24-以评估收货(评价)和非评估收货(非评价)

SAP 中 有评价入库&#xff08;评估收货&#xff09;和非评价入库&#xff08;非评估收货&#xff09;两种入库方式。 一般来说在库品目会采用评价入库&#xff0c;而消费品目&#xff0c;会采用非评价入库。 其实评价入库&#xff0c;非评价入库对外都无所谓的&#xff0c;人…

计算机竞赛 python+opencv+机器学习车牌识别

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器学习的车牌识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;4分工作量&#xff1a;4分创新点&#xff1a;3分 该项目较为新颖&#xff0c;适…

HTTP 协议的基本格式和 fiddler 的用法

目录 一. HTTP 协议 1. HTTP协议是什么 2. HTTP协议的基本格式 HTTP请求 首行 GET和POST方法&#xff1a; 其他方法 经典面试题&#xff1a; URL Header(请求报头)部分 空行 ​HTTP响应 状态码总结: 二、Fiddler的用法 1.Fidder的安装 2.Fidder的使用 一. HTTP 协议 1. H…

日常BUG——普通页面跳转tabbar页面报错

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 微信小程序页面跳转的时候出现下面的问题&#xff1a; wx.redirectTo({url: /pages/index/i…

java 使用log4j显示到界面和文件 并格式化

1.下载log4j jar包https://dlcdn.apache.org/logging/log4j/2.20.0/apache-log4j-2.20.0-bin.zip 2. 我只要到核心包 &#xff0c;看需要 sources是源码包&#xff0c;可以看到说明。在IDEA里先加入class jar后&#xff0c;再双击这个class jar包或或右键选Navigate ,Add ,…

【贪心】CF1779 D

不会1700 Problem - 1779D - Codeforces 题意&#xff1a; 思路&#xff1a; 首先手推样例&#xff0c;可以发现一些零碎的性质&#xff1a; 然后考虑如何去计算贡献 难点在于&#xff0c;当一个区间的两端是区间max时&#xff0c;怎么去计算贡献 事实上&#xff0c;只需要…

【HttpRunnerManager】搭建接口自动化测试平台操作流程

一、需要准备的知识点 1. linux: 安装 python3、nginx 安装和配置、mysql 安装和配置 2. python: django 配置、uwsgi 配置 二、我搭建的环境 1. Centos7 &#xff08;配置 rabbitmq、mysql 、Supervisord&#xff09; 2. python 3.6.8 &#xff08;配置 django、uwsgi&…

kubernetes二进制部署2之 CNI 网络组件部署

CNI 网络组件部署 一&#xff1a;K8S提供三大接口1容器运行时接口CRI2云原生网络接口CNI3云原生存储接口CSI 部署 flannelK8S 中 Pod 网络通信&#xff1a;Overlay Network&#xff1a;VXLAN&#xff1a;Flannel:Flannel udp 模式的工作原理&#xff1a;ETCD 之 Flannel 提供说…

麒麟arm架构 编译安装qt5.14.2

1、先在官网下载qt源码&#xff1a; https://download.qt.io/archive/qt/5.14/5.14.2/single/[qt源码下载地址] 2、解压编译 使用tar -xvf qt-everywhere-src-5.14.2.tar.xz 解压压缩包 cd qt-everywhere-src-5.14.2 执行 ./configure --prefix/usr/local/qt.5.14.2 make -…

计算机竞赛 python 爬虫与协同过滤的新闻推荐系统

1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; python 爬虫与协同过滤的新闻推荐系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&…

Cpp学习——string模拟实现

目录 一&#xff0c;string的成员变量 二&#xff0c;string的各项功能函数 1.构造函数 2.析构函数 3.扩容函数 4.插入与删除数据的函数 5.运算符重载 6.打印显示函数 7&#xff0c;拷贝构造 8.find函数 一&#xff0c;string的成员变量 在模拟实现string之前&#xff…

云原生 AI 工程化实践之 FasterTransformer 加速 LLM 推理

作者&#xff1a;颜廷帅&#xff08;瀚廷&#xff09; 01 背景 OpenAI 在 3 月 15 日发布了备受瞩目的 GPT4&#xff0c;它在司法考试和程序编程领域的惊人表现让大家对大语言模型的热情达到了顶点。人们纷纷议论我们是否已经跨入通用人工智能的时代。与此同时&#xff0c;基…

二自由度机械臂的gazebo仿真

一、创建ros软件包 #1、创建工作空间 mkdir 2d_robot_ws cd 2d_robot_ws mkdir src cd src catkin_init_workspace #2、编译工作空间 cd .. catkin_make #3、创建软件包 catkin_create_pkg 2d_robot std_msgs rospy roscpp二、创建模型文件 1、编写urdf模型文件 在2d_robot_…

LLMs大模型plugin开发实战

一、概述 ChatGPT是通用语言大模型&#xff0c;如果用户想要在与大模型进行交互时能够使用到企业私有的数据&#xff0c;那么可以通过开发plugin&#xff08;插件&#xff09;的方式来实现&#xff0c;另外GPT3.5模型的训练数据是截止到2021年9月&#xff0c;如果想让模型能够…

mysql-5.5.62-win32安装与使用

1.为啥是这个版本而不是当前最新的8.0&#xff1f; 因为我要用32位。目前mysql支持win32的版本最新只到5.7.33。 首先&#xff0c;到官网MySQL :: MySQL Downloads 然后选 选一个自己喜欢的版本就好。我这里是如标题版本。下载32位的zip。然后回来解压。 完了创建系统环境变…

29 深度玻尔兹曼机

文章目录 29 深度玻尔兹曼机29.1 背景介绍29.2 DBM的叠加方式 29 深度玻尔兹曼机 29.1 背景介绍 过去在解决BM问题的时候&#xff0c;提出过多种模型&#xff1a;RBM、SBN、DBN 其中RBM是一种有限制条件的&#xff0c;简化的BM&#xff0c;限制了隐藏层和观测层内部都没有连…

【数据结构OJ题】移除链表元素

原题链接&#xff1a;https://leetcode.cn/problems/remove-linked-list-elements/description/ 1. 题目描述 2. 思路分析 我们可以定义一个结构体指针变量cur&#xff0c;让cur一开始指向头结点&#xff0c;同时定义一个结构体指针prev&#xff0c;令prev初始化为空指针NULL…