You need to enable JavaScript to run this app. 基于OpenCV的直方图特征提取:如何计算均值、方差、归一化方差与熵
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenCV的直方图特征提取:如何计算均值、方差、归一化方差与熵

基于OpenCV的直方图特征提取实现方案

你现有的直方图计算流程已经完全可以支撑特征提取需求,不需要引入复杂依赖,借助NumPy即可实现均值、方差、归一化方差、熵四类特征的落地计算,完全兼容你已有的代码逻辑。

各特征的计算实现

所有计算函数均适配cv2.calcHist()的输出格式(形状为(256,1)的二维数组),不需要额外做复杂的格式转换。

1. 直方图均值

  • 核心逻辑:以每个灰度级的像素计数为权重,计算灰度值的加权平均,等价于图像全局像素的平均灰度值
  • 可复用代码:
import numpy as np

def calc_hist_mean(hist):
    hist_flat = hist.flatten()
    # 生成每个bin对应的灰度取值(256个bin对应0~255)
    bin_levels = np.arange(hist_flat.shape[0])
    total_pixels = hist_flat.sum()
    mean = (bin_levels * hist_flat).sum() / total_pixels
    return mean

2. 直方图方差

  • 核心逻辑:衡量直方图分布的离散程度,计算每个灰度值与均值差值的平方加权和
  • 可复用代码:
def calc_hist_variance(hist, mean=None):
    hist_flat = hist.flatten()
    bin_levels = np.arange(hist_flat.shape[0])
    total_pixels = hist_flat.sum()
    if mean is None:
        mean = (bin_levels * hist_flat).sum() / total_pixels
    variance = ((bin_levels - mean) ** 2 * hist_flat).sum() / total_pixels
    return variance

3. 归一化方差

  • 核心逻辑:消除直方图bin数量不同带来的尺度影响,让不同分箱粒度的直方图特征具备横向可比性,计算方式为方差除以bin总数的平方
  • 可复用代码:
def calc_hist_norm_variance(hist, variance=None):
    hist_flat = hist.flatten()
    n_bins = hist_flat.shape[0]
    if variance is None:
        variance = calc_hist_variance(hist)
    norm_variance = variance / (n_bins ** 2)
    return norm_variance

4. 直方图熵

  • 核心逻辑:衡量直方图的分布均匀度,分布越均匀熵值越高,分布越集中熵值越低。计算时需要过滤计数为0的bin,避免出现对数计算错误
  • 可复用代码:
def calc_hist_entropy(hist):
    hist_flat = hist.flatten()
    total_pixels = hist_flat.sum()
    # 过滤零值bin,计算归一化概率
    valid_p = hist_flat[hist_flat > 0] / total_pixels
    entropy = - (valid_p * np.log2(valid_p)).sum()
    return entropy

与现有代码的整合

把上述特征计算函数嵌入你已有的直方图对比流程中即可,整合后的完整代码如下,同时修正了原代码中对比方法硬编码的问题:

HIST_METHODS = {
    "Correlation": cv2.HISTCMP_CORREL,
    "Chi-Squared": cv2.HISTCMP_CHISQR,
    "Intersection": cv2.HISTCMP_INTERSECT,
    "Hellinger": cv2.HISTCMP_BHATTACHARYYA
}
HIST_COLORS = ('b','g','r')

# 此处放置上述定义的4个特征计算函数

for key, value in HIST_METHODS.items():
    compare_results = []
    feature_results = []
    for i, col in enumerate(HIST_COLORS):
        hist1 = cv2.calcHist([img1],[i],None,[256],[0,256], accumulate = False)
        hist2 = cv2.calcHist([img2],[i],None,[256],[0,256], accumulate = False)
        
        # 原有直方图对比逻辑,修正为使用循环内的对比方法值
        res = cv2.compareHist(hist1, hist2, value)
        compare_results.append(res)

        # 提取两个图像的直方图特征
        img1_feat = {
            "mean": calc_hist_mean(hist1),
            "variance": calc_hist_variance(hist1),
            "norm_variance": calc_hist_norm_variance(hist1),
            "entropy": calc_hist_entropy(hist1)
        }
        img2_feat = {
            "mean": calc_hist_mean(hist2),
            "variance": calc_hist_variance(hist2),
            "norm_variance": calc_hist_norm_variance(hist2),
            "entropy": calc_hist_entropy(hist2)
        }
        feature_results.append((img1_feat, img2_feat))

注意:你原代码中cv2.compareHist的第三个参数硬编码为cv2.HISTCMP_CORREL,没有使用循环遍历到的方法值,实际运行时无论循环到哪种对比方法,返回结果都是相关性对比的结果,可顺手修正。


内容的提问来源于stack exchange,提问作者Lleims

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.24 17:06:04