2. 彩色图像各通道直方图统计

任务说明

读取一张彩色图像,分别统计R、G、B三个通道的像素强度分布(0~255共256个灰度级),将三条直方图曲线绘制在同一坐标系中,用于观察图像的整体色彩倾向与各通道动态范围。本案例使用OpenCV读取图像、NumPy完成统计、Matplotlib完成可视化。

实现代码


import cv2
import numpy as np
import matplotlib.pyplot as plt

# 读取彩色图像(BGR顺序)
img = cv2.imread('sample.jpg')
if img is None:
    raise FileNotFoundError('未找到图像文件 sample.jpg')

# 拆分通道并计算直方图(256个bin,范围0~255)
channels = ['B', 'G', 'R']
hist_data = {}
for i, name in enumerate(channels):
    hist = cv2.calcHist([img], [i], None, [256], [0, 256])
    hist_data[name] = hist.flatten()

# 在同一坐标系中绘制三条直方图曲线
x = np.arange(256)
plt.figure(figsize=(10, 5))
plt.plot(x, hist_data['B'], color='blue', label='Blue (B)', linewidth=1)
plt.plot(x, hist_data['G'], color='green', label='Green (G)', linewidth=1)
plt.plot(x, hist_data['R'], color='red', label='Red (R)', linewidth=1)
plt.title('RGB Channel Histograms')
plt.xlabel('Pixel Intensity (0-255)')
plt.ylabel('Pixel Count')
plt.legend()
plt.grid(alpha=0.3)
plt.xlim([0, 255])
plt.tight_layout()
plt.savefig('rgb_histogram.png', dpi=150)
plt.show()

# 打印各通道均值与标准差,辅助分析色彩分布
for i, name in enumerate(channels):
    mean_val = np.mean(img[:, :, i])
    std_val = np.std(img[:, :, i])
    print(f'{name} channel: mean={mean_val:.2f}, std={std_val:.2f}')

运行方式

安装依赖:pip install opencv-python numpy matplotlib。将待分析的彩色图像命名为sample.jpg并置于脚本同目录,执行脚本即可。程序会弹出直方图窗口,同时将图像保存为rgb_histogram.png。

验证方法

观察生成的直方图:横轴为像素强度0~255,纵轴为该强度下的像素数量。三条曲线分别对应B、G、R通道。若图像整体偏红,则R通道曲线峰值集中在高亮度区且均值明显高于B、G通道;若图像偏暗,则三条曲线均集中在低亮度区。控制台输出的各通道均值与标准差可量化验证上述观察——均值反映整体亮度倾向,标准差反映对比度强弱。判定标准:三条曲线与均值输出能正确反映图像的实际色彩观感,且曲线形态与图像内容相符(如蓝天图像B通道高亮度区像素数显著多于R通道)。

RGB通道直方图统计流程 彩色图像 sample.jpg BGR三通道 通道拆分 img[:,:,0] → B img[:,:,1] → G img[:,:,2] → R 直方图统计 calcHist 256 bins 范围 [0, 256) 每通道256个计数 叠加绘制 B/G/R三曲线 同一坐标系 输出png 输出直方图示意(同一坐标系三条曲线) 像素强度 (0-255) 像素数 0 64 128 192 255 B通道 G通道 R通道 R峰值 B峰值 通过峰值位置与曲线形态判断色彩倾向:R峰值偏右表示图像偏红,B峰值偏左表示蓝色成分少