2. 图像对比度增强
任务说明
本案例针对低对比度图像(如雾天、背光、医学影像等场景),通过对比度增强使图像特征更明显。核心目标是:给定一张输入图像,输出对比度增强后的图像,并验证增强前后像素灰度分布的变化。
实现方案
采用两种互补的对比度增强方法,并允许用户选择:
- 线性拉伸(Min-Max Stretch):将灰度范围线性映射到[0,255],简单高效,适合整体偏灰的图像。
- 直方图均衡化(Histogram Equalization):通过累积分布函数重映射灰度,自动增强全局对比度,对低对比度图像效果显著。
使用OpenCV实现,代码可直接运行,无需额外数据集——使用内置的cv2.imread读取任意本地图像即可。
环境依赖
pip install opencv-python numpy matplotlib
完整代码
import cv2
import numpy as np
import matplotlib.pyplot as plt
def linear_stretch(img_gray):
"""线性拉伸:将灰度范围映射到[0,255]"""
min_val = np.min(img_gray)
max_val = np.max(img_gray)
if max_val == min_val:
return img_gray.copy()
stretched = (img_gray.astype(np.float32) - min_val) * 255.0 / (max_val - min_val)
return stretched.astype(np.uint8)
def histogram_equalization(img_gray):
"""直方图均衡化"""
return cv2.equalizeHist(img_gray)
def process_image(image_path, method='equalize'):
"""
主处理函数
method: 'stretch' 或 'equalize'
"""
# 读取图像(灰度)
img = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
if img is None:
raise FileNotFoundError(f"无法读取图像: {image_path}")
# 执行增强
if method == 'stretch':
enhanced = linear_stretch(img)
elif method == 'equalize':
enhanced = histogram_equalization(img)
else:
raise ValueError("method 参数必须为 'stretch' 或 'equalize'")
# 保存结果
out_path = f"enhanced_{method}.jpg"
cv2.imwrite(out_path, enhanced)
# 可视化对比(原图、增强图、直方图)
fig, axes = plt.subplots(2, 2, figsize=(10, 8))
axes[0, 0].imshow(img, cmap='gray')
axes[0, 0].set_title('Original')
axes[0, 0].axis('off')
axes[0, 1].imshow(enhanced, cmap='gray')
axes[0, 1].set_title(f'Enhanced ({method})')
axes[0, 1].axis('off')
axes[1, 0].hist(img.ravel(), bins=256, range=(0, 255), color='blue', alpha=0.7)
axes[1, 0].set_title('Original Histogram')
axes[1, 1].hist(enhanced.ravel(), bins=256, range=(0, 255), color='red', alpha=0.7)
axes[1, 1].set_title('Enhanced Histogram')
plt.tight_layout()
plt.savefig(f"comparison_{method}.png", dpi=150)
plt.show()
# 输出灰度范围统计
print(f"原图灰度范围: [{np.min(img)}, {np.max(img)}]")
print(f"增强后灰度范围: [{np.min(enhanced)}, {np.max(enhanced)}]")
print(f"原图标准差: {np.std(img):.2f}")
print(f"增强后标准差: {np.std(enhanced):.2f}")
print(f"结果已保存: {out_path}")
if __name__ == "__main__":
# 使用示例:替换为你的低对比度图像路径
process_image("low_contrast.jpg", method="equalize")
# process_image("low_contrast.jpg", method="stretch") # 可选线性拉伸
运行与验证
- 准备一张低对比度图像(如雾天风景、背光照片),命名为
low_contrast.jpg,放在与脚本相同的目录下。 - 运行脚本:
python contrast_enhance.py - 观察弹出的对比图窗口,检查:
- 增强后图像视觉上是否更清晰、细节更明显;
- 直方图是否从集中在狭窄区间变为覆盖更宽的灰度范围;
- 控制台输出的标准差是否显著增大(标准差越大,对比度越高)。
通过条件:增强后图像灰度范围接近[0,255],标准差相比原图明显提升,且直方图分布更均匀,即视为增强成功。
预期输出示例
原图灰度范围: [52, 178]
增强后灰度范围: [0, 255]
原图标准差: 28.34
增强后标准差: 74.12
结果已保存: enhanced_equalize.jpg
以上数值仅为逻辑一致的示例——实际结果取决于输入图像,但灰度范围扩展和标准差增大是必然趋势。
常见问题
- 增强后出现噪点:直方图均衡化可能放大噪声。若图像噪声明显,可先做轻微高斯模糊(
cv2.GaussianBlur)再增强。 - 线性拉伸效果不明显:说明原图灰度范围已接近[0,255],此时应改用直方图均衡化。
- 彩色图像处理:本案例针对灰度图。若需处理彩色图,可先转换到HSV色彩空间,仅对V通道增强后合并。