在图像处理中,直方图是一种非常重要的工具,它可以帮助我们了解图像的像素分布情况。
通过分析图像的直方图,我们可以进行图像增强、对比度调整、图像分割等操作。
什么是图像直方图?
图像直方图是图像像素强度分布的图形表示,对于灰度图像,直方图显示了每个灰度级(0到255)在图像中出现的频率,对于彩色图像,我们可以分别计算每个通道(如R、G、B)的直方图。
直方图可以帮助我们了解图像的亮度、对比度等信息。例如,如果直方图集中在低灰度区域,说明图像偏暗;如果直方图分布均匀,说明图像对比度较好。
直方图: 表示图像中像素强度的分布情况,横轴表示像素强度值,纵轴表示该强度值的像素数量。
灰度直方图: 针对灰度图像的直方图,表示每个灰度级的像素数量。
颜色直方图: 针对彩色图像的直方图,分别表示每个颜色通道(如 BGR)的像素强度分布。
OpenCV 提供了丰富的直方图计算和操作函数:
OpenCV 中的直方图计算函数
在 OpenCV 中,我们可以使用 cv2.calcHist() 函数来计算图像的直方图。
cv2.calcHist() 函数语法
cv2 . calcHist ( images , channels , mask , histSize , ranges [, hist [, accumulate ]])
参数说明
images: 输入的图像列表,通常是一个包含单通道或多通道图像的列表。例如 [img]。
channels: 需要计算直方图的通道索引。对于灰度图像,使用 [0];对于彩色图像,可以使用
[0]、[1]、[2] 分别计算蓝色、绿色和红色通道的直方图。
mask: 掩码图像。如果指定了掩码,则只计算掩码区域内的像素。如果不需要掩码,可以传入 None。
histSize: 直方图的 bin 数量。对于灰度图像,通常设置为 [256],表示将灰度级分为
256 个 bin。
ranges: 像素值的范围。对于灰度图像,通常设置为 [0, 256],表示像素值的范围是
0 到 255。
hist: 输出的直方图数组。
accumulate: 是否累积直方图。如果设置为 True,则直方图不会被清零,而是在每次调用时累积。
假设我们有一张灰度图像 img,我们可以使用以下代码计算其直方图:
实例
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取图像
img = cv2.imread ( 'image.jpg' , cv2.IMREAD_GRAYSCALE )
# 计算直方图
hist = cv2.calcHist ( [ img] , [ 0 ] , None , [ 256 ] , [ 0 , 256 ] )
# 绘制直方图
plt.plot ( hist)
plt.title ( 'Grayscale Histogram' )
plt.xlabel ( 'Pixel Value' )
plt.ylabel ( 'Frequency' )
plt.show ( )
直方图均衡化
直方图均衡化是一种增强图像对比度的方法,通过重新分配像素强度值,使直方图更加均匀。
语法:
equalized_image = cv2 . equalizeHist ( image )
实例
# 直方图均衡化
equalized_image = cv2.equalizeHist ( image)
# 显示结果
cv2.imshow ( "Equalized Image" , equalized_image)
cv2.waitKey ( 0 )
cv2.destroyAllWindows ( )
颜色直方图
计算颜色直方图
对于彩色图像,可以分别计算每个颜色通道的直方图。
实例
# 读取彩色图像
image = cv2.imread ( "path/to/image" )
# 计算 BGR 各通道的直方图
colors = ( 'b' , 'g' , 'r' )
for i, color in enumerate ( colors) :
hist = cv2.calcHist ( [ image] , [ i] , None , [ 256 ] , [ 0 , 256 ] )
plt.plot ( hist, color= color)
# 绘制直方图
plt.title ( "Color Histogram" )
plt.xlabel ( "Pixel Intensity" )
plt.ylabel ( "Pixel Count" )
plt.show ( )
颜色直方图均衡化
对于彩色图像,可以对每个通道分别进行直方图均衡化。
实例
# 分离通道
b, g, r = cv2.split ( image)
# 对每个通道进行直方图均衡化
b_eq = cv2.equalizeHist ( b)
g_eq = cv2.equalizeHist ( g)
r_eq = cv2.equalizeHist ( r)
# 合并通道
equalized_image = cv2.merge ( [ b_eq, g_eq, r_eq] )
# 显示结果
cv2.imshow ( "Equalized Color Image" , equalized_image)
cv2.waitKey ( 0 )
cv2.destroyAllWindows ( )
直方图比较
OpenCV 提供了 cv2.compareHist() 函数,用于比较两个直方图的相似度。
语法:
similarity = cv2 . compareHist ( hist1 , hist2 , method )
hist1: 第一个直方图。
hist2: 第二个直方图。
method: 比较方法,例如 cv2.HISTCMP_CORREL(相关性比较)。
实例
# 计算两个图像的直方图
hist1 = cv2.calcHist ( [ image1] , [ 0 ] , None , [ 256 ] , [ 0 , 256 ] )
hist2 = cv2.calcHist ( [ image2] , [ 0 ] , None , [ 256 ] , [ 0 , 256 ] )
# 比较直方图
similarity = cv2.compareHist ( hist1, hist2, cv2.HISTCMP_CORREL )
print ( "Histogram Similarity:" , similarity)
直方图的应用
图像增强: 通过直方图均衡化,可以增强图像的对比度,使细节更加清晰。
图像分割: 过分析直方图,可以确定阈值,用于图像分割。
图像匹配: 通过比较直方图,可以判断两幅图像的相似度,用于图像匹配和检索。
颜色分析: 通过颜色直方图,可以分析图像的颜色分布,用于颜色校正和风格化处理。
以下是一个完整的直方图计算和均衡化示例代码:
实例
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 读取灰度图像
image = cv2.imread ( "path/to/image" , cv2.IMREAD_GRAYSCALE )
# 计算灰度直方图
hist = cv2.calcHist ( [ image] , [ 0 ] , None , [ 256 ] , [ 0 , 256 ] )
# 绘制直方图
plt.plot ( hist)
plt.title ( "Grayscale Histogram" )
plt.xlabel ( "Pixel Intensity" )
plt.ylabel ( "Pixel Count" )
plt.show ( )
# 直方图均衡化
equalized_image = cv2.equalizeHist ( image)
# 显示结果
cv2.imshow ( "Equalized Image" , equalized_image)
cv2.waitKey ( 0 )
cv2.destroyAllWindows ( )