Python图像处理丨如何调用OpenCV绘制直方图

摘要:本篇文章主要讲解灰度直方图的基本概念,Python调用OpenCV实现绘制图像直方图。

本文分享自华为云社区《​​[Python图像处理] 十一.灰度直方图概念及OpenCV绘制直方图​​》,作者:eastmount。

一. 灰度直方图基本概念

什么是灰度直方图?

灰度直方图(histogram)是灰度级的函数,描述的是图像中每种灰度级像素的个数,反映图像中每种灰度出现的频率。横坐标是灰度级,纵坐标是灰度级出现的频率。

Python图像处理丨如何调用OpenCV绘制直方图

对于连续图像,它从中心的高灰度平滑地变化到边缘的低灰度。直方图定义为:

[En]

For continuous images, it changes smoothly from a high grayscale in the center to a low grayscale at the edge. The histogram is defined as:

Python图像处理丨如何调用OpenCV绘制直方图

其中A(D)为阈值面积函数:为一幅连续图像中被具有灰度级D的所有轮廓线所包围的面积。对于离散函数,固定ΔD为1,则:H(D)=A(D)-A(D+1)。

色彩直方图是高维直方图的特例,它统计色彩的出现频率,即色彩概率分布信息。通常这需要一定的量化过程,将色彩分成若干互不重叠的种类。一般不直接在RGB色彩空间中统计,而是在将亮度分离出来后,对代表色彩部分的信息进行统计,如在HSI空间的HS子空间、YUV空间的UV子空间,以及其它反映人类视觉特点的彩色空间表示中进行。

直方图的计算方法如下:

依据定义,若图像具有L(通常L=256,即8位灰度级)级灰度,则大小为MxN的灰度图像f(x,y)的灰度直方图hist[0…L-1]可用如下计算获得。

1、初始化 hist[k]=0; k=0,…,L-1
2、统计 hist[f(x,y)]++; x=0,…,M-1, y =0,…,N-1
3、归一化 hist[f(x,y)]/=M*N

那么,在说了这么多之后,直方图有什么用呢?

[En]

So after all that has been said, what is the use of histograms?

在使用轮廓线确定物体边界时,通过直方图更好的选择边界阈值,进行阈值化处理;对物体与背景有较强对比的景物的分割特别有用;简单物体的面积和综合光密度IOD可以通过图像的直方图求得。

二. 绘制直方图

1.基础概念

在直方图中,横坐标表示图像中每个像素的灰度级,纵坐标表示具有该灰度级的像素数。

[En]

In the histogram, the Abscissa represents the gray level of each pixel in the image, and the ordinate represents the number of pixels with that gray level.

Python图像处理丨如何调用OpenCV绘制直方图

假设存在一个3*3的图像,如下图所示,x数组统计的是像素点的灰度级,y数组统计的是具有该灰度级的像素个数。其中,灰度为1的像素共3个,灰度为2的像素共1个,灰度为3的像素共2个,灰度为4的像素共1个,灰度为5的像素共2个。

x = [1, 2, 3, 4, 5]
y = [3, 1, 2, 1, 2]

绘制的折线图如下所示:

Python图像处理丨如何调用OpenCV绘制直方图

绘制的直方图如下所示:

Python图像处理丨如何调用OpenCV绘制直方图

如果灰度级为0-255(最小值0黑色,最大值255白色),同样可以绘制对应的直方图,下图是三张图片拼接而成及其对应的直方图。

Python图像处理丨如何调用OpenCV绘制直方图

2.归一化直方图

直方图的横坐标表示图像中每个像素的灰度级,纵坐标表示该灰度级的概率。计算方法如下:

[En]

The Abscissa of the histogram represents the gray level of each pixel in the image, and the ordinate represents the probability of this gray level. The calculation method is as follows:

(1) 先计算灰度级及对应像素的个数
x = [1, 2, 3, 4, 5]
t = [3, 1, 2, 1, 2]

(2) 统计总的像素个数
n = (3 + 1 + 2 + 1 +2) = 9

(3) 统计各个灰度级的出现概率
y = t / n = [3/9, 1/9, 2/9, 1/9, 2/9]

Python图像处理丨如何调用OpenCV绘制直方图

3.绘制直方图

主要调用matplotlib的子库pyplot实现,它提供了类似于Matlab的绘图框架,matplotlib是非常强大基础的一个Python绘图包。Provides a Matlab-like plotting framework. 导入代码如下:

