直方图均衡作为一种图像增强技术,主要通过重新分布图像的像素强度值,使图像的直方图更均匀分布,最终提高图像的对比度。
数学原理:对于灰度图像,变换函数为:

其中:
原理:将图像分成小块,对每一块单独进行直方图均衡化
优点:更好的处理局部对比度
缺点:放大噪声,泛发性不足
原理:在自适应直方图均衡化基础上限制对比度增强幅度,避免噪声过度被放大
优点:平衡对比度增强和噪声控制
应用:医学影像、低照度图像处理
方法:
pip install opencv-python opencv-contrib-python numpy matplotlib -i https://pypi.tuna.tsinghua.edu.cn/simple/import cv2import numpy as npimport matplotlib.pyplot as pltfrom matplotlib import rcParams# 设置中文字体rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei']rcParams['axes.unicode_minus'] = Falsedef plot_images(images, titles, rows, cols, figsize=(15, 10)):"""绘制图像对比图"""fig, axes = plt.subplots(rows, cols, figsize=figsize)axes = axes.ravel() if rows * cols > 1 else [axes]for idx, (img, title) in enumerate(zip(images, titles)):ax = axes[idx]if len(img.shape) == 2: # 灰度图ax.imshow(img, cmap='gray')else: # 彩色图ax.imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))ax.set_title(title, fontsize=12)ax.axis('off')plt.tight_layout()plt.show()def plot_histograms(images, titles):"""绘制直方图对比"""fig, axes = plt.subplots(2, len(images), figsize=(15, 8))for idx, (img, title) in enumerate(zip(images, titles)):# 绘制图像if len(img.shape) == 2: # 灰度图axes[0, idx].imshow(img, cmap='gray')# 绘制直方图axes[1, idx].hist(img.ravel(), 256, [0, 256], color='blue', alpha=0.7)else: # 彩色图axes[0, idx].imshow(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))# 绘制RGB直方图colors = ('b', 'g', 'r')for i, color in enumerate(colors):hist = cv2.calcHist([img], [i], None, [256], [0, 256])axes[1, idx].plot(hist, color=color, alpha=0.7)axes[0, idx].set_title(title, fontsize=12)axes[0, idx].axis('off')axes[1, idx].set_title(f'{title}直方图')axes[1, idx].grid(True, alpha=0.3)plt.tight_layout()plt.show()def basic_histogram_equalization(img):"""基础直方图均衡化"""# 应用直方图均衡化img_eq = cv2.equalizeHist(img)# 显示结果images = [img, img_eq]titles = ['原始图像', '均衡化后图像']plot_images(images, titles, 1, 2)plot_histograms(images, titles)return img, img_eqdef clahe_implementation(img):# 创建CLAHE对象clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))# 应用CLAHEimg_clahe = clahe.apply(img)# 对比普通均衡化和CLAHEimg_eq = cv2.equalizeHist(img)images = [img, img_eq, img_clahe]titles = ['原始图像', '普通均衡化', 'CLAHE']plot_images(images, titles, 1, 3, figsize=(18, 6))# 绘制直方图对比plot_histograms(images, titles)return img_clahedef color_image_histogram_equalization(img):# 方法1:分别对每个通道均衡化(不推荐)b, g, r = cv2.split(img)b_eq = cv2.equalizeHist(b)g_eq = cv2.equalizeHist(g)r_eq = cv2.equalizeHist(r)img_eq_channels = cv2.merge([b_eq, g_eq, r_eq])# 方法2:转换到HSV/YCrCb空间,均衡化亮度通道# HSV方法img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)h, s, v = cv2.split(img_hsv)v_eq = cv2.equalizeHist(v)img_hsv_eq = cv2.merge([h, s, v_eq])img_eq_hsv = cv2.cvtColor(img_hsv_eq, cv2.COLOR_HSV2BGR)# YCrCb方法img_ycrcb = cv2.cvtColor(img, cv2.COLOR_BGR2YCrCb)y, cr, cb = cv2.split(img_ycrcb)y_eq = cv2.equalizeHist(y)img_ycrcb_eq = cv2.merge([y_eq, cr, cb])img_eq_ycrcb = cv2.cvtColor(img_ycrcb_eq, cv2.COLOR_YCrCb2BGR)images = [img, img_eq_channels, img_eq_hsv, img_eq_ycrcb]titles = ['原始彩色图像', '各通道分别均衡化', 'HSV空间V通道均衡化', 'YCrCb空间Y通道均衡化']plot_images(images, titles, 2, 2, figsize=(15, 12))return img_eq_ycrcbdef adaptive_histogram_equalization(img):"""自适应直方图均衡化演示"""# 添加一些噪声noise = np.random.normal(0, 10, img.shape).astype(np.uint8)img = cv2.add(img, noise)results = []titles = []# 不同参数的CLAHEclahe_params = [(2.0, (8, 8), "clipLimit=2.0, grid=(8,8)"),(4.0, (8, 8), "clipLimit=4.0, grid=(8,8)"),(2.0, (4, 4), "clipLimit=2.0, grid=(4,4)"),(2.0, (16, 16), "clipLimit=2.0, grid=(16,16)"),]results.append(img)titles.append("原始图像")for clip_limit, grid_size, title in clahe_params:clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=grid_size)img_clahe = clahe.apply(img)results.append(img_clahe)titles.append(f"CLAHE\n{title}")plot_images(results, titles, 2, 3, figsize=(15, 10))def practical_example(img):"""实际应用示例"""# 模拟低照度图像# 1. 普通均衡化img_eq = cv2.equalizeHist(img)# 2. CLAHEclahe = cv2.createCLAHE(clipLimit=3.0, tileGridSize=(8, 8))img_clahe = clahe.apply(img)# 3. Gamma校正(对比)gamma = 0.5img_gamma = np.uint8(((img / 255.0) ** gamma) * 255)images = [img, img_eq, img_clahe, img_gamma]titles = ['低照度图像', '直方图均衡化', 'CLAHE', 'Gamma校正(γ=0.5)']plot_images(images, titles, 2, 2, figsize=(12, 10))def main():"""主函数"""# 可根据需要对不同函数进行注释# 设置图片路径img = cv2.imread('data/datasets/JPEGImages/00F75605333_0730135838385.jpg')gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 1. 基础直方图均衡化basic_histogram_equalization(gray)# 2. CLAHE实现clahe_implementation(gray)# 3. 彩色图像处理color_image_histogram_equalization(img)# 4. 自适应均衡化参数调节adaptive_histogram_equalization(gray)# 5. 实际应用示例practical_example(gray)if __name__ == "__main__":main()
# 1. 基础直方图均衡化cv2.equalizeHist(src, dst=None) → dst# 2. 创建CLAHE对象clahe = cv2.createCLAHE(clipLimit=None, tileGridSize=None) → retval# 3. CLAHE应用clahe.apply(src, dst=None) → dst# 4. 直方图计算cv2.calcHist(images, channels, mask, histSize, ranges) → histCLAHE参数:
clipLimit: 对比度限制阈值,默认40tileGridSize: 分块大小,默认(8,8)