9 图像处理实战:从基础操作到完整项目开发
在数字图像处理领域,无论是计算机视觉项目还是日常的图片编辑需求,掌握图像处理的核心技术都至关重要。本文将通过完整的实战案例,带你系统学习图像处理的全流程,从环境搭建、基础操作到项目实战,每个环节都提供可运行的代码示例和详细解释。
1. 图像处理基础概念与环境准备
1.1 什么是数字图像处理
数字图像处理是指使用计算机算法对数字图像进行分析、处理和解释的技术。简单来说,就是将图像转换为数字矩阵,然后通过数学运算来改善图像质量、提取有用信息或实现特定视觉效果。
数字图像由像素组成,每个像素包含颜色信息。在灰度图像中,每个像素用一个数值表示亮度;在彩色图像中,每个像素用三个数值(RGB)表示颜色分量。
1.2 环境准备与工具选择
对于图像处理项目,我们推荐使用Python语言,因为它拥有丰富的图像处理库和简洁的语法。以下是环境配置步骤:
安装必要的库:
pip install opencv-python pip install pillow pip install matplotlib pip install numpy pip install scikit-image验证安装:
import cv2 import numpy as np from PIL import Image import matplotlib.pyplot as plt print(f"OpenCV版本: {cv2.__version__}") print(f"NumPy版本: {np.__version__}")推荐开发环境:
- Python 3.8+
- Jupyter Notebook(用于实验和调试)
- PyCharm或VS Code(用于项目开发)
- 至少4GB内存(处理大图像时需要更多内存)
2. 图像基础操作与IO处理
2.1 图像读取与显示
图像读取是处理的第一步,不同的库提供了不同的读取方式:
import cv2 import matplotlib.pyplot as plt from PIL import Image import numpy as np # 使用OpenCV读取图像 def read_image_opencv(image_path): # 读取图像,-1表示包含alpha通道,0表示灰度,1表示彩色 img = cv2.imread(image_path, 1) # OpenCV默认使用BGR格式,需要转换为RGB img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) return img_rgb # 使用PIL读取图像 def read_image_pil(image_path): img = Image.open(image_path) # 转换为numpy数组 img_array = np.array(img) return img_array # 图像显示函数 def display_images(images, titles, figsize=(15, 5)): plt.figure(figsize=figsize) for i, (image, title) in enumerate(zip(images, titles)): plt.subplot(1, len(images), i+1) plt.imshow(image) plt.title(title) plt.axis('off') plt.tight_layout() plt.show() # 示例使用 image_path = "sample.jpg" # 替换为你的图像路径 img_opencv = read_image_opencv(image_path) img_pil = read_image_pil(image_path) print(f"图像形状: {img_opencv.shape}") print(f"数据类型: {img_opencv.dtype}") print(f"像素值范围: {img_opencv.min()} - {img_opencv.max()}")2.2 图像基本属性与信息提取
了解图像的基本属性对于后续处理至关重要:
def analyze_image_properties(image_path): # 读取图像 img = cv2.imread(image_path) img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 基本属性 height, width, channels = img.shape total_pixels = height * width image_size = img.nbytes # 字节大小 print(f"图像尺寸: {width} x {height}") print(f"通道数: {channels}") print(f"总像素数: {total_pixels}") print(f"图像大小: {image_size} 字节") print(f"数据类型: {img.dtype}") # 统计信息 print(f"红色通道统计: 均值={img_rgb[:,:,0].mean():.2f}, 标准差={img_rgb[:,:,0].std():.2f}") print(f"绿色通道统计: 均值={img_rgb[:,:,1].mean():.2f}, 标准差={img_rgb[:,:,1].std():.2f}") print(f"蓝色通道统计: 均值={img_rgb[:,:,2].mean():.2f}, 标准差={img_rgb[:,:,2].std():.2f}") return img_rgb # 创建测试图像(如果无真实图像) def create_test_image(): # 创建一个512x512的测试图像 test_img = np.zeros((512, 512, 3), dtype=np.uint8) # 添加彩色矩形 cv2.rectangle(test_img, (100, 100), (200, 200), (255, 0, 0), -1) # 红色 cv2.rectangle(test_img, (250, 100), (350, 200), (0, 255, 0), -1) # 绿色 cv2.rectangle(test_img, (400, 100), (500, 200), (0, 0, 255), -1) # 蓝色 # 添加文字 cv2.putText(test_img, 'OpenCV Test', (150, 300), cv2.FONT_HERSHEY_SIMPLEX, 1, (255, 255, 255), 2) return test_img # 使用测试图像进行分析 test_image = create_test_image() analyze_image_properties = lambda x: None # 重新定义避免错误 print("测试图像分析:") print(f"形状: {test_image.shape}")3. 图像预处理技术
3.1 图像尺寸调整与缩放
图像缩放是常见的预处理操作,需要注意保持宽高比:
def resize_image(image, new_size, keep_aspect_ratio=True): """ 调整图像尺寸 Args: image: 输入图像 new_size: 新尺寸 (width, height) 或缩放比例 keep_aspect_ratio: 是否保持宽高比 """ h, w = image.shape[:2] if isinstance(new_size, float): # 按比例缩放 new_w = int(w * new_size) new_h = int(h * new_size) resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LINEAR) elif isinstance(new_size, tuple) and keep_aspect_ratio: # 保持宽高比调整到指定大小 target_w, target_h = new_size scale = min(target_w/w, target_h/h) new_w = int(w * scale) new_h = int(h * scale) resized = cv2.resize(image, (new_w, new_h), interpolation=cv2.INTER_LINEAR) # 填充到目标尺寸 delta_w = target_w - new_w delta_h = target_h - new_h top, bottom = delta_h//2, delta_h - delta_h//2 left, right = delta_w//2, delta_w - delta_w//2 resized = cv2.copyMakeBorder(resized, top, bottom, left, right, cv2.BORDER_CONSTANT, value=[0, 0, 0]) else: # 直接调整到指定尺寸 resized = cv2.resize(image, new_size, interpolation=cv2.INTER_LINEAR) return resized # 测试不同的缩放方法 test_img = create_test_image() # 1. 按比例缩放 scaled_50 = resize_image(test_img, 0.5) scaled_150 = resize_image(test_img, 1.5) # 2. 调整到固定尺寸(保持宽高比) resized_300x300 = resize_image(test_img, (300, 300), keep_aspect_ratio=True) # 3. 直接调整(可能变形) resized_direct = resize_image(test_img, (300, 100), keep_aspect_ratio=False) images = [test_img, scaled_50, scaled_150, resized_300x300, resized_direct] titles = ['原图', '缩放50%', '缩放150%', '调整到300x300(保持比例)', '直接调整300x100'] display_images(images, titles, figsize=(20, 4))3.2 图像色彩空间转换
不同的色彩空间适用于不同的处理任务:
def color_space_conversions(image): """ 演示不同色彩空间的转换 """ # RGB to Grayscale gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # RGB to HSV hsv = cv2.cvtColor(image, cv2.COLOR_RGB2HSV) # RGB to LAB lab = cv2.cvtColor(image, cv2.COLOR_RGB2LAB) # RGB to YCrCb ycrcb = cv2.cvtColor(image, cv2.COLOR_RGB2YCrCb) return gray, hsv, lab, ycrcb def demonstrate_color_spaces(image): gray, hsv, lab, ycrcb = color_space_conversions(image) # 显示各个通道 images = [ image, # 原图 gray, # 灰度图 hsv[:,:,0], hsv[:,:,1], hsv[:,:,2], # HSV各通道 lab[:,:,0], lab[:,:,1], lab[:,:,2], # LAB各通道 ycrcb[:,:,0], ycrcb[:,:,1], ycrcb[:,:,2] # YCrCb各通道 ] titles = [ '原图(RGB)', '灰度图', 'H通道', 'S通道', 'V通道', 'L通道', 'A通道', 'B通道', 'Y通道', 'Cr通道', 'Cb通道' ] plt.figure(figsize=(20, 10)) for i, (img, title) in enumerate(zip(images, titles)): plt.subplot(3, 4, i+1) if len(img.shape) == 2: # 灰度图 plt.imshow(img, cmap='gray') else: plt.imshow(img) plt.title(title) plt.axis('off') plt.tight_layout() plt.show() # 演示色彩空间转换 demonstrate_color_spaces(test_img)4. 图像滤波与增强
4.1 常用滤波技术
图像滤波用于去噪、平滑、边缘检测等:
def apply_filters(image): """ 应用各种图像滤波器 """ # 高斯模糊 gaussian_blur = cv2.GaussianBlur(image, (5, 5), 0) # 中值滤波 median_blur = cv2.medianBlur(image, 5) # 双边滤波(保持边缘) bilateral_blur = cv2.bilateralFilter(image, 9, 75, 75) # 边缘检测 - Sobel gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=5) sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=5) sobel_combined = np.sqrt(sobelx**2 + sobely**2) # 边缘检测 - Canny edges = cv2.Canny(gray, 100, 200) return gaussian_blur, median_blur, bilateral_blur, sobel_combined, edges def demonstrate_filters(image): filters = apply_filters(image) images = [image] + list(filters) titles = [ '原图', '高斯模糊', '中值滤波', '双边滤波', 'Sobel边缘检测', 'Canny边缘检测' ] display_images(images, titles, figsize=(20, 10)) # 创建带噪声的测试图像 def create_noisy_image(): clean_img = create_test_image() # 添加高斯噪声 mean = 0 sigma = 25 gaussian_noise = np.random.normal(mean, sigma, clean_img.shape).astype(np.uint8) noisy_img = cv2.add(clean_img, gaussian_noise) return clean_img, noisy_img clean, noisy = create_noisy_image() demonstrate_filters(noisy)4.2 图像增强技术
图像增强可以改善视觉效果或为后续处理做准备:
def image_enhancement_techniques(image): """ 图像增强技术演示 """ # 直方图均衡化(灰度图) gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) hist_eq = cv2.equalizeHist(gray) # CLAHE(对比度受限的自适应直方图均衡化) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) clahe_applied = clahe.apply(gray) # 伽马校正 gamma = 1.5 inv_gamma = 1.0 / gamma table = np.array([((i / 255.0) ** inv_gamma) * 255 for i in np.arange(0, 256)]).astype("uint8") gamma_corrected = cv2.LUT(image, table) # 对比度拉伸 alpha = 1.5 # 对比度控制 beta = 10 # 亮度控制 contrast_stretched = cv2.convertScaleAbs(image, alpha=alpha, beta=beta) return gray, hist_eq, clahe_applied, gamma_corrected, contrast_stretched def demonstrate_enhancement(image): enhancements = image_enhancement_techniques(image) images = [image] + list(enhancements) titles = [ '原图', '灰度图', '直方图均衡化', 'CLAHE', '伽马校正(γ=1.5)', '对比度拉伸' ] # 灰度图单独显示 gray_images = enhancements[:3] # 前三个是灰度图 gray_titles = titles[1:4] plt.figure(figsize=(15, 10)) # 显示彩色增强 plt.subplot(2, 3, 1) plt.imshow(images[0]) plt.title(titles[0]) plt.axis('off') for i, (img, title) in enumerate(zip(enhancements[3:], titles[4:])): plt.subplot(2, 3, i+2) plt.imshow(img) plt.title(title) plt.axis('off') # 显示灰度增强 for i, (img, title) in enumerate(zip(gray_images, gray_titles)): plt.subplot(2, 3, i+4) plt.imshow(img, cmap='gray') plt.title(title) plt.axis('off') plt.tight_layout() plt.show() # 演示增强技术 demonstrate_enhancement(test_img)5. 图像分割与特征提取
5.1 阈值分割技术
图像分割是将图像分成有意义的区域的过程:
def thresholding_techniques(image): """ 各种阈值分割方法 """ gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 全局阈值 _, global_thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # Otsu's 阈值 _, otsu_thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU) # 自适应阈值 adaptive_thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2) return gray, global_thresh, otsu_thresh, adaptive_thresh def demonstrate_thresholding(image): thresholds = thresholding_techniques(image) images = list(thresholds) titles = [ '灰度原图', '全局阈值(127)', "Otsu's阈值", '自适应阈值' ] display_images(images, titles, figsize=(15, 10)) # 创建适合阈值分割的测试图像 def create_threshold_test_image(): img = np.zeros((300, 300), dtype=np.uint8) # 添加不同亮度的区域 cv2.rectangle(img, (50, 50), (100, 100), 100, -1) # 暗区域 cv2.rectangle(img, (150, 50), (200, 100), 150, -1) # 中等亮度 cv2.rectangle(img, (250, 50), (300, 100), 200, -1) # 亮区域 # 添加高斯噪声 noise = np.random.normal(0, 25, img.shape).astype(np.uint8) noisy_img = cv2.add(img, noise) return noisy_img threshold_test = create_threshold_test_image() demonstrate_thresholding(threshold_test)5.2 轮廓检测与形状分析
轮廓检测用于识别图像中的物体边界:
def contour_detection_analysis(image): """ 轮廓检测与形状分析 """ # 转换为灰度并二值化 gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 查找轮廓 contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) # 在原图上绘制轮廓 contour_image = image.copy() cv2.drawContours(contour_image, contours, -1, (0, 255, 0), 2) # 分析每个轮廓 contour_info = [] for i, contour in enumerate(contours): # 计算轮廓面积 area = cv2.contourArea(contour) # 计算轮廓周长 perimeter = cv2.arcLength(contour, True) # 轮廓近似 epsilon = 0.02 * perimeter approx = cv2.approxPolyDP(contour, epsilon, True) # 边界矩形 x, y, w, h = cv2.boundingRect(contour) contour_info.append({ 'index': i, 'area': area, 'perimeter': perimeter, 'approx_points': len(approx), 'bounding_rect': (x, y, w, h) }) return binary, contour_image, contours, contour_info def demonstrate_contours(image): binary, contour_img, contours, info = contour_detection_analysis(image) # 创建分析结果图像 analysis_img = image.copy() for i, data in enumerate(info): if data['area'] > 100: # 只显示面积较大的轮廓 x, y, w, h = data['bounding_rect'] # 绘制边界矩形 cv2.rectangle(analysis_img, (x, y), (x+w, y+h), (255, 0, 0), 2) # 添加文本信息 text = f"Area: {data['area']:.0f}" cv2.putText(analysis_img, text, (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 1) images = [image, binary, contour_img, analysis_img] titles = ['原图', '二值图', '轮廓检测', '形状分析'] display_images(images, titles) # 打印轮廓信息 print("轮廓分析结果:") for data in info: if data['area'] > 100: print(f"轮廓{data['index']}: 面积={data['area']:.1f}, 周长={data['perimeter']:.1f}, " f"近似点数={data['approx_points']}") # 创建包含多个形状的测试图像 def create_shape_test_image(): img = np.zeros((400, 400, 3), dtype=np.uint8) # 绘制不同形状 cv2.rectangle(img, (50, 50), (150, 150), (255, 255, 255), -1) # 正方形 cv2.circle(img, (300, 100), 50, (255, 255, 255), -1) # 圆形 cv2.ellipse(img, (200, 250), (80, 40), 0, 0, 360, (255, 255, 255), -1) # 椭圆 # 绘制三角形 pts = np.array([[350, 250], [320, 320], [380, 320]], np.int32) cv2.fillPoly(img, [pts], (255, 255, 255)) return img shape_test = create_shape_test_image() demonstrate_contours(shape_test)6. 完整图像处理项目实战
6.1 项目需求分析:智能图像分析工具
我们将开发一个完整的图像处理工具,具备以下功能:
- 图像基本信息分析
- 自动色彩增强
- 物体检测与计数
- 图像质量评估
- 批量处理支持
6.2 项目架构设计
import os import json from datetime import datetime from typing import Dict, List, Tuple class ImageAnalyzer: """ 智能图像分析器主类 """ def __init__(self): self.supported_formats = ['.jpg', '.jpeg', '.png', '.bmp', '.tiff'] self.analysis_results = {} def load_image(self, image_path: str) -> np.ndarray: """加载图像文件""" if not os.path.exists(image_path): raise FileNotFoundError(f"图像文件不存在: {image_path}") _, ext = os.path.splitext(image_path) if ext.lower() not in self.supported_formats: raise ValueError(f"不支持的图像格式: {ext}") image = cv2.imread(image_path) if image is None: raise ValueError("无法读取图像文件") return cv2.cvtColor(image, cv2.COLOR_BGR2RGB) def analyze_basic_properties(self, image: np.ndarray) -> Dict: """分析图像基本属性""" height, width, channels = image.shape return { 'dimensions': f"{width} x {height}", 'channels': channels, 'total_pixels': width * height, 'file_size_estimate': image.nbytes, 'data_type': str(image.dtype), 'color_mean': [float(image[:,:,i].mean()) for i in range(channels)], 'color_std': [float(image[:,:,i].std()) for i in range(channels)] } def enhance_image(self, image: np.ndarray, method: str = 'auto') -> np.ndarray: """图像增强""" if method == 'auto': # 自动选择增强方法 if image.std() < 30: # 低对比度图像 # 使用CLAHE增强对比度 lab = cv2.cvtColor(image, cv2.COLOR_RGB2LAB) clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8)) lab[:,:,0] = clahe.apply(lab[:,:,0]) enhanced = cv2.cvtColor(lab, cv2.COLOR_LAB2RGB) else: # 轻度伽马校正 gamma = 1.2 table = np.array([((i / 255.0) ** (1.0/gamma)) * 255 for i in np.arange(0, 256)]).astype("uint8") enhanced = cv2.LUT(image, table) elif method == 'histogram_equalization': # 直方图均衡化 lab = cv2.cvtColor(image, cv2.COLOR_RGB2LAB) lab[:,:,0] = cv2.equalizeHist(lab[:,:,0]) enhanced = cv2.cvtColor(lab, cv2.COLOR_LAB2RGB) else: enhanced = image.copy() return enhanced def detect_objects(self, image: np.ndarray, min_area: int = 100) -> Dict: """简单物体检测""" gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) blurred = cv2.GaussianBlur(gray, (5, 5), 0) # 自适应阈值 binary = cv2.adaptiveThreshold(blurred, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 形态学操作去除噪声 kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3)) binary = cv2.morphologyEx(binary, cv2.MORPH_CLOSE, kernel) # 查找轮廓 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) objects = [] result_image = image.copy() for i, contour in enumerate(contours): area = cv2.contourArea(contour) if area > min_area: # 计算边界框 x, y, w, h = cv2.boundingRect(contour) # 计算中心点 center_x = x + w // 2 center_y = y + h // 2 objects.append({ 'id': i, 'area': area, 'bounding_box': (x, y, w, h), 'center': (center_x, center_y) }) # 在图像上绘制 cv2.rectangle(result_image, (x, y), (x+w, y+h), (0, 255, 0), 2) cv2.putText(result_image, f'Obj{i}', (x, y-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1) return { 'object_count': len(objects), 'objects': objects, 'annotated_image': result_image } def assess_quality(self, image: np.ndarray) -> Dict: """图像质量评估""" gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY) # 计算清晰度(使用拉普拉斯方差) sharpness = cv2.Laplacian(gray, cv2.CV_64F).var() # 计算对比度 contrast = gray.std() # 计算亮度 brightness = gray.mean() # 评估结果 quality_score = (sharpness / 1000 + contrast / 50 + (128 - abs(brightness - 128)) / 128) / 3 return { 'sharpness': sharpness, 'contrast': contrast, 'brightness': brightness, 'quality_score': quality_score, 'quality_level': '优秀' if quality_score > 0.7 else '良好' if quality_score > 0.5 else '一般' } def comprehensive_analysis(self, image_path: str) -> Dict: """综合图像分析""" try: # 加载图像 image = self.load_image(image_path) # 基本属性分析 basic_props = self.analyze_basic_properties(image) # 图像增强 enhanced_image = self.enhance_image(image) # 物体检测 object_detection = self.detect_objects(image) # 质量评估 quality_assessment = self.assess_quality(image) # 生成分析报告 analysis_report = { 'timestamp': datetime.now().isoformat(), 'filename': os.path.basename(image_path), 'basic_properties': basic_props, 'quality_assessment': quality_assessment, 'object_detection': { 'count': object_detection['object_count'], 'objects': object_detection['objects'] }, 'enhancement_applied': True } # 保存结果图像 result_images = { 'original': image, 'enhanced': enhanced_image, 'annotated': object_detection['annotated_image'] } return { 'report': analysis_report, 'images': result_images, 'success': True } except Exception as e: return { 'success': False, 'error': str(e) }6.3 项目使用示例
def demonstrate_image_analyzer(): """演示图像分析器的使用""" # 创建分析器实例 analyzer = ImageAnalyzer() # 使用测试图像 test_image = create_test_image() # 保存测试图像 cv2.imwrite('test_analysis.jpg', cv2.cvtColor(test_image, cv2.COLOR_RGB2BGR)) # 进行分析 result = analyzer.comprehensive_analysis('test_analysis.jpg') if result['success']: # 显示分析结果 report = result['report'] images = result['images'] print("=== 图像分析报告 ===") print(f"文件名: {report['filename']}") print(f"分析时间: {report['timestamp']}") print(f"图像尺寸: {report['basic_properties']['dimensions']}") print(f"检测到物体数量: {report['object_detection']['count']}") print(f"质量评估: {report['quality_assessment']['quality_level']} " f"(得分: {report['quality_assessment']['quality_score']:.2f})") # 显示图像对比 display_images( [images['original'], images['enhanced'], images['annotated']], ['原图', '增强后', '物体检测'], figsize=(15, 5) ) # 显示详细统计信息 print("\n=== 详细统计 ===") props = report['basic_properties'] print(f"总像素: {props['total_pixels']}") print(f"红色通道均值: {props['color_mean'][0]:.1f} ± {props['color_std'][0]:.1f}") print(f"绿色通道均值: {props['color_mean'][1]:.1f} ± {props['color_std'][1]:.1f}") print(f"蓝色通道均值: {props['color_mean'][2]:.1f} ± {props['color_std'][2]:.1f}") else: print(f"分析失败: {result['error']}") # 清理临时文件 if os.path.exists('test_analysis.jpg'): os.remove('test_analysis.jpg') # 运行演示 demonstrate_image_analyzer()7. 批量图像处理与性能优化
7.1 批量处理实现
在实际项目中,经常需要处理大量图像:
class BatchImageProcessor: """ 批量图像处理器 """ def __init__(self, input_dir: str, output_dir: str): self.input_dir = input_dir self.output_dir = output_dir self.analyzer = ImageAnalyzer() # 创建输出目录 os.makedirs(output_dir, exist_ok=True) def process_directory(self, enhancement=True, detection=True, resize=None, format='jpg') -> Dict: """处理整个目录的图像""" image_files = self._find_image_files() results = { 'processed': 0, 'failed': 0, 'details': [], 'total_time': 0 } start_time = datetime.now() for filename in image_files: try: result = self._process_single_file(filename, enhancement, detection, resize, format) results['details'].append(result) results['processed'] += 1 except Exception as e: results['details'].append({ 'filename': filename, 'success': False, 'error': str(e) }) results['failed'] += 1 results['total_time'] = (datetime.now() - start_time).total_seconds() return results def _find_image_files(self) -> List[str]: """查找目录中的图像文件""" supported = self.analyzer.supported_formats image_files = [] for file in os.listdir(self.input_dir): if any(file.lower().endswith(ext) for ext in supported): image_files.append(file) return sorted(image_files) def _process_single_file(self, filename: str, enhancement: bool, detection: bool, resize: Tuple, format: str) -> Dict: """处理单个图像文件""" input_path = os.path.join(self.input_dir, filename) # 加载图像 image = self.analyzer.load_image(input_path) # 应用处理 if enhancement: image = self.analyzer.enhance_image(image) if resize: image = resize_image(image, resize) # 物体检测(可选) detection_result = None if detection: detection_result = self.analyzer.detect_objects(image) output_image = detection_result['annotated_image'] else: output_image = image # 保存结果 output_filename = f"processed_{os.path.splitext(filename)[0]}.{format}" output_path = os.path.join(self.output_dir, output_filename) # 转换回BGR格式保存 output_bgr = cv2.cvtColor(output_image, cv2.COLOR_RGB2BGR) cv2.imwrite(output_path, output_bgr) # 生成处理报告 basic_props = self.analyzer.analyze_basic_properties(image) quality = self.analyzer.assess_quality(image) return