使用opencv操作直方图需要进行的两个步骤:

  1. 统计直方图
  2. 显示直方图

直方图

什么是直方图呢?通过直方图你可以对整幅图像的灰度分布有一个整体的 了解。直方图的 x 轴是灰度值(0 到 255),y 轴是图片中具有同一个灰度值的 点的数目

什么是直方图

通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值(0 到 255),y 轴是图片中具有同一个灰度值的点的数目

Opencv中统计直方图的使用

参考链接:https://www.cnblogs.com/Undo-self-blog/p/8439149.html

BINS:上面的直方图显示了每个灰度值对应的像素数。如果像素值为 0到 255,你就需要 256 个数来显示上面的直方图。但是,如果你不需要知道每一个像素值的像素点数目的,而只希望知道两个像素值之间的像素点数目怎么办呢?举例来说,我们想知道像素值在 0 到 15 之间的像素点的数目,接着是 16 到 31,....,240 到 255。我们只需要 16 个值来绘制直方图。OpenCVTutorials on histograms中例子所演示的内容。 那到底怎么做呢?你只需要把原来的 256 个值等分成 16 小组,取每组的总和。而这里的每一个小组就被成为 BIN。第一个例子中有 256 个 BIN,第二个例子中有 16 个 BIN。在 OpenCV 的文档中用 histSize 表示 BINS

DIMS:表示我们收集数据的参数数目。在本例中,我们对收集到的数据只考虑一件事:灰度值。所以这里就是 1。   RANGE:就是要统计的灰度值范围,一般来说为 [0,256],也就是说所有的灰度值
使用 OpenCV 统计直方图 函数 cv2.calcHist 可以帮助我们统计一幅图像的直方图

可以帮助我们统计一幅图像的直方图。我们一起来熟悉一下这个函数和它的参数:

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

  1. images: 原图像(图像格式为 uint8 或 float32)。当传入函数时应该用中括号 [] 括起来,例如:[img]。
  2. channels: 同样需要用中括号括起来,它会告诉函数我们要统计那幅图像的直方图。如果输入图像是灰度图,它的值就是 [0];如果是彩色图像的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。
  3. mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并使用它。(后边有例子)
  4. histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。
  5. ranges: 像素值范围,通常为 [0,256]

直方图的绘制包括最核心的两步:统计直方图,绘制直方图

使用opencv 统计直方图

函数 cv2.calcHist 可以帮助我们统计一幅图像 的直方图

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

返回值:返回的hist 是一个 256x1 的数组,每一个值代表了与次灰度值对应的像素点数 目

参数解释:

  1. images: 原图像(图像格式为 uint8 或 float32)。当传入函数时应该 用中括号 [] 括起来,例如:[img]。

  2. channels: 同样需要用中括号括起来,它会告诉函数我们要统计那幅图 像的直方图。如果输入图像是灰度图,它的值就是 [0];如果是彩色图像 的话,传入的参数可以是 [0],[1],[2] 它们分别对应着通道 B,G,R。

  3. mask: 掩模图像。要统计整幅图像的直方图就把它设为 None。但是如 果你想统计图像某一部分的直方图的话,你就需要制作一个掩模图像,并 使用它。(后边有例子)

  4. histSize:BIN 的数目。也应该用中括号括起来,例如:[256]。

  5. ranges: 像素值范围,通常为 [0,256]

image.ravel() 将图像转换成一维数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
"""
@File : opencv统计直方图.py

@Author: sivan Wu

@Date : 2020/1/12 4:07 下午

@Desc :

"""


import cv2
import matplotlib.pyplot as plt
image = cv2.imread("../data/angela.jpeg", cv2.IMREAD_GRAYSCALE)

## 使用opencv 统计直方图函数
## 返回的hist 是一个 256x1 的数组,每一个值代表了与次灰度值对应的像素点数 目
hist = cv2.calcHist([image], [0], None, [256], [0, 256])
print(hist)
plt.plot(hist)
plt.show()

