本文目录导读:

我来为您介绍几种批量调整图片自适应均衡的方法,主要使用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
这些脚本会自动处理目录中的所有图片,并保持原始文件格式和质量。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播