You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 16:32:30