Python中5张图像RGB颜色分布的简易对比方法求助
简易对比多张图像RGB颜色分布的方法
核心思路
不用像素级比对,直接通过RGB通道直方图的可视化+简单量化指标就能快速判断颜色分布和频次的差异,适合新手快速上手。
步骤1:用Pillow提取每张图像的RGB直方图
Pillow的Image.histogram()方法会直接返回一个长度为768的数组:前256个元素是红色通道的频次(对应0-255亮度值),中间256个是绿色通道,最后256个是蓝色通道。
示例代码:
from PIL import Image # 替换成你的5张图片路径列表 image_paths = ["img1.jpg", "img2.jpg", "img3.jpg", "img4.jpg", "img5.jpg"] histograms = [] for path in image_paths: with Image.open(path) as img: # 统一转为RGB格式,避免灰度图/RGBA格式干扰 rgb_img = img.convert("RGB") # 获取直方图并拆分RGB三个通道 full_hist = rgb_img.histogram() r_hist = full_hist[:256] g_hist = full_hist[256:512] b_hist = full_hist[512:] histograms.append((r_hist, g_hist, b_hist))
步骤2:可视化对比(最直观)
用Matplotlib把所有图像的同一通道直方图画在同一张图里,一眼就能看出分布差异——比如红色通道的曲线重叠度、峰值位置、分布宽度的区别。
示例代码:
import matplotlib.pyplot as plt # 自定义标签,方便区分不同图像 img_labels = ["图1", "图2", "图3", "图4", "图5"] channel_names = ["红色", "绿色", "蓝色"] # 分别绘制三个通道的对比图 for channel_idx in range(3): plt.figure(figsize=(10, 5)) for img_idx in range(len(histograms)): # 获取当前图像对应通道的直方图数据 current_hist = histograms[img_idx][channel_idx] plt.plot(range(256), current_hist, label=img_labels[img_idx], alpha=0.6) plt.title(f"{channel_names[channel_idx]}通道颜色分布对比") plt.xlabel("颜色亮度值(0-255)") plt.ylabel("像素出现频次") plt.legend() plt.show()
如果两张图颜色分布相似,曲线会几乎重叠;若差异明显,曲线的形状、峰值位置会有显著区别。
步骤3:简单量化差异(可选)
如果需要用数值量化差异,可以计算直方图的余弦相似度(值越接近1越相似)或均方误差(值越小越相似)。这里以余弦相似度为例:
示例代码:
from scipy.spatial.distance import cosine # 以第一张图为基准,对比其余图像的相似度 base_r, base_g, base_b = histograms[0] for idx in range(1, len(histograms)): r_sim = 1 - cosine(base_r, histograms[idx][0]) g_sim = 1 - cosine(base_g, histograms[idx][1]) b_sim = 1 - cosine(base_b, histograms[idx][2]) avg_sim = (r_sim + g_sim + b_sim) / 3 print(f"图1 vs 图{idx+1}:平均颜色分布相似度 = {avg_sim:.4f}")
平均相似度接近1说明分布差异极小;远小于1则说明颜色分布存在明显不同。
注意事项
- 所有图像统一转为RGB格式,避免灰度图、RGBA格式的干扰。
- 如果图像尺寸差异过大,可先resize到相同尺寸再提取直方图,减少像素数量差异带来的频次偏差(可选,根据需求决定)。
内容的提问来源于stack exchange,提问作者BeatriceD1995
相关产品推荐
相关产品推荐

