目录
引言:
OpenCV库中的直方图是一个非常有用的工具,用于图像处理和计算机视觉任务。直方图在图像处理中主要用于表示图像中像素值的分布情况。通过分析直方图,我们可以得到图像的许多有用信息,例如亮度分布、对比度和颜色分布等。
直方图的作用
-
图像增强:通过直方图均衡化,可以增强图像的对比度,使图像更清晰。
-
图像分割:直方图可以帮助确定阈值,用于将图像分割成不同的区域。
-
特征提取:在对象检测和识别中,直方图可以作为特征来描述图像的某些特征,例如颜色直方图可以用于图像检索。
-
图像匹配:通过比较两幅图像的直方图,可以实现图像的匹配和相似度计算。
绘制图像的分布直方图
绘制图像的黑白像素频率直方图
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 读取图像并转换为灰度图像
img = cv2.imread(r'C:\Users\35173\Desktop\tg.png', cv2.IMREAD_GRAYSCALE)
# 计算直方图
hist = cv2.calcHist([img], [0], None, [256], [0, 256])
# 绘制直方图
plt.bar(range(256), hist[:, 0], width=1.0, edgecolor='black')
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定中文字体为宋体
plt.rcParams['axes.unicode_minus'] = False
plt.title('灰度直方图')
plt.xlabel('像素值')
plt.ylabel('频率')
plt.show()
代码解读:
步骤 | 操作 | 解释 |
---|---|---|
读取图像 | img = cv2.imread(r'C:\Users\35173\Desktop\tg.png', cv2.IMREAD_GRAYSCALE) | 使用cv2.imread() 函数读取图像,并将其转换为灰度图像。 |
计算直方图 | hist = cv2.calcHist([img], [0], None, [256], [0, 256]) | 使用cv2.calcHist() 函数计算灰度图像的直方图。 |
绘制直方图 | plt.bar(range(256), hist[:, 0], width=1.0, edgecolor='black') | 使用plt.bar() 函数绘制柱状图,其中range(256) 表示像素值的范围(0-255),hist[:, 0] 表示各个像素值的频率。 |
设置柱子宽度 | width=1.0 | 设置柱子的宽度为1.0。 |
设置边框颜色 | edgecolor='black' | 设置柱子的边框颜色为黑色。 |
设置中文字体和负号显示 | plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False | plt.rcParams 用于设置绘图的全局参数,确保标题和标签可以显示中文,并正确显示负号。 |
显示图像 | plt.show() | 使用plt.show() 函数显示绘制的直方图。 |
最后, 这段代码将生成一个直方图,展示图像中每个灰度值的频率,柱状图的形式更适合展示直方图数据的分布情况。
结果如下图所示:
绘制彩色分别直方图的代码
import cv2
import numpy as np
from matplotlib import pyplot as plt
# 读取彩色图像
img = cv2.imread(r'C:\Users\35173\Desktop\tg.png')
# 分离图像的三个通道
color = ('b', 'g', 'r')
for i, col in enumerate(color):
hist = cv2.calcHist([img], [i], None, [256], [0, 256])
plt.bar(range(256), hist[:, 0], color=col, alpha=0.6, label=col, edgecolor='black')
plt.rcParams['font.sans-serif'] = ['SimHei'] # 指定中文字体为宋体
plt.rcParams['axes.unicode_minus'] = False
plt.title('彩色直方图')
plt.xlabel('像素值')
plt.ylabel('频率')
plt.show()
代码解读如下表格所示
步骤 | 操作 | 解释 |
---|---|---|
读取图像 | img = cv2.imread(r'C:\Users\35173\Desktop\tg.png') | 使用cv2.imread() 函数读取彩色图像。 |
分离图像的三个通道 | color = ('b', 'g', 'r') <br> for i, col in enumerate(color): | 定义颜色通道顺序,并使用enumerate 遍历每个通道。 |
计算直方图 | hist = cv2.calcHist([img], [i], None, [256], [0, 256]) | 使用cv2.calcHist() 函数计算每个通道的直方图。 |
绘制直方图 | plt.bar(range(256), hist[:, 0], color=col, alpha=0.6, label=col, edgecolor='black') | 使用plt.bar() 函数绘制柱状图。<br>range(256) 表示像素值范围(0-255)。<br>hist[:, 0] 表示各个像素值的频率。<br>color=col 设置柱子的颜色为当前通道的颜色。<br>alpha=0.6 设置透明度,使多个通道的柱状图可以重叠显示。<br>label=col 设置图例标签为当前通道的颜色。<br>edgecolor='black' 设置柱子的边框颜色为黑色。 |
设置中文字体和负号显示 | plt.rcParams['font.sans-serif'] = ['SimHei'] <br> plt.rcParams['axes.unicode_minus'] = False | plt.rcParams 用于设置绘图的全局参数,确保标题和标签可以显示中文,并正确显示负号。 |
设置标题和标签 | plt.title('彩色直方图') <br> plt.xlabel('像素值') <br> plt.ylabel('频率') | 使用plt.title() 设置标题,使用plt.xlabel() 和plt.ylabel() 设置X轴和Y轴标签。 |
显示图像 | plt.show() | 使用plt.show() 函数显示绘制的直方图。 |
最后绘制出来一个彩色像素点的分布直方图,如下图所示: