繁体   English   中英

在 opencv 中使用 imwrite 保存图像写入全黑但 imshow 显示正确

[英]Saving an image with imwrite in opencv writes all black but imshow shows correctly

原始问题

此示例代码将显示正确创建的图像,但将保存只有黑色像素的 png。 Mat 采用 CV_32FC3 格式,因此有 3 个浮动通道。

我发现的已回答问题涉及图像处理问题或错误转换或使用各种压缩保存为 jpeg。

#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace std;
using namespace cv;

int main()
{
    int i = 0;
    int j = 0;

    Vec3f intensity;
     cv::Mat imageF;
    imageF= cv::Mat::zeros(36,36,CV_32FC3);

    for(j=0;j<imageF.cols;++j){
    for(i=0;i<imageF.rows;++i){
        intensity = imageF.at<Vec3f>(j, i);
        intensity.val[2] = 0.789347;
        intensity.val[1] = 0.772673;
        intensity.val[0] = 0.692689;
        imageF.at<Vec3f>(j, i) = intensity;
    }}
    imshow("Output", imageF);  
    imwrite("test.png", imageF);

    waitKey(0);
    return 0;
}

需要进行哪些更改才能使其按预期保存?

贝瑞尔的解决方案

#include "opencv2/highgui/highgui.hpp"
#include <iostream>

using namespace std;
using namespace cv;

int main() {
    int i = 0;
    int j = 0;

    Vec3f intensity;
    cv::Mat imageF;
    cv::Mat image;
    imageF= cv::Mat::zeros(36,36,CV_32FC3);

    for(j=0; j<imageF.cols; ++j) {
        for(i=0; i<imageF.rows; ++i) {
            intensity = imageF.at<Vec3f>(j, i);
            intensity.val[2] = 0.789347;
            intensity.val[1] = 0.772673;
            intensity.val[0] = 0.692689;
            imageF.at<Vec3f>(j, i) = intensity;
            }
        }

    imshow("Output", imageF);

    Mat3b imageF_8UC3;
    imageF.convertTo(imageF_8UC3, CV_8UC3, 255);
    imwrite("test.png", imageF_8UC3);

    waitKey(0);
    return 0;
    }

正如您在文档中所读到的:

函数 imwrite 将图像保存到指定的文件中。 图像格式是根据文件扩展名选择的(有关扩展名列表,请参阅 imread())。 使用此功能只能保存 8 位(或 16 位无符号 (CV_16U),对于 PNG、JPEG 2000 和 TIFF)单通道或 3 通道(具有“BGR”通道顺序)图像。 如果格式、深度或通道顺序不同,请在保存前使用 Mat::convertTo() 和 cvtColor() 进行转换。

您应该使用convertToCV_32FC3转换为CV_8UC3以获得相同的结果:

Mat3b imageF_8UC3;
imageF.convertTo(imageF_8UC3, CV_8UC3, 255);
imwrite("test.png", imageF_8UC3);

顺便说一句, imshow()显示正确,因为...

  • 如果图像是 8 位无符号,则按原样显示。
  • 如果图像是 16 位无符号或 32 位整数,则将像素除以 256。即值范围 [0,255*256] 映射到 [0,255]。
  • 如果图像是 32 位浮点数,则像素值乘以 255。即值范围 [0,1] 映射到 [0,255]。

基本上,同样的技巧是你在写作之前需要做的。

我来到这个问题,因为我也有黑色“.png”图像的问题。 最终我意识到,我的带有通道(红色、绿色、蓝色、Alpha)的 32 位图像有一个零值的 Alpha 通道(完全透明)。 因此,知道透明度的程序只会显示“图像背后的黑色背景”。 将透明度更改为“255”(无透明度)后,我保存的 png 图像可以很好地可视化:

MyImage[:,:,3] = 255

您可以通过分配 127 的值来检查该行为,您将获得图像的苍白/灰色版本。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM