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

As you can read in the documentation:

The function imwrite saves the image to the specified file. The image format is chosen based on the filename extension (see imread() for the list of extensions). Only 8-bit (or 16-bit unsigned (CV_16U) in case of PNG, JPEG 2000, and TIFF) single-channel or 3-channel (with ‘BGR’ channel order) images can be saved using this function. If the format, depth or channel order is different, use Mat::convertTo() , and cvtColor() to convert it before saving.

You should use convertTo to convert from CV_32FC3 to CV_8UC3 to get the same result:

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

By the way, imshow() displays correctly because...

  • If the image is 8-bit unsigned, it is displayed as is.
  • If the image is 16-bit unsigned or 32-bit integer, the pixels are divided by 256. That is, the value range [0,255*256] is mapped to [0,255].
  • If the image is 32-bit floating-point, the pixel values are multiplied by 255. That is, the value range [0,1] is mapped to [0,255].

Basically, the same trick is what you need to do before writing.

Tags:

C++

Opencv