如何用Python为延时摄影图片集实现统一白平衡?
延时摄影照片统一白平衡的Python实现方案
针对不同天气(晴天、雾霾、雨天)导致的曝光/白平衡差异,不能依赖固定参数,必须用自动白平衡算法针对单张图片计算适配参数,以下是可落地的实现方案:
核心思路
采用两种主流自动白平衡算法,适配不同场景:
- 灰度世界法:假设场景中所有颜色的平均值为中性灰色,适合色彩分布均匀的自然风光;
- 白点校正法:取图像中最亮的n%像素作为"白点",将其映射为纯白,适合存在明显高光区域(如天空)的场景。
结合自动曝光校正,进一步提升画面流畅度。
代码实现(基于OpenCV)
1. 灰度世界法白平衡
import cv2 import numpy as np import os def gray_world_white_balance(img): img_float = img.astype(np.float32) / 255.0 # 计算RGB三通道均值 mean_r = np.mean(img_float[:, :, 2]) mean_g = np.mean(img_float[:, :, 1]) mean_b = np.mean(img_float[:, :, 0]) # 以绿色通道为基准计算增益 gain_r = mean_g / mean_r if mean_r != 0 else 1.0 gain_b = mean_g / mean_b if mean_b != 0 else 1.0 # 应用增益并裁剪到有效范围 img_float[:, :, 2] *= gain_r img_float[:, :, 0] *= gain_b img_float = np.clip(img_float, 0, 1) return (img_float * 255).astype(np.uint8) def batch_process_images(input_dir, output_dir, process_func): os.makedirs(output_dir, exist_ok=True) for filename in os.listdir(input_dir): if filename.lower().endswith(('.png', '.jpg', '.jpeg')): img_path = os.path.join(input_dir, filename) img = cv2.imread(img_path) if img is None: print(f"跳过无法读取的图片: {filename}") continue corrected_img = process_func(img) cv2.imwrite(os.path.join(output_dir, filename), corrected_img) print(f"已处理: {filename}") # 使用示例 input_folder = "你的输入图片文件夹路径" output_folder = "你的输出图片文件夹路径" batch_process_images(input_folder, output_folder, gray_world_white_balance)
2. 白点校正法白平衡(更适合你的示例场景)
def white_point_white_balance(img, percentile=1): img_float = img.astype(np.float32) / 255.0 b, g, r = cv2.split(img_float) # 获取通道高百分位值作为白点 def get_white_point(channel): flat = channel.flatten() flat.sort() return flat[-int(len(flat)*percentile/100)] if len(flat) > 0 else 1.0 wp_b, wp_g, wp_r = get_white_point(b), get_white_point(g), get_white_point(r) # 计算增益将白点映射为纯白 gain_r = 1.0 / wp_r if wp_r != 0 else 1.0 gain_g = 1.0 / wp_g if wp_g != 0 else 1.0 gain_b = 1.0 / wp_b if wp_b != 0 else 1.0 r *= gain_r g *= gain_g b *= gain_b corrected = cv2.merge((b, g, r)) corrected = np.clip(corrected, 0, 1) return (corrected * 255).astype(np.uint8) # 替换process_func即可批量使用 batch_process_images(input_folder, output_folder, white_point_white_balance)
3. 结合曝光校正的完整流程
如果曝光差异过大,可在白平衡后添加自适应曝光调整:
def adjust_exposure(img): hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV) h, s, v = cv2.split(hsv) # 自适应直方图均衡化(CLAHE)调整亮度通道 clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) v_clahe = clahe.apply(v) return cv2.cvtColor(cv2.merge((h, s, v_clahe)), cv2.COLOR_HSV2BGR) # 组合白平衡+曝光校正 def full_correction(img): corrected_wb = white_point_white_balance(img) return adjust_exposure(corrected_wb) # 批量处理 batch_process_images(input_folder, output_folder, full_correction)
注意事项
- 先拿几张示例图测试两种白平衡算法,选择效果最优的(你的示例图含天空,白点校正法大概率更合适);
- 若场景存在大面积单色区域(如纯色墙面),灰度世界法可能失效,此时优先使用白点校正法;
- 批量处理前备份原始图片,避免不可逆修改;
- 可根据实际效果调整
percentile(白点校正)或clipLimit(曝光校正)的参数值。
内容的提问来源于stack exchange,提问作者coderAI
相关产品推荐
相关产品推荐

