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

USE*_*UNK 10 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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;
    }
Run Code Online (Sandbox Code Playgroud)

Ber*_*iel 14

正如您可以在文档中阅读:

函数imwrite将图像保存到指定的文件.基于文件扩展名选择图像格式(请参阅imread()以获取扩展名列表).使用此功能时,只能保存8位(或PNG,JPEG 2000和TIFF情况下的16位无符号(CV_16U))单通道或3通道(带'BGR'通道顺序)图像.如果格式,深度或通道顺序不同,请使用Mat :: convertTo()和cvtColor()在保存之前进行转换.

您应该使用convertTo转换从CV_32FC3CV_8UC3获得相同的结果:

Mat3b imageF_8UC3;
imageF.convertTo(imageF_8UC3, CV_8UC3, 255);
imwrite("test.png", imageF_8UC3);
Run Code Online (Sandbox Code Playgroud)

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

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

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