脚本如何批量调整图片色阶

wen 实用脚本 2

本文目录导读:

脚本如何批量调整图片色阶

  1. 方法1:使用 Python + Pillow 库
  2. 方法2:使用 OpenCV + Python
  3. 方法3:使用 ImageMagick 命令行
  4. 方法4:使用专业软件
  5. 安装依赖
  6. 进阶功能

我来介绍几种批量调整图片色阶的方法,包括使用专业工具、命令行工具和Python脚本。

方法1:使用 Python + Pillow 库

from PIL import Image, ImageEnhance, ImageOps
import os
import glob
def batch_adjust_levels(input_folder, output_folder, black_point=0, white_point=255, gamma=1.0):
    """
    批量调整图片色阶
    参数:
    input_folder: 输入文件夹路径
    output_folder: 输出文件夹路径
    black_point: 黑场阈值 (0-255)
    white_point: 白场阈值 (0-255)
    gamma: 伽马值 (默认1.0,大于1变亮,小于1变暗)
    """
    # 创建输出文件夹
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    # 支持的图片格式
    extensions = ['*.jpg', '*.jpeg', '*.png', '*.bmp', '*.tiff']
    image_files = []
    for ext in extensions:
        image_files.extend(glob.glob(os.path.join(input_folder, ext)))
        image_files.extend(glob.glob(os.path.join(input_folder, ext.upper())))
    for image_path in image_files:
        try:
            # 打开图片
            img = Image.open(image_path)
            # 转换为RGB模式(如果是RGBA)
            if img.mode == 'RGBA':
                img = img.convert('RGB')
            # 调整色阶
            img = adjust_levels(img, black_point, white_point, gamma)
            # 保存图片
            filename = os.path.basename(image_path)
            output_path = os.path.join(output_folder, filename)
            img.save(output_path)
            print(f"已处理: {filename}")
        except Exception as e:
            print(f"处理 {image_path} 时出错: {str(e)}")
def adjust_levels(img, black_point=0, white_point=255, gamma=1.0):
    """调整单张图片的色阶"""
    # 自动色阶:如果black_point和white_point为None
    if black_point is None or white_point is None:
        # 获取图片直方图
        hist = img.histogram()
        # 找到直方图中的第一个和最后一个非零像素
        if black_point is None:
            for i, count in enumerate(hist):
                if count > 0:
                    black_point = i
                    break
        if white_point is None:
            for i in range(len(hist)-1, -1, -1):
                if hist[i] > 0:
                    white_point = i
                    break
    # 应用色阶调整
    # 使用点运算进行映射
    def level_mapping(x):
        # 归一化
        if x < black_point:
            return 0
        elif x > white_point:
            return 255
        else:
            # 线性映射
            normalized = (x - black_point) / (white_point - black_point)
            # 应用伽马校正
            adjusted = pow(normalized, 1/gamma) * 255
            return int(adjusted)
    # 应用到所有通道
    return img.point(level_mapping)
# 使用示例
if __name__ == "__main__":
    # 基本使用 - 自动调整
    batch_adjust_levels(
        "./input_images", 
        "./output_images",
        black_point=None,  # 自动检测黑场
        white_point=None,  # 自动检测白场
        gamma=1.0         # 保持原伽马
    )
    # 或者手动指定色阶
    batch_adjust_levels(
        "./input_images", 
        "./output_images_custom",
        black_point=30,   # 黑场设为30
        white_point=220,  # 白场设为220
        gamma=1.2         # 稍微变亮
    )

方法2:使用 OpenCV + Python

