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

plt.imsave保存图像异常及CLEVR数据集生成问题排查求助

解决CLEVR数据集生成中的图像显示与物体数量异常问题

看起来你在构建自定义CLEVR风格数据集时遇到了几个典型的代码问题,我帮你逐一分析并给出修复方案:

问题1:调试时第5张图像不显示

matplotlib的plt.imshow()只是将图像数据加载到内存中的画布,不会自动弹出显示窗口。如果在循环中连续调用imshow而没有触发绘图动作,后面的图像会覆盖前面的画布内容,导致你看不到中间步骤的图像。

修复方案:

  • 如果你想每次循环都弹出单独的显示窗口,在每个plt.imshow(img)后添加plt.show()(注意:这会阻塞程序,直到你关闭当前窗口才会继续生成下一个物体);
  • 如果你想在同一个窗口中实时更新图像,可以提前开启交互式模式:
    plt.ion()  # 开启交互式模式
    
    然后在每次imshow后调用plt.draw()和plt.pause(0.1)来刷新窗口。

问题2:本地保存的图像仅含2个物体

这大概率是代码中的未捕获错误导致循环提前终止,我发现了两个关键问题:

  1. 缺少random模块导入:代码中使用了random.random()来随机选择形状,但没有导入random库,执行到这一行会直接抛出NameError,循环中断,所以只生成了前1-2个物体就停止了;
  2. 变量名不匹配:build_dataset函数的参数是loopnumber,但保存图像时写的是str(loop),loop是未定义的变量,会导致保存失败,你看到的可能是之前运行残留的旧图像。

另外还有一个隐性问题:cv2与matplotlib的颜色空间不兼容——cv2生成的图像是BGR格式,而matplotlib的imshow/imsave使用RGB格式,会导致颜色显示反转(比如你定义的红色会显示成蓝色)。

修正后的完整代码

import matplotlib.pyplot as plt
import cv2
import numpy as np
import random  # 新增导入

colors = [
    (0, 0, 255), # r (BGR格式,对应matplotlib的RGB红色)
    (0, 255, 0), # g
    (255, 0, 0), # b
    (0, 156, 255), # o
    (128, 128, 128), # k
    (0, 255, 255) # y
]
img_size = 75
size = 5

def center_generate(objects):
    while True:
        pas = True
        center = np.random.randint(0+size, img_size - size, 2)
        if len(objects) > 0:
            for name, c, shape in objects:
                # 检查新物体与已有物体的距离是否足够(避免重叠)
                if ((center - c) ** 2).sum() < ((size * 2) ** 2):
                    pas = False
        if pas:
            return center

def build_dataset(dataset_type, loopnumber):
    objects = []
    img = np.ones((img_size, img_size, 3)) * 255
    # 开启交互式模式,实时更新图像(可选)
    plt.ion()
    plt.figure()
    for color_id, color in enumerate(colors):
        center = center_generate(objects)
        shape_type = 'r' if random.random() < 0.5 else 'c'
        if shape_type == 'r':
            start = (center[0]-size, center[1]-size)
            end = (center[0]+size, center[1]+size)
            # cv2.rectangle直接修改img,不需要重新赋值
            cv2.rectangle(img, start, end, color, -1)
        else:
            center_ = (center[0], center[1])
            cv2.circle(img, center_, size, color, -1)
        
        # 转换颜色空间:BGR -> RGB
        img_rgb = cv2.cvtColor(img.astype(np.uint8), cv2.COLOR_BGR2RGB)
        plt.imshow(img_rgb)
        plt.title(f"Object {color_id+1} added")
        plt.draw()
        plt.pause(0.5)  # 暂停0.5秒查看效果
        objects.append((color_id, center, shape_type))
    
    # 保存图像时同样转换颜色空间
    img_save = cv2.cvtColor(img.astype(np.uint8), cv2.COLOR_BGR2RGB)
    save_path = f'../img/{dataset_type}/img_{loopnumber}.jpeg'
    plt.imsave(save_path, img_save)
    plt.ioff()  # 关闭交互式模式
    plt.close()

# 测试调用
build_dataset('test', 1)

额外说明

  • 我修改了cv2.rectangle和cv2.circle的赋值方式:这两个函数会直接修改传入的img数组,不需要重新赋值给img;
  • 添加了颜色空间转换,确保保存和显示的颜色与你定义的一致;
  • 调整了物体类型的记录逻辑,避免重复调用random.random()导致形状不一致;
  • 修复了保存路径的变量名问题,使用loopnumber替代未定义的loop。

内容的提问来源于stack exchange,提问作者Rishik Mani

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:40:38