本文目录导读:

我来为您介绍几种批量调整图片自适应均衡的方法,主要使用Python脚本实现:
使用OpenCV的CLAHE(推荐)
import cv2
import numpy as np
from pathlib import Path
import os
def batch_adaptive_equalization(input_dir, output_dir, clip_limit=2.0, grid_size=(8,8)):
"""
批量处理图片自适应直方图均衡化
参数:
input_dir: 输入图片目录
output_dir: 输出图片目录
clip_limit: 对比度限制(默认2.0)
grid_size: 网格大小(默认8x8)
"""
# 创建输出目录
Path(output_dir).mkdir(parents=True, exist_ok=True)
# 支持的文件格式
extensions = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff']
# 获取所有图片文件
image_files = []
for ext in extensions:
image_files.extend(Path(input_dir).glob(f'*{ext}'))
image_files.extend(Path(input_dir).glob(f'*{ext.upper()}'))
print(f"找到 {len(image_files)} 张图片")
# 创建CLAHE对象
clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=grid_size)
for i, img_path in enumerate(image_files, 1):
try:
# 读取图片
img = cv2.imread(str(img_path))
if img is None:
print(f"无法读取: {img_path.name}")
continue
# 转换为LAB颜色空间
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
# 对亮度通道应用CLAHE
l_eq = clahe.apply(l)
# 合并通道并转换回BGR
lab_eq = cv2.merge([l_eq, a, b])
img_eq = cv2.cvtColor(lab_eq, cv2.COLOR_LAB2BGR)
# 保存结果
output_path = Path(output_dir) / img_path.name
cv2.imwrite(str(output_path), img_eq)
print(f"处理进度: {i}/{len(image_files)} - {img_path.name}")
except Exception as e:
print(f"处理失败 {img_path.name}: {str(e)}")
# 使用示例
if __name__ == "__main__":
# 设置参数
input_directory = "./input_images"
output_directory = "./output_images"
# 执行批量处理
batch_adaptive_equalization(
input_directory,
output_directory,
clip_limit=3.0, # 对比度限制,值越大对比度越强
grid_size=(8,8) # 网格大小,越小细节增强越明显
)
使用PIL(Pillow)的自动对比度增强
from PIL import Image, ImageEnhance, ImageOps
from pathlib import Path
import concurrent.futures
from tqdm import tqdm
def auto_contrast_enhance(img_path, output_dir, factor=1.5):
"""
使用PIL进行自适应对比度增强
参数:
img_path: 输入图片路径
output_dir: 输出目录
factor: 增强因子(1.0为原始,越大对比度越强)
"""
try:
# 打开图片
img = Image.open(img_path)
# 转换为RGB模式(如果是RGBA)
if img.mode == 'RGBA':
img = img.convert('RGB')
# 自动均衡化
img_eq = ImageOps.equalize(img)
# 增强对比度
if factor != 1.0:
enhancer = ImageEnhance.Contrast(img_eq)
img_eq = enhancer.enhance(factor)
# 保存结果
output_path = Path(output_dir) / img_path.name
img_eq.save(output_path, quality=95)
return True
except Exception as e:
print(f"处理失败 {img_path.name}: {str(e)}")
return False
def batch_pil_equalization(input_dir, output_dir, factor=1.5, workers=4):
"""
批量处理图片(支持多线程)
"""
# 创建输出目录
Path(output_dir).mkdir(parents=True, exist_ok=True)
# 获取图片文件
extensions = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff']
image_files = []
for ext in extensions:
image_files.extend(Path(input_dir).glob(f'*{ext}'))
image_files.extend(Path(input_dir).glob(f'*{ext.upper()}'))
print(f"找到 {len(image_files)} 张图片")
# 使用多线程处理
with concurrent.futures.ThreadPoolExecutor(max_workers=workers) as executor:
futures = []
for img_path in image_files:
future = executor.submit(
auto_contrast_enhance,
img_path,
output_dir,
factor
)
futures.append(future)
# 显示进度
results = []
for future in tqdm(concurrent.futures.as_completed(futures),
total=len(futures),
desc="处理进度"):
results.append(future.result())
success = sum(results)
print(f"处理完成: 成功 {success}/{len(image_files)}")
# 使用示例
if __name__ == "__main__":
# 参数设置
input_dir = "./input"
output_dir = "./processed"
# 批量处理
batch_pil_equalization(
input_dir,
output_dir,
factor=1.3, # 对比度增强系数
workers=4 # 线程数
)
高级版本 - 带GUI和参数调整
import tkinter as tk
from tkinter import filedialog, ttk
import cv2
import numpy as np
from pathlib import Path
import threading
class BatchEqualizerUI:
def __init__(self, root):
self.root = root
self.root.title("批量自适应均衡工具")
self.root.geometry("500x400")
self.input_dir = ""
self.output_dir = ""
self.setup_ui()
def setup_ui(self):
# 输入目录选择
ttk.Label(self.root, text="输入目录:").grid(row=0, column=0, padx=5, pady=5)
self.input_entry = ttk.Entry(self.root, width=40)
self.input_entry.grid(row=0, column=1, padx=5, pady=5)
ttk.Button(self.root, text="选择", command=self.select_input).grid(row=0, column=2)
# 输出目录选择
ttk.Label(self.root, text="输出目录:").grid(row=1, column=0, padx=5, pady=5)
self.output_entry = ttk.Entry(self.root, width=40)
self.output_entry.grid(row=1, column=1, padx=5, pady=5)
ttk.Button(self.root, text="选择", command=self.select_output).grid(row=1, column=2)
# 参数设置
ttk.Label(self.root, text="clip_limit:").grid(row=2, column=0, padx=5, pady=5)
self.clip_limit_var = tk.DoubleVar(value=2.0)
ttk.Spinbox(self.root, from_=0.5, to=10.0, increment=0.5,
textvariable=self.clip_limit_var, width=10).grid(row=2, column=1, sticky='w')
# 进度条
self.progress = ttk.Progressbar(self.root, length=400, mode='determinate')
self.progress.grid(row=3, column=0, columnspan=3, padx=5, pady=20)
# 状态标签
self.status_label = ttk.Label(self.root, text="就绪")
self.status_label.grid(row=4, column=0, columnspan=3, pady=10)
# 开始按钮
self.start_button = ttk.Button(self.root, text="开始处理", command=self.start_processing)
self.start_button.grid(row=5, column=0, columnspan=3, pady=10)
def select_input(self):
directory = filedialog.askdirectory()
if directory:
self.input_entry.delete(0, tk.END)
self.input_entry.insert(0, directory)
def select_output(self):
directory = filedialog.askdirectory()
if directory:
self.output_entry.delete(0, tk.END)
self.output_entry.insert(0, directory)
def start_processing(self):
if not self.input_entry.get() or not self.output_entry.get():
self.status_label.config(text="请选择输入和输出目录")
return
# 在新线程中处理,避免阻塞UI
thread = threading.Thread(target=self.process_images)
thread.daemon = True
thread.start()
def process_images(self):
input_dir = self.input_entry.get()
output_dir = self.output_entry.get()
clip_limit = self.clip_limit_var.get()
Path(output_dir).mkdir(parents=True, exist_ok=True)
# 获取图片文件
image_files = list(Path(input_dir).glob('*.jpg')) + \
list(Path(input_dir).glob('*.png')) + \
list(Path(input_dir).glob('*.jpeg'))
total_files = len(image_files)
self.progress['maximum'] = total_files
clahe = cv2.createCLAHE(clipLimit=clip_limit, tileGridSize=(8,8))
for i, img_path in enumerate(image_files, 1):
try:
img = cv2.imread(str(img_path))
if img is None:
continue
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
l, a, b = cv2.split(lab)
l_eq = clahe.apply(l)
lab_eq = cv2.merge([l_eq, a, b])
img_eq = cv2.cvtColor(lab_eq, cv2.COLOR_LAB2BGR)
output_path = Path(output_dir) / img_path.name
cv2.imwrite(str(output_path), img_eq)
# 更新进度
self.progress['value'] = i
self.status_label.config(text=f"处理中: {i}/{total_files}")
self.root.update_idletasks()
except Exception as e:
print(f"处理失败 {img_path.name}: {str(e)}")
self.status_label.config(text="处理完成!")
# 运行GUI
def main():
root = tk.Tk()
app = BatchEqualizerUI(root)
root.mainloop()
if __name__ == "__main__":
main()
使用说明
-
安装依赖:
pip install opencv-python pillow tqdm numpy
-
使用方法:
- 方法一和二:直接修改输入输出目录路径运行
- 运行后会显示GUI界面,选择目录和参数后点击开始
-
参数调整建议:
clip_limit:2.0-3.0 适合大多数图片grid_size:默认(8,8)适用于大多数情况- 对于过度曝光或欠曝的图片,可以适当增大clip_limit
这些脚本会自动处理目录中的所有图片,并保持原始文件格式和质量。