You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何提取Hue直方图[120-180]区间的正态分布均值与标准差

Hey there! Let's tackle this problem step by step. You're already doing great by accumulating hue histograms across all your images—now we just need to zoom in on the [120, 180] interval, calculate its mean/standard deviation, and fit a normal distribution to that subset.

Here's the updated code with explanations tailored to your needs:

import matplotlib.pyplot as plt
import numpy as np
import cv2
import os
from imutils import paths
from scipy.stats import norm  # Added for normal distribution fitting

directory = os.getcwd() + "\Demos/SotetLila"
total_hue_hist = np.zeros((180,))
total_sat_hist = np.zeros((256,))
total_val_hist = np.zeros((256,))

# Keep your existing histogram accumulation logic
for imagePath in paths.list_images(directory):
    img = cv2.imread(imagePath)
    blur = cv2.GaussianBlur(img, (5, 5), 0)
    hsv = cv2.cvtColor(blur, cv2.COLOR_BGR2HSV)
    hue, sat, val = hsv[:, :, 0], hsv[:, :, 1], hsv[:, :, 2]
    
    hue_hist, bin_hue = np.histogram(hue, bins=range(181))
    total_hue_hist += hue_hist
    
    sat_hist, bin_sat = np.histogram(sat, bins=range(257))
    total_sat_hist += sat_hist
    
    val_hist, bin_val = np.histogram(val, bins=range(257))
    total_val_hist += val_hist

# ----------------------
# Process the [120, 180] hue interval
# ----------------------
# Define the range: indices 120 to 179 (each index i covers hue range [i, i+1))
start_hue = 120
end_hue = 180
target_hist = total_hue_hist[start_hue:end_hue]
# Calculate midpoints of each bin (e.g., bin 120 corresponds to hue 120.5)
bin_centers = np.arange(start_hue + 0.5, end_hue + 0.5, 1)

total_pixels = target_hist.sum()
if total_pixels == 0:
    print("No pixels found in the [120, 180] hue range!")
else:
    # Compute weighted mean (accounts for pixel count in each bin)
    weighted_mean = np.sum(bin_centers * target_hist) / total_pixels
    
    # Compute weighted standard deviation
    squared_diff = (bin_centers - weighted_mean) ** 2
    weighted_variance = np.sum(target_hist * squared_diff) / total_pixels
    weighted_std = np.sqrt(weighted_variance)
    
    print(f"[120-180] Hue Mean: {weighted_mean:.2f}")
    print(f"[120-180] Hue Standard Deviation: {weighted_std:.2f}")
    
    # Fit normal distribution to the data
    # Option 1: Create a sample array (repeat bin centers by their pixel count)
    sample_data = np.repeat(bin_centers, target_hist.astype(int))
    fit_mean, fit_std = norm.fit(sample_data)
    
    # Option 2: Use weights (requires scipy >= 1.7.0, more memory-efficient)
    # fit_mean, fit_std = norm.fit(bin_centers, weights=target_hist)
    
    print(f"Fitted Normal Distribution Mean: {fit_mean:.2f}")
    print(f"Fitted Normal Distribution Std Dev: {fit_std:.2f}")
    
    # ----------------------
    # Visualize results
    # ----------------------
    plt.figure(figsize=(10, 6))
    
    # Plot the target histogram
    plt.bar(bin_centers - 0.5, target_hist, width=1, label="Hue Histogram (120-180)")
    
    # Plot the fitted normal curve (scaled to match histogram height)
    x_range = np.linspace(start_hue, end_hue, 100)
    normal_curve = norm.pdf(x_range, fit_mean, fit_std) * total_pixels
    plt.plot(x_range, normal_curve, 'r--', linewidth=2, 
             label=f"Fitted Normal (μ={fit_mean:.2f}, σ={fit_std:.2f})")
    
    plt.xlabel("Hue Value")
    plt.ylabel("Pixel Count")
    plt.title("Hue Histogram (120-180) with Fitted Normal Distribution")
    plt.legend()
    plt.grid(axis='y', alpha=0.3)
    plt.show()

Key Details:

  • Isolating the Interval: We slice the accumulated histogram to focus on indices 120–179, which correspond to the hue range [120, 180). Bin centers are used instead of raw bin edges to get accurate statistical values.
  • Weighted Statistics: Since each bin represents a count of pixels, we weight each bin's midpoint by its pixel count to calculate mean and standard deviation—this gives results that reflect the actual distribution of pixels, not just bin positions.
  • Normal Fitting: Two options are provided for fitting the normal distribution. The first creates a full sample array (easy to understand), while the second uses weights (better for large datasets to save memory).
  • Visualization: The plot overlays the fitted normal curve on your histogram so you can visually assess how well the distribution matches your data.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 22:12:33