3. 直方图特征分析

直方图不只是个“图”。它背后藏着一堆数字特征,能告诉你图像的亮度分布、对比度强弱、纹理复杂程度。说白了,这些统计量就是图像的“体检报告”。

我个人习惯,拿到一张图先算这六个指标。它们能帮我快速判断:这张图是不是过曝了?是不是雾蒙蒙的?有没有细节可以挖?

3.1 均值(Mean)—— 图像的整体亮度

均值就是所有像素灰度的平均值。公式很简单:

μ = (1 / N) * Σ_{i=0}^{L-1} i * p(i)

其中 p(i) 是灰度 i 出现的概率,N 是总像素数,L 是灰度级数(通常是 256)。

  • 均值偏小(< 80):图像偏暗,细节可能藏在暗部。
  • 均值适中(80~170):亮度正常,视觉舒适。
  • 均值偏大(> 170):图像偏亮,高光区域可能过曝。
我的经验: 均值只能反映“整体亮度”,不能说明对比度。一张灰蒙蒙的图和一张高对比的图,均值可能一模一样。所以别只看均值。

3.2 方差(Variance)—— 对比度的度量

方差衡量像素值偏离均值的程度。对比度越高,方差越大。

σ² = Σ_{i=0}^{L-1} (i - μ)² * p(i)

标准差 σ 是方差的平方根,单位与灰度一致,更直观。

方差范围 对比度描述 典型场景
< 1000 低对比度,图像模糊 雾天、水下、老照片
1000 ~ 4000 中等对比度,正常 日常拍摄、监控画面
> 4000 高对比度,层次分明 强光下、艺术摄影
注意: 方差过大不一定好。我曾经处理过一张工业检测图,方差很高,但暗部完全死黑、亮部完全过曝——细节全丢了。高方差不等于高质量。

3.3 偏度(Skewness)—— 亮度分布的对称性

偏度告诉你直方图是“左偏”还是“右偏”。

Skewness = (1 / σ³) * Σ_{i=0}^{L-1} (i - μ)³ * p(i)
  • 偏度 > 0(右偏):直方图左侧有长尾,图像偏暗,暗部细节丰富。
  • 偏度 < 0(左偏):直方图右侧有长尾,图像偏亮,高光区域多。
  • 偏度 ≈ 0:直方图对称,亮度分布均匀。

为什么会这样?你想想看,如果大部分像素集中在暗部,少数像素在亮部,直方图就会向右拖出一条尾巴——这就是正偏度。

实用技巧: 偏度值 > 1 时,图像大概率存在曝光问题。这时候直方图均衡化往往效果不错。

3.4 峰度(Kurtosis)—— 分布的“尖峭”程度

峰度衡量直方图是“尖峰”还是“扁平”。

Kurtosis = (1 / σ⁴) * Σ_{i=0}^{L-1} (i - μ)⁴ * p(i) - 3

这里减 3 是为了让正态分布的峰度为 0,方便比较。

  • 峰度 > 0(尖峰):像素集中在少数灰度级,图像纹理单一,比如纯色背景。
  • 峰度 < 0(平峰):像素分布分散,纹理丰富,细节多。
  • 峰度 ≈ 0:接近正态分布,自然图像常见。

我记得有一次做医学图像分析,CT 图像的峰度特别高——因为大部分像素集中在骨骼和空气两个灰度区间。这时候做增强,得小心别把噪声也放大了。

3.5 能量(Energy)—— 灰度分布的集中度

能量是各灰度概率的平方和。它反映直方图的“纯净度”。

Energy = Σ_{i=0}^{L-1} [p(i)]²
  • 能量高(接近 1):少数灰度级占主导,图像简单,比如二值图。
  • 能量低(接近 0):灰度分布均匀,图像复杂,纹理丰富。
避坑指南: 我曾经把能量和熵搞混过。记住:能量看“集中度”,熵看“混乱度”。两者是互补关系,不是一回事。

3.6 熵(Entropy)—— 图像的信息量

熵来自信息论,衡量直方图的不确定性。熵越大,图像包含的信息越丰富。

Entropy = - Σ_{i=0}^{L-1} p(i) * log₂[p(i)]

对于 8 位图像,熵的最大值是 8(所有灰度等概率出现)。

熵值范围 信息量描述 典型图像
< 4 信息量低,图像简单 纯色背景、简单图形
4 ~ 7 信息量中等,正常 自然风景、人像
> 7 信息量高,纹理复杂 遥感图像、密集纹理

嗯,这里要注意:熵高不一定好。噪声图像的熵也很高,但那是“无效信息”。所以熵要结合其他指标一起看。

3.7 六个特征的关系图谱

下面这张图帮你理清这六个指标的逻辑关系:

直方图统计特征关系图 图像直方图 亮度水平 分布形态 信息含量 均值 (Mean) 方差 (Variance) 偏度 (Skewness) 峰度 (Kurtosis) 能量 (Energy) 熵 (Entropy) 💡 六个指标分属三个维度:亮度水平(均值)、分布形态(方差/偏度/峰度)、信息含量(能量/熵) 实际分析时,建议从每个维度至少选一个指标,综合判断图像质量

3.8 实战:用 Python 计算这些特征

光说不练假把式。下面这段代码,我经常在项目里直接复用:

import cv2
import numpy as np

def histogram_features(image):
    # 计算直方图
    hist = cv2.calcHist([image], [0], None, [256], [0, 256])
    hist = hist.flatten()
    prob = hist / hist.sum()  # 归一化为概率
    gray_levels = np.arange(256)

    # 均值
    mean = np.sum(gray_levels * prob)

    # 方差
    variance = np.sum((gray_levels - mean) ** 2 * prob)

    # 偏度
    skewness = np.sum((gray_levels - mean) ** 3 * prob) / (variance ** 1.5)

    # 峰度
    kurtosis = np.sum((gray_levels - mean) ** 4 * prob) / (variance ** 2) - 3

    # 能量
    energy = np.sum(prob ** 2)

    # 熵
    entropy = -np.sum(prob * np.log2(prob + 1e-10))

    return {
        'mean': mean,
        'variance': variance,
        'skewness': skewness,
        'kurtosis': kurtosis,
        'energy': energy,
        'entropy': entropy
    }

# 使用示例
img = cv2.imread('example.jpg', cv2.IMREAD_GRAYSCALE)
features = histogram_features(img)
for key, value in features.items():
    print(f"{key}: {value:.4f}")
核心要点: 这六个特征不是孤立的。均值 + 方差看亮度和对比度,偏度 + 峰度看分布形态,能量 + 熵看信息量。组合使用,才能全面评估图像质量。

嗯,以上就是直方图统计特征的完整分析。下次拿到一张图,先跑一遍这六个指标,你就能快速判断它“健不健康”了。