如何用Python案例实现批量对比度调整?

wen python案例 2

本文目录导读:

如何用Python案例实现批量对比度调整?

  1. 基础批量对比度调整
  2. 进阶功能实现
  3. 使用说明
  4. 对比度因子参考

我来为您提供一个完整的Python批量对比度调整案例,这个案例使用PIL(Pillow)库来处理图像。

基础批量对比度调整

安装依赖库

pip install Pillow

基础实现

from PIL import Image, ImageEnhance
import os
from pathlib import Path
def batch_adjust_contrast(input_dir, output_dir, factor, file_extensions=['.jpg', '.jpeg', '.png']):
    """
    批量调整图片对比度
    参数:
        input_dir (str): 输入图片目录
        output_dir (str): 输出图片目录
        factor (float): 对比度因子 (1.0 = 原始, <1.0 降低对比度, >1.0 增加对比度)
        file_extensions (list): 处理的文件扩展名列表
    """
    # 创建输出目录
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    # 获取所有图片文件
    image_files = []
    for ext in file_extensions:
        image_files.extend(Path(input_dir).glob(f'*{ext}'))
        image_files.extend(Path(input_dir).glob(f'*{ext.upper()}'))
    if not image_files:
        print(f"在 {input_dir} 中没有找到图片文件")
        return
    processed_count = 0
    for img_path in image_files:
        try:
            # 打开图片
            with Image.open(img_path) as img:
                # 创建对比度增强器
                enhancer = ImageEnhance.Contrast(img)
                # 调整对比度
                enhanced_img = enhancer.enhance(factor)
                # 构建输出路径
                output_path = Path(output_dir) / img_path.name
                # 保存图片
                enhanced_img.save(output_path)
                processed_count += 1
                print(f"已处理: {img_path.name} -> {output_path}")
        except Exception as e:
            print(f"处理 {img_path.name} 时出错: {e}")
    print(f"\n处理完成!共处理 {processed_count} 张图片")
# 使用示例
if __name__ == "__main__":
    # 增加对比度 (factor > 1.0)
    batch_adjust_contrast(
        input_dir="original_images",
        output_dir="high_contrast",
        factor=1.5  # 增加50%对比度
    )
    # 降低对比度 (factor < 1.0)
    batch_adjust_contrast(
        input_dir="original_images",
        output_dir="low_contrast",
        factor=0.5  # 降低50%对比度
    )

进阶功能实现

多参数批量处理

def batch_contrast_with_multiple_factors(input_dir, output_base_dir, factors, file_extensions=['.jpg', '.jpeg', '.png']):
    """
    使用多个对比度因子批量处理图片
    参数:
        input_dir (str): 输入图片目录
        output_base_dir (str): 输出基础目录
        factors (list): 对比度因子列表
        file_extensions (list): 处理的文件扩展名列表
    """
    image_files = []
    for ext in file_extensions:
        image_files.extend(Path(input_dir).glob(f'*{ext}'))
        image_files.extend(Path(input_dir).glob(f'*{ext.upper()}'))
    for factor in factors:
        # 为每个因子创建子目录
        factor_dir = Path(output_base_dir) / f"contrast_{factor:.1f}"
        factor_dir.mkdir(parents=True, exist_ok=True)
        print(f"\n处理对比度因子: {factor}")
        for img_path in image_files:
            try:
                with Image.open(img_path) as img:
                    enhancer = ImageEnhance.Contrast(img)
                    enhanced_img = enhancer.enhance(factor)
                    # 保存时添加因子标识
                    output_name = f"{img_path.stem}_contrast_{factor:.1f}{img_path.suffix}"
                    output_path = factor_dir / output_name
                    enhanced_img.save(output_path)
            except Exception as e:
                print(f"处理 {img_path.name} 时出错: {e}")
# 使用示例
if __name__ == "__main__":
    batch_contrast_with_multiple_factors(
        input_dir="original_images",
        output_base_dir="comparison_results",
        factors=[0.3, 0.7, 1.0, 1.5, 2.0]
    )

自动优化对比度

from PIL import Image, ImageStat
import numpy as np
def calculate_optimal_contrast_factor(img):
    """
    计算图片的最佳对比度因子
    参数:
        img (PIL.Image): 输入图片
    返回:
        float: 建议的对比度因子
    """
    # 转换为灰度图计算统计信息
    gray_img = img.convert('L')
    # 获取像素值统计
    stats = ImageStat.Stat(gray_img)
    # 计算图像的标准差
    std = np.std(stats.std)
    # 目标标准差 (通常127是中间值)
    target_std = 50
    # 计算对比度因子
    if std > 0:
        factor = target_std / std
    else:
        factor = 1.0
    # 限制范围在0.3到3.0之间
    factor = max(0.3, min(3.0, factor))
    return factor
