在opencv中使用imwrite保存图像会写入所有黑色,但会正确显示im

时间:2016-05-04 11:32:03

标签: c++ opencv

原始问题

此示例代码将显示正确创建的图像,但会保存仅包含黑色像素的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;
}

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

Berriel的解决方案

#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;
    }

2 个答案:

答案 0 :(得分:14)

您可以阅读documentation

  

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]映射到   [0255]。
  •   
  • 如果图像是32位浮点,则像素值乘以255.也就是说,值范围[0,1]被映射到   [0255]
  •   

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

答案 1 :(得分:0)

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

MyImage[:,:,3] = 255

您可以通过将值设置为127来检查该行为,然后获得图像的浅灰色/灰色版本。