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个物体
这大概率是代码中的未捕获错误导致循环提前终止,我发现了两个关键问题:
- 缺少random模块导入:代码中使用了
random.random()来随机选择形状,但没有导入random库,执行到这一行会直接抛出NameError,循环中断,所以只生成了前1-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
相关产品推荐
相关产品推荐

