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 channels of floats.
The answered questions I've found deal with image manipulation issues or converting incorrectly or saving in jpeg with various compression.
#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;
}
What changes need to be made to make it save as expected?
#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;
}
In this example, we will read an image, transform it and then save the image to persistent file storage using imwrite() method. import cv2 #read image as grey scale img = cv2. imread('D:/image-1. png') #do some transformations on img #save matrix/array as image file isWritten = cv2.
cv2. imwrite() method is used to save an image to any storage device. This will save the image according to the specified format in current working directory.
Does cv2 Imwrite overwrite Python? imwrite will overwrite existing files without outputting an error or asking for confirmation. Image of any format can be saved using this method.
If you are receiving a NoneType error and your code is calling cv2. imread , then the likely cause of the error is an invalid file path supplied to cv2. imread . The cv2.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With