import matplotlib.pyplot as plt

其中绘制直方图主要调用hist函数实现,它根据数据源和像素级绘制直方图。函数原型如下:

hist(数据源, 像素级)参数:数据源必须是一维数组,通常需要通过函数ravel()拉直图像像素级一般是256,表示[0, 255]

Python图像处理丨如何调用OpenCV绘制直方图

函数ravel()将多维数组降为一维数组,格式为:

一维数组 = 多维数组.ravel()

Python图像处理丨如何调用OpenCV绘制直方图

4.代码实现

#encoding:utf-8import cv2  import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread('test01.jpg')cv2.imshow("src", src)cv2.waitKey(0)cv2.destroyAllWindows()plt.hist(src.ravel(), 256)plt.show()

输出结果如下所示:

Python图像处理丨如何调用OpenCV绘制直方图

Python图像处理丨如何调用OpenCV绘制直方图

三. 使用OpenCV统计绘制直方图

1.函数原型

前面讲解调用matplotlib库绘制直方图,接下来讲解使用OpenCV统计绘制直方图的例子。

直方图横坐标:图像中每个像素的灰度

[En]

Histogram Abscissa: the grayscale of each pixel in an image

直方图纵坐标:该灰度级的像素数

[En]

Histogram ordinate: the number of pixels with this gray level

Python图像处理丨如何调用OpenCV绘制直方图

主要调用函数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=3表示三个灰度级

Python图像处理丨如何调用OpenCV绘制直方图

Python图像处理丨如何调用OpenCV绘制直方图
  • ranges表示像素值范围,例如[0, 255]
  • accumulate表示累计叠加标识,默认为false,如果被设置为true,则直方图在开始分配时不会被清零,该参数允许从多个对象中计算单个直方图,或者用于实时更新直方图;多个直方图的累积结果用于对一组图像的直方图计算

Python图像处理丨如何调用OpenCV绘制直方图

2.代码实现

首先,计算图像的基本大小、形状和灰度级的内容。

[En]

First of all, the basic size, shape and content of the gray level of the image are calculated.

#encoding:utf-8import cv2  import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread('test01.jpg')#参数:原图像 通道[0]-B 掩码 BINS为256 像素范围0-255 hist = cv2.calcHist([src], [0], None, [256], [0,255])print(type(hist))print(hist.size)print(hist.shape)print(hist)

输出结果如下所示:

Python图像处理丨如何调用OpenCV绘制直方图

下面是绘制图像的代码,首先补充一些matplotlib库绘制图像代码,也推荐我的文章。
​[Python数据挖掘课程] 六.Numpy、Pandas和Matplotlib包基础知识​

#encoding:utf-8import cv2  import numpy as npimport matplotlib.pyplot as plt#绘制sin函数曲线x1 = np.arange(0, 6, 0.1)y1 = np.sin(x1)plt.plot(x1, y1)#绘制坐标点折现x2 = [0, 1, 2, 3, 4, 5, 6]y2 = [0.3, 0.4, 2.5, 3.4, 4, 5.8, 7.2]plt.plot(x2, y2)#省略有规则递增的x2参数 y3 = [0, 0.5, 1.5, 2.4, 4.6, 8]plt.plot(y3, color="r")plt.show()

输出有三行,如下所示:

[En]

The output has three lines, as shown below:

Python图像处理丨如何调用OpenCV绘制直方图

最后给出调用calcHist()计算B、G、R灰度级并绘制图形的代码。

#encoding:utf-8import cv2  import numpy as npimport matplotlib.pyplot as pltsrc = cv2.imread('test01.jpg')histb = cv2.calcHist([src], [0], None, [256], [0,255])histg = cv2.calcHist([src], [1], None, [256], [0,255])histr = cv2.calcHist([src], [2], None, [256], [0,255])cv2.imshow("src", src)cv2.waitKey(0)cv2.destroyAllWindows()plt.plot(histb, color='b')plt.plot(histg, color='g')plt.plot(histr, color='r')plt.show()

输出结果如下图所示:

Python图像处理丨如何调用OpenCV绘制直方图

Python图像处理丨如何调用OpenCV绘制直方图

点击关注,第一时间了解华为云新鲜技术~

Original: https://blog.51cto.com/u_15214399/5548199
Author: 华为云开发者联盟
Title: Python图像处理丨如何调用OpenCV绘制直方图

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/504451/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球