def batch_auto_contrast(input_dir, output_dir, file_extensions=['.jpg', '.jpeg', '.png']):
    """
    批量自动优化对比度
    参数:
        input_dir (str): 输入图片目录
        output_dir (str): 输出图片目录
        file_extensions (list): 处理的文件扩展名列表
    """
    Path(output_dir).mkdir(parents=True, exist_ok=True)
    image_files = []
    for ext in file_extensions:
        image_files.extend(Path(input_dir).glob(f'*{ext}'))
        image_files.extend(Path(input_dir).glob(f'*{ext.upper()}'))
    for img_path in image_files:
        try:
            with Image.open(img_path) as img:
                # 计算最佳对比度因子
                factor = calculate_optimal_contrast_factor(img)
                print(f"{img_path.name}: 建议对比度因子 = {factor:.2f}")
                # 应用对比度调整
                enhancer = ImageEnhance.Contrast(img)
                enhanced_img = enhancer.enhance(factor)
                # 保存结果
                output_path = Path(output_dir) / img_path.name
                enhanced_img.save(output_path)
        except Exception as e:
            print(f"处理 {img_path.name} 时出错: {e}")
# 使用示例
if __name__ == "__main__":
    batch_auto_contrast(
        input_dir="original_images",
        output_dir="auto_contrast_results"
    )

带进度显示的高级版本

import time
from PIL import Image, ImageEnhance
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor
class BatchContrastAdjuster:
    """批量对比度调整器(带进度显示)"""
    def __init__(self, input_dir, output_dir, file_extensions=['.jpg', '.jpeg', '.png']):
        self.input_dir = Path(input_dir)
        self.output_dir = Path(output_dir)
        self.file_extensions = file_extensions
        self.progress_callback = None
    def set_progress_callback(self, callback):
        """设置进度回调函数"""
        self.progress_callback = callback
    def process_single_image(self, img_path, factor):
        """处理单张图片"""
        try:
            with Image.open(img_path) as img:
                enhancer = ImageEnhance.Contrast(img)
                enhanced = enhancer.enhance(factor)
                output_path = self.output_dir / img_path.name
                enhanced.save(output_path, quality=95)
                return True, img_path.name, None
        except Exception as e:
            return False, img_path.name, str(e)
    def batch_process(self, factor, max_workers=4, show_progress=True):
        """批量处理图片"""
        self.output_dir.mkdir(parents=True, exist_ok=True)
        # 获取所有图片文件
        image_files = []
        for ext in self.file_extensions:
            image_files.extend(list(self.input_dir.glob(f'*{ext}')))
            image_files.extend(list(self.input_dir.glob(f'*{ext.upper()}')))
        if not image_files:
            print(f"没有找到图片文件")
            return
        total = len(image_files)
        print(f"找到 {total} 张图片,开始处理...")
        start_time = time.time()
        # 使用线程池并行处理
        with ThreadPoolExecutor(max_workers=max_workers) as executor:
            # 提交所有任务
            futures = [
                executor.submit(self.process_single_image, img_path, factor)
                for img_path in image_files
            ]
            # 收集结果
            results = []
            success_count = 0
            fail_count = 0
            for i, future in enumerate(futures):
                success, filename, error = future.result()
                results.append((success, filename, error))
                if success:
                    success_count += 1
                else:
                    fail_count += 1
                # 显示进度
                if show_progress:
                    progress = (i + 1) / total * 100
                    elapsed = time.time() - start_time
                    estimated_total = elapsed / (i + 1) * total
                    remaining = estimated_total - elapsed
                    print(f"\r进度: {progress:.1f}% | "
                          f"成功: {success_count} | "
                          f"失败: {fail_count} | "
                          f"剩余时间: {remaining:.1f}秒", end='')
                    if self.progress_callback:
                        self.progress_callback(progress)
        print(f"\n处理完成!")
        print(f"成功: {success_count} 张")
        if fail_count > 0:
            print(f"失败: {fail_count} 张")
            for success, filename, error in results:
                if not success:
                    print(f"  - {filename}: {error}")
        elapsed = time.time() - start_time
        print(f"总耗时: {elapsed:.1f} 秒")
    def batch_compare_factors(self, factors):
        """批量对比不同对比度因子"""
        for factor in factors:
            factor_dir = self.output_dir / f"contrast_{factor:.1f}"
            adjuster = BatchContrastAdjuster(
                self.input_dir, 
                factor_dir,
                self.file_extensions
            )
            print(f"\n{'='*50}")
            print(f"处理对比度因子: {factor}")
            print('='*50)
            adjuster.batch_process(factor, max_workers=2)
# 使用示例
if __name__ == "__main__":
    # 基本使用
    adjuster = BatchContrastAdjuster(
        input_dir="original_images",
        output_dir="adjusted_images"
    )
    # 批量处理(2倍对比度)
    adjuster.batch_process(factor=2.0, max_workers=4)
    # 或者对比不同因子
    # adjuster = BatchContrastAdjuster(
    #     input_dir="original_images",
    #     output_dir="comparison"
    # )
    # adjuster.batch_compare_factors([0.5, 1.0, 1.5, 2.0])

使用说明

  1. 基本使用:运行batch_adjust_contrast函数,指定输入输出目录和对比度因子
  2. 多因子对比:使用batch_contrast_with_multiple_factors生成不同效果的对比图
  3. 自动优化:使用batch_auto_contrast自动计算并应用最佳对比度
  4. 高级版本:使用BatchContrastAdjuster类,支持并行处理和进度显示

对比度因子参考

  • 0-0.5: 大幅降低对比度,图片变灰
  • 5-0.8: 适度降低对比度
  • 0: 原始对比度(无变化)
  • 0-1.5: 适度增加对比度
  • 5-3.0: 大幅增加对比度

这个案例提供了从简单到高级的各种批量对比度调整方案,您可以根据实际需求选择使用。

抱歉,评论功能暂时关闭!