import cv2
import numpy as np
import os
import glob
def batch_levels_opencv(input_folder, output_folder, clip_hist_percent=1):
    """
    使用OpenCV批量调整色阶(自动对比度)
    参数:
    clip_hist_percent: 裁剪直方图的百分比,用于去除极端值
    """
    if not os.path.exists(output_folder):
        os.makedirs(output_folder)
    extensions = ['*.jpg', '*.jpeg', '*.png', '*.bmp']
    image_files = []
    for ext in extensions:
        image_files.extend(glob.glob(os.path.join(input_folder, ext)))
    for image_path in image_files:
        try:
            img = cv2.imread(image_path)
            # 自动对比度调整
            gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
            # 计算直方图
            hist = cv2.calcHist([gray], [0], None, [256], [0, 256])
            # 计算累积直方图
            accumulator = np.cumsum(hist)
            # 根据百分比找到最小和最大灰度值
            maximum = accumulator[-1]
            clip_hist_percent *= (maximum / 100.0)
            clip_hist_percent /= 2.0
            # 找到最小灰度值
            minimum_gray = 0
            while accumulator[minimum_gray] < clip_hist_percent:
                minimum_gray += 1
            # 找到最大灰度值
            maximum_gray = 255
            while accumulator[maximum_gray] >= (maximum - clip_hist_percent):
                maximum_gray -= 1
            # 应用色阶调整
            alpha = 255 / (maximum_gray - minimum_gray)
            beta = -minimum_gray * alpha
            adjusted = cv2.convertScaleAbs(img, alpha=alpha, beta=beta)
            # 保存
            filename = os.path.basename(image_path)
            output_path = os.path.join(output_folder, filename)
            cv2.imwrite(output_path, adjusted)
            print(f"已处理: {filename}")
        except Exception as e:
            print(f"处理 {image_path} 时出错: {str(e)}")
# 使用示例
batch_levels_opencv("./input_images", "./output_images", clip_hist_percent=1)

方法3:使用 ImageMagick 命令行

ImageMagick 是非常强大的图像处理工具,可以用命令行批量处理:

#!/bin/bash
# 批量调整色阶 - 自动调整
for file in input_images/*.jpg; do
    filename=$(basename "$file")
    convert "$file" -auto-level "output_images/$filename"
done
# 手动指定色阶 (黑点30, 白点200, 伽马1.5)
for file in input_images/*.jpg; do
    filename=$(basename "$file")
    convert "$file" -level 30%,80%,1.5 "output_images/$filename"
done
# 更精确的控制
for file in input_images/*.jpg; do
    filename=$(basename "$file")
    # black-point:30, white-point:220, gamma:1.2
    convert "$file" -level 30,220,1.2 "output_images/$filename"
done

方法4:使用专业软件

Photoshop (批处理)

  1. 录制一个调整色阶的动作
  2. 文件 > 自动 > 批处理
  3. 选择动作和源文件夹

GIMP (免费开源)

  1. 使用 "BIMP" 插件
  2. 可以批量应用色阶调整

安装依赖

对于 Python 方法,需要安装依赖:

# 方法1的依赖
pip install Pillow
# 方法2的依赖
pip install opencv-python numpy
# 方法3需要安装ImageMagick
# Ubuntu/Debian: sudo apt-get install imagemagick
# macOS: brew install imagemagick
# Windows: 下载安装程序

进阶功能

如果需要更复杂的色阶调整,可以添加:

def advanced_levels(img, shadows=(0, 0, 0), midtones=(1.0, 1.0, 1.0), highlights=(255, 255, 255)):
    """
    分别调整RGB三个通道的色阶
    参数:
    shadows: (R, G, B) 黑场值 (0-255)
    midtones: (R, G, B) 伽马值
    highlights: (R, G, B) 白场值 (0-255)
    """
    channels = list(img.split())
    adjusted_channels = []
    for i, channel in enumerate(channels):
        def mapping(x):
            if x < shadows[i]:
                return 0
            elif x > highlights[i]:
                return 255
            else:
                normalized = (x - shadows[i]) / (highlights[i] - shadows[i])
                adjusted = pow(normalized, 1/midtones[i]) * 255
                return int(adjusted)
        adjusted_channels.append(channel.point(mapping))
    return Image.merge('RGB', adjusted_channels)

选择哪种方法取决于你的具体需求和技术水平,对于简单批量处理,推荐使用ImageMagick命令行;如果需要精细控制,使用Python脚本会更灵活。

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