使用numpy统计直方图

Numpy 还 有 一 个 函 数 np.bincount(), 它 的 运 行 速 度 是 np.histgram 的 十 倍。 所 以 对 于 一 维 直 方 图, 我 们 最 好 使 用 这 个 函 数。 使 用 np.bincount 时 别 忘 了 设 置 minlength=256。 例 如, hist=np.bincount(img.ravel(),minlength=256)

注意:OpenCV 的函数要比 np.histgram() 快 40 倍。 所以坚持使用 OpenCV 函数。

例子:Numpy 中的函数 np.histogram() 也可以帮我们统计直方图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
"""
@File : numpy统计直方图.py

@Author: sivan Wu

@Date : 2020/1/12 4:13 下午

@Desc :

"""

import cv2
import numpy as np
import matplotlib.pyplot as plt
image = cv2.imread("../data/angela.jpeg")
hist = np.histogram(image.ravel(), 256, [0, 256])
plt.show()
print(hist)
print(len(hist))

使用opencv绘制直方图

由于步骤比较繁琐,参考

使用matlotlib绘制直方图

绘制灰度的直方图

包括如下3部分内容:

  1. opencv统计直方图和matplotlib显示
  2. numpy.bincount()统计直方图和matplotlib显示
  3. numpy.histogram()统计直方图和matplotlib显示

Numpy 还 有 一 个 函 数 np.bincount(), 它 的 运 行 速 度 是 np.histgram 的 十 倍。 所 以 对 于 一 维 直 方 图, 我 们 最 好 使 用 这 个 函 数。 使 用 np.bincount 时 别 忘 了 设 置 minlength=256。 例 如, hist=np.bincount(img.ravel(),minlength=256)

注意:OpenCV 的函数要比 np.histgram() 快 40 倍。 所以坚持使用OpenCV函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
"""
@File : matplotlib绘制灰色图的直方图.py

@Author: sivan Wu

@Date : 2020/1/12 4:20 下午

@Desc :

"""

import cv2
import matplotlib.pyplot as plt

image = cv2.imread("../data/angela.jpeg", cv2.IMREAD_GRAYSCALE)

## 使用opencv 统计直方图函数 和 matplotlib显示
## 返回的hist 是一个 256x1 的数组,每一个值代表了与次灰度值对应的像素点数 目
hist = cv2.calcHist([image], [0], None, [256], [0, 256])
print(hist)
plt.plot(hist)
plt.show()

import numpy as np

## 使用numpy统计直方图函数np.bincount() 和 matplotlib显示
image = cv2.imread("../data/angela.jpeg", cv2.IMREAD_GRAYSCALE)
hist2 = np.bincount(image.ravel(), minlength=256)
print(len(hist2)) # 256
print(type(hist2)) # <class 'numpy.ndarray'>
plt.plot(hist2)
plt.show()

## 使用numpy统计直方图函数np.histogram() 和 matplotlib显示
hist, bins = np.histogram(image.ravel(), 256, [0, 256])
print(type(hist))
print(len(hist))
plt.plot(hist)
plt.show()

绘制彩色图的直方图

绘制彩色图在不同颜色通道下的直方图

例如:绘制彩色图对应BGR三个颜色通道的直方图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

"""
@File : matplotlib绘制彩色图的直方图.py

@Author: sivan Wu

@Date : 2020/1/12 4:20 下午

@Desc :

"""

import cv2
import matplotlib.pyplot as plt

image = cv2.imread("../data/angela.jpeg")

color = ['b', 'g', 'r']
# 绘制彩色图不同通道的直方图
for i, col in enumerate(color):
hist = cv2.calcHist([image], [i], None, [256], [0, 256])
plt.plot(hist, color=col)
plt.xlim([0, 256]) # 包括256
plt.show()

参考

更多资源