Python遍历目录批量处理BMP图像 色彩分析报错解决
问题排查与可运行实现方案
报错原因
TypeError: pil_test() takes 0 positional arguments but 1 was given触发逻辑非常直接:你写的单图处理函数pil_test()定义时没有设置入参,但在批量遍历的循环里调用这个函数时,传入了图像路径作为位置参数,参数数量不匹配直接抛出异常。
前置依赖安装
先安装脚本需要的第三方库:pip install pillow matplotlib opencv-python scikit-learn numpy
完整可运行代码
代码支持单功能独立运行、双功能顺序执行,自动遍历指定目录下所有BMP文件,结果统一输出到目标目录:
import os import cv2 import numpy as np from PIL import Image import matplotlib.pyplot as plt from sklearn.cluster import KMeans # -------------------------- 配置项 按需修改 -------------------------- SOURCE_DIR = "./input_bmp" # 原始BMP图像存放目录 TARGET_DIR = "./output" # 处理结果输出目录 RUN_MODE = 3 # 运行模式:1=仅nipy_spectral色彩映射 2=仅KMeans主色提取 3=两项都执行 N_MAIN_COLOR = 5 # 提取的主色数量 # -------------------------------------------------------------------- def nipy_spectral_process(input_path, output_dir): """单图nipy_spectral色彩映射处理""" # 读取图像转灰度 gray_img = Image.open(input_path).convert('L') gray_array = np.array(gray_img) # 应用色图转换 cmap = plt.get_cmap('nipy_spectral') colored_array = cmap(gray_array / 255.0) # 转8位RGB格式保存 colored_rgb = (colored_array[:, :, :3] * 255).astype(np.uint8) base_name = os.path.splitext(os.path.basename(input_path))[0] save_path = os.path.join(output_dir, f"{base_name}_spectral.bmp") Image.fromarray(colored_rgb).save(save_path) print(f"色彩映射完成,结果保存至:{save_path}") def kmeans_maincolor_process(input_path, output_dir): """单图KMeans主色提取、占比计算与可视化""" # 读取图像转RGB格式 img = cv2.imread(input_path) img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 像素重排为聚类输入格式 pixel_data = img_rgb.reshape((-1, 3)).astype(np.float32) # 执行聚类 kmeans = KMeans(n_clusters=N_MAIN_COLOR, n_init=10, random_state=42) labels = kmeans.fit_predict(pixel_data) # 计算各主色占比 label_count = np.bincount(labels) color_ratio = label_count / len(labels) main_colors = kmeans.cluster_centers_.astype(np.uint8) # 控制台输出占比信息 base_name = os.path.splitext(os.path.basename(input_path))[0] print(f"\n===== {base_name} 主色占比统计 =====") for idx, (color, ratio) in enumerate(zip(main_colors, color_ratio)): print(f"主色{idx+1} RGB{tuple(color)}:占比 {ratio*100:.2f}%") # 生成占比可视化条 plt.figure(figsize=(8, 2)) start_pos = 0 for idx, (color, ratio) in enumerate(zip(main_colors, color_ratio)): end_pos = start_pos + ratio plt.axvspan(start_pos, end_pos, color=color/255, label=f"{ratio*100:.1f}%") start_pos = end_pos plt.xticks([]) plt.yticks([]) plt.legend(loc="upper center", bbox_to_anchor=(0.5, -0.2), ncol=N_MAIN_COLOR) save_path = os.path.join(output_dir, f"{base_name}_maincolor.png") plt.savefig(save_path, bbox_inches='tight', dpi=150) plt.close() print(f"主色可视化图保存至:{save_path}\n") if __name__ == "__main__": # 自动创建输出目录 os.makedirs(TARGET_DIR, exist_ok=True) # 筛选目录下所有BMP文件(支持大小写后缀) bmp_files = [f for f in os.listdir(SOURCE_DIR) if f.lower().endswith('.bmp')] if not bmp_files: print("源目录下未检测到BMP格式图像") exit() # 逐文件执行处理 for file_name in bmp_files: file_full_path = os.path.join(SOURCE_DIR, file_name) print(f"正在处理:{file_name}") if RUN_MODE in (1, 3): nipy_spectral_process(file_full_path, TARGET_DIR) if RUN_MODE in (2, 3): kmeans_maincolor_process(file_full_path, TARGET_DIR) print("全部文件处理完成")
使用说明
- 代码头部的配置项可按需修改,不需要改动函数内部逻辑
- 程序会自动跳过目录下非BMP格式的文件,避免读取出错
- 主色提取的聚类参数固定了随机种子,同一张图多次运行结果一致
- 色彩映射输出为BMP格式,主色可视化输出为PNG格式,两类文件不会互相覆盖
内容的提问来源于stack exchange,提问作者gregory
相关产品推荐
相关产品推荐

