cv2.imwrite无报错但也没有保存图片

【问题】

在使用SAM2分割图片的时候,想要把mask保存下来,于是使用下列代码

masks, scores, logits = predictor.predict(
    point_coords=input_point,
    point_labels=input_label,
    multimask_output=True,
)
sorted_ind = np.argsort(scores)[::-1]
masks = masks[sorted_ind]
cv2.imwrite('./test.jpg', masks*255)

(除了最后一行,其他都是截取自SAM2官方文档)

结果是没有报错,图片也没有保存下来

分析

v = cv2.imwrite('./test.jpg', masks*255)
print(v)

用上面的代码打印出imwrite的返回值,发现是False

一般有两种原因,一是路径错误,二是图像格式不对。这里路径显然是没有问题的,那么问题应该就出在masks的格式上。

启动调试,查看masks变量,发现它是numpy ndarray格式(符合opencv的要求),size为[3, 1200, 1800],对应[C, H, W],这就是问题所在,因为opencv保存时图像尺寸要求为[H, W, C],所以只要对masks做一下变换就可以了。操作如下。

解决方法

masks = masks[sorted_ind]
masks_cv2 = np.transpose(masks, (1, 2, 0))
cv2.imwrite('./test.jpg', masks_cv2*255)

在保存前使用np.transpose对masks进行处理,交换不同维度的顺序,调整为[H, W, C]即可

再次运行就成功保存了mask图片

### C++ OpenCV `imwrite` 方法无法保存图像的原因分析 当遇到 `cv2.imwrite` 或者其对应的 C++ API `cv::imwrite()` 无法正常工作的情况时,通常有几种常见原因可能导致此问题的发生[^1]。 #### 图像路径错误 如果指定的文件路径不正确或不可访问,则函数将不会抛出异常而是简单地返回 false。因此建议先验证目标路径的有效性和可写权限。 ```cpp std::string filename = "output.jpg"; if (!cv::utils::fs::exists(filename)) { std::cout << "Path does not exist or cannot be accessed." << std::endl; } ``` #### 文件扩展名缺失或不匹配 OpenCV 需要明确知道所处理的是哪种类型的图像格式。这取决于所提供的文件名中的扩展部分。如果不提供有效的扩展名或将不同格式的数据强制转换成另一种格式可能会导致失败。 ```cpp // 正确做法:带有适当扩展名 bool result = cv::imwrite("image.png", img); // 错误示范:缺少扩展名或使用了不适合当前编码参数的扩展名 result = cv::imwrite("image_without_extension", img); ``` #### 编码参数设置不当 对于某些特定格式(如JPEG),可能还需要额外配置相应的压缩质量等选项来确保成功写出文件。 ```cpp std::vector<int> compression_params; compression_params.push_back(cv::IMWRITE_JPEG_QUALITY); compression_params.push_back(95); bool success = cv::imwrite("high_quality_image.jpg", image, compression_params); ``` #### 输入矩阵为空或数据损坏 最后还需确认输入给 `imwrite` 的 Mat 对象确实包含了有效的内容而不是空指针或是已经破坏的数据结构。 ```cpp if(image.empty()){ std::cerr<<"Image data is empty!"<<std::endl; }else{ bool ret = imwrite("savedImage.bmp", image); if(!ret){ std::cerr<<"Failed to write the file"<<std::endl; } } ``` 通过以上几个方面排查可以有效地定位并解决问题所在之处。另外值得注意的是,在较新的版本里,OpenCV 已经不再支持 Python 中使用的 `cv2.imwrite` 形式的命名方式;相反应该采用标准库的形式调用 `cv::imwrite` 函数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值