如何使用Segment Anything Model(SAM)保存分割图像或掩码?
解决分割结果保存问题及IndexError修复
一、保存二进制掩码(最直接的方法)
二进制掩码是纯黑白的分割结果,适合后续分析或处理,代码实现简单直接:
# 创建输出目录(不存在则自动创建) output_dir = "segmentation_results" os.makedirs(output_dir, exist_ok=True) # 保存点选生成的多个掩码 for i, mask in enumerate(masks): # 将布尔型掩码转换为uint8格式(255代表前景,0代表背景) binary_mask = (mask * 255).astype(np.uint8) # 保存为PNG格式(避免压缩失真) cv2.imwrite(os.path.join(output_dir, f"mask_point_{i+1}.png"), binary_mask) # 保存框选生成的掩码 if len(masks) > 0: binary_mask_box = (masks[0] * 255).astype(np.uint8) cv2.imwrite(os.path.join(output_dir, "mask_box.png"), binary_mask_box)
二、保存带掩码的叠加图像(和显示效果一致)
如果需要保存和matplotlib显示完全一致的叠加图像,只需修改现有代码中的plt.show()为plt.savefig()即可:
修改点选掩码的循环代码:
for i, (mask, score) in enumerate(zip(masks, scores)): plt.figure(figsize=(10,10)) plt.imshow(image) show_mask(mask, plt.gca()) show_points(input_point, input_label, plt.gca()) plt.title(f"Mask {i+1}, Score: {score:.3f}", fontsize=18) plt.axis('off') # 保存图像,bbox_inches='tight'去除多余白边 plt.savefig(os.path.join(output_dir, f"overlay_point_{i+1}.png"), bbox_inches='tight', pad_inches=0) plt.close() # 关闭画布释放内存
修改框选掩码的显示代码:
plt.figure(figsize=(10, 10)) plt.imshow(image) show_mask(masks[0], plt.gca()) show_box(input_box, plt.gca()) plt.axis('off') plt.savefig(os.path.join(output_dir, "overlay_box.png"), bbox_inches='tight', pad_inches=0) plt.close()
三、IndexError的常见原因及修复
你遇到的IndexError大概率是以下情况:
- 掩码索引错误:当
multimask_output=True时,masks是(3, H, W)形状的数组,需通过masks[i]访问单个掩码;若直接把masks当作2D数组操作会报错。 - 空掩码数组:如果模型未生成有效掩码(极少发生),访问
masks[0]会报错,可先判断len(masks) > 0再处理。 - 图像维度不匹配:确保保存时掩码的尺寸和输入图像一致,SAM生成的掩码会自动匹配输入图像尺寸,只要不乱改形状就不会出问题。
内容的提问来源于stack exchange,提问作者L. Guilherme P. Melquiades
相关产品推荐
相关产品推荐

