This example code will display the image created correctly, but will save a png with only black pixels. The Mat is in CV_32FC3 format, so 3 chann
I came to this question, because I also had a problem with black ".png" images. Eventually I realised, that my 32 bit image with channels (Red, Green, Blue, Alpha) had a zero-valued alpha channel (full transparency). Thus, programs that are aware of transparency just show the "black background behind the image". After changing transparency to "255" (no transparency) my saved png-image could be visualized just fine:
MyImage[:,:,3] = 255
You can check that behaviour by assigning a value of 127 and you'll get a pale/greyed version of your image.
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.