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

批量提取文件夹图像轮廓后无法保存图片,报错ValueError求助

问题根源

你遇到的ValueError是因为**plt.contour()返回的是ContourSet对象**,而不是可以直接保存的图像数值数组——scipy.misc.imsave(这个函数其实已经被官方弃用)需要的是符合形状要求的像素数组,自然会触发形状不匹配的报错。

修正方案

我们需要先把轮廓绘制到matplotlib的画布上,再通过画布保存图像,或者将画布内容转换为数组后保存。下面是两种可行的修正代码:

方案一:直接用matplotlib保存画布(最简单)

这个方法直接利用matplotlib的savefig保存绘制好轮廓的画布,不需要额外转换数组:

import matplotlib.pyplot as plt
import os
from os.path import join
from PIL import Image
import numpy as np  # 补充你缺失的numpy导入

i = 0
directory_in_str = 'C:\\directory'
directory_output = 'C:\\output_directory'

# 提前创建输出文件夹,避免保存时出错
if not os.path.exists(directory_output):
    os.makedirs(directory_output)

for file in os.listdir(directory_in_str):
    print(file)
    # 读取图像并转为灰度数组
    im = np.array(Image.open(join(directory_in_str, file)).convert('L'))
    
    # 创建与原图像尺寸匹配的画布(dpi=100是为了保证尺寸精度)
    fig, ax = plt.subplots(figsize=(im.shape[1]/100, im.shape[0]/100), dpi=100)
    # 绘制轮廓
    ax.contour(im, levels=[100], colors='black', origin='image')
    
    # 隐藏坐标轴、去掉边距,让保存的图片只保留轮廓
    ax.axis('off')
    plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
    plt.margins(0, 0)
    
    # 保存图片
    save_path = join(directory_output, f'image{i}.jpg')
    plt.savefig(save_path, bbox_inches='tight', pad_inches=0)
    plt.close(fig)  # 关闭画布释放内存,避免内存泄漏
    
    i += 1
print('done')

方案二:转换为数组后用PIL保存

如果你需要拿到图像数组做后续处理,可以先把画布内容转为数组,再用PIL保存:

import matplotlib.pyplot as plt
import os
from os.path import join
from PIL import Image
import numpy as np

i = 0
directory_in_str = 'C:\\directory'
directory_output = 'C:\\output_directory'

if not os.path.exists(directory_output):
    os.makedirs(directory_output)

for file in os.listdir(directory_in_str):
    print(file)
    im = np.array(Image.open(join(directory_in_str, file)).convert('L'))
    
    fig, ax = plt.subplots(figsize=(im.shape[1]/100, im.shape[0]/100), dpi=100)
    ax.contour(im, levels=[100], colors='black', origin='image')
    ax.axis('off')
    plt.subplots_adjust(top=1, bottom=0, right=1, left=0, hspace=0, wspace=0)
    plt.margins(0, 0)
    
    # 将画布内容转为RGB数组
    fig.canvas.draw()
    data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
    data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))
    
    # 用PIL保存数组为图片
    img = Image.fromarray(data)
    img.save(join(directory_output, f'image{i}.jpg'))
    plt.close(fig)
    
    i += 1
print('done')

额外注意点

  1. 补充了numpy的导入:你之前代码里的array()其实是numpy.array(),必须导入numpy才能正常使用。
  2. 新增了输出文件夹的判断:如果目标文件夹不存在,先创建它,避免保存时抛出路径不存在的错误。
  3. 弃用了scipy.misc.imsave:这个函数已经被官方标记为弃用,用matplotlib或PIL的保存方法更稳定可靠。
  4. 调整了画布布局:隐藏坐标轴、去掉边距是为了让保存的图片只包含轮廓,没有多余的边框和轴元素。

内容的提问来源于stack exchange,提问作者Simon Kiely

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:51:54