保姆级教程:用Python修复GitHub上的NIQE代码,批量计算图片质量指标
保姆级教程:用Python修复GitHub上的NIQE代码,批量计算图片质量指标
图像质量评估是计算机视觉领域的重要研究方向,NIQE(Natural Image Quality Evaluator)作为一种无参考图像质量评价算法,能够在不依赖原始图像的情况下评估失真图像的质量。本文将手把手教你修复GitHub上常见的NIQE实现代码问题,并扩展其功能实现批量处理。
1. 环境准备与依赖安装
在开始修复代码前,我们需要确保开发环境配置正确。NIQE算法依赖于多个科学计算库,以下是必须安装的Python包:
pip install numpy scipy scikit-image pillow注意:建议使用Python 3.7及以上版本,某些库在新版本中API可能有变化。如果遇到兼容性问题,可以创建虚拟环境:
python -m venv niqe_env source niqe_env/bin/activate # Linux/Mac niqe_env\Scripts\activate # Windows2. 原始代码问题分析与修复
从GitHub获取的NIQE实现通常存在几个典型问题:
2.1 imsize错误解析
原始代码最常见的报错是imsize相关错误,这通常由于:
- 图像尺寸不满足算法最小要求(192x192像素)
- 图像通道数处理不当
- 类型转换问题
修复后的图像加载代码应包含尺寸检查和预处理:
def load_image(image_path): img = Image.open(image_path) if img.mode != 'L': img = img.convert('L') # 转换为灰度图 img_array = np.array(img) # 检查最小尺寸 min_size = 192 if img_array.shape[0] < min_size or img_array.shape[1] < min_size: print(f"Warning: Image size {img_array.shape} is too small, resizing...") scale = max(min_size/img_array.shape[0], min_size/img_array.shape[1]) new_size = (int(img_array.shape[1]*scale), int(img_array.shape[0]*scale)) img = img.resize(new_size, Image.BICUBIC) img_array = np.array(img) return img_array2.2 依赖库API变更处理
原始代码可能使用已弃用的API,如scipy.misc.imresize。现代替代方案:
from skimage.transform import resize # 替换旧版imresize img_resized = resize(img_array, (new_height, new_width), mode='constant', anti_aliasing=True)3. 批量处理功能实现
我们将扩展原始单图处理功能,实现文件夹批量处理并输出统计结果:
3.1 文件遍历与处理框架
def batch_process(folder_path, output_file='results.csv'): supported_formats = ('.png', '.jpg', '.jpeg', '.bmp') image_files = [f for f in os.listdir(folder_path) if f.lower().endswith(supported_formats)] results = [] for idx, img_file in enumerate(image_files, 1): try: img_path = os.path.join(folder_path, img_file) img_array = load_image(img_path) score = niqe(img_array) results.append((img_file, score)) print(f"Processed {idx}/{len(image_files)}: {img_file} - NIQE: {score:.2f}") except Exception as e: print(f"Error processing {img_file}: {str(e)}") # 保存结果 df = pd.DataFrame(results, columns=['Filename', 'NIQE']) df.to_csv(output_file, index=False) # 计算统计量 stats = { 'mean': df['NIQE'].mean(), 'median': df['NIQE'].median(), 'std': df['NIQE'].std(), 'min': df['NIQE'].min(), 'max': df['NIQE'].max() } return df, stats3.2 结果可视化(可选)
添加matplotlib可视化支持:
import matplotlib.pyplot as plt def plot_results(df, stats): plt.figure(figsize=(12, 6)) # 分数分布直方图 plt.subplot(1, 2, 1) plt.hist(df['NIQE'], bins=20, edgecolor='black') plt.axvline(stats['mean'], color='r', linestyle='--', label=f"Mean: {stats['mean']:.2f}") plt.xlabel('NIQE Score') plt.ylabel('Count') plt.title('NIQE Score Distribution') plt.legend() # 分数排序图 plt.subplot(1, 2, 2) sorted_scores = df.sort_values('NIQE')['NIQE'].values plt.plot(sorted_scores, 'o-') plt.xlabel('Image Index (sorted)') plt.ylabel('NIQE Score') plt.title('Sorted NIQE Scores') plt.tight_layout() plt.savefig('niqe_results.png') plt.close()4. 完整工作流与性能优化
4.1 完整修复版代码结构
建议将代码组织为以下模块:
niqe_toolkit/ ├── __init__.py ├── core.py # 核心算法实现 ├── utils.py # 工具函数 ├── cli.py # 命令行接口 └── params/ # 模型参数 └── niqe_image_params.mat4.2 多进程加速
对于大量图像,可以使用多进程处理:
from multiprocessing import Pool def process_single(args): img_file, folder_path = args try: img_path = os.path.join(folder_path, img_file) img_array = load_image(img_path) return (img_file, niqe(img_array)) except Exception as e: print(f"Error processing {img_file}: {str(e)}") return (img_file, None) def batch_process_parallel(folder_path, workers=4): image_files = [f for f in os.listdir(folder_path) if f.lower().endswith(('.png', '.jpg', '.jpeg'))] with Pool(workers) as p: results = p.map(process_single, [(img, folder_path) for img in image_files]) valid_results = [r for r in results if r[1] is not None] df = pd.DataFrame(valid_results, columns=['Filename', 'NIQE']) return df4.3 常见错误处理
完善错误处理机制:
| 错误类型 | 可能原因 | 解决方案 |
|---|---|---|
| 尺寸错误 | 图像小于192x192 | 自动放大或跳过 |
| 内存不足 | 处理超大图像 | 添加图像尺寸限制 |
| 文件损坏 | 无效图像文件 | 捕获异常并记录 |
| 参数缺失 | 缺少.mat参数文件 | 检查文件路径 |
5. 实际应用案例
5.1 监控图像质量退化
# 监控摄像头画面质量变化 def monitor_camera_quality(camera_url, interval=60, duration=3600): import cv2 import time timestamps = [] scores = [] start_time = time.time() cap = cv2.VideoCapture(camera_url) while (time.time() - start_time) < duration: ret, frame = cap.read() if not ret: print("Failed to capture frame") time.sleep(interval) continue # 转换为PIL格式 frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) img = Image.fromarray(frame) img_array = np.array(img.convert('L')) score = niqe(img_array) timestamps.append(time.strftime("%Y-%m-%d %H:%M:%S")) scores.append(score) print(f"{timestamps[-1]} - Quality Score: {score:.2f}") time.sleep(interval) return pd.DataFrame({'Timestamp': timestamps, 'NIQE': scores})5.2 图像增强算法评估
def evaluate_enhancement(original_img, enhanced_img): """ 比较增强前后的质量变化 """ orig_score = niqe(original_img) enh_score = niqe(enhanced_img) print(f"Original NIQE: {orig_score:.2f}") print(f"Enhanced NIQE: {enh_score:.2f}") print(f"Improvement: {(orig_score - enh_score):.2f} ({((orig_score - enh_score)/orig_score)*100:.1f}%)") return { 'original': orig_score, 'enhanced': enh_score, 'improvement': orig_score - enh_score }在图像处理项目中,NIQE分数通常与主观评价有较高相关性。根据经验,当NIQE分数降低超过15%时,人眼通常能明显感知到质量改善。
