如何提取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
相关产品推荐
相关产品推荐

