原始问题
此示例代码将正确显示创建的图像,但将保存只有黑色像素的 png。垫子采用 CV_32FC3 格式,因此有 3 个 float channel 。
我发现的已回答问题涉及图像处理问题或转换不正确或以各种压缩格式保存为 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;
}
最佳答案
正如您在 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.
您应该使用 convertTo
将 CV_32FC3
转换为 CV_8UC3
以获得相同的结果:
Mat3b imageF_8UC3;
imageF.convertTo(imageF_8UC3, CV_8UC3, 255);
imwrite("test.png", imageF_8UC3);
顺便说一下,imshow()
显示正确是因为...
- 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].
基本上,同样的技巧是你在写作之前需要做的。
关于c++ - 在 opencv 中使用 imwrite 保存图像写入全黑但 imshow 显示正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37026582/