OpenCV imwrite gives washed-out result for jpeg images

为君一笑 提交于 2019-12-28 22:50:24

问题


I am using OpenCV 3.0 and whenever I read an image and write it back the result is a washed-out image.

code:

cv::Mat img = cv::imread("dir/frogImage.jpg",-1);
cv::imwrite("dir/result.jpg",img);

Does anyone know whats causing this?

Original:

Result:


回答1:


You can try to increase the compression quality parameter as shown in OpenCV Documentation of cv::imwrite :

cv::Mat img = cv::imread("dir/frogImage.jpg",-1);

std::vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(100);

cv::imwrite("dir/result.jpg",img, compression_params);

Without specifying the compression quality manually, quality of 95% will be applied.

but 1. you don't know what jpeg compression quality your original image had (so maybe you might increase the image size) and 2. it will (afaik) still introduce additional minor artifacts, because after all it is a lossy compression method.

UPDATE your problem seems to be not because of compression artifacts but because of an image with Adobe RGB 1998 color format. OpenCV interprets the color values as they are, but instead it should scale the color values to fit the "real" RGB color space. Browser and some image viewers do apply the color format correctly, while others don't (e.g. irfanView). I used GIMP to verify. Using GIMP you can decide on startup how to interpret the color values by format, either getting your desired or your "washed out" image. OpenCV definitely doesn't care about such things, since it's not a photo editing library, so neither on reading nor on writing, color format will be handled.




回答2:


This is because you are saving the image as JPG. When doing this the OpenCV will compress the image. try to save it as PNG or BMP and no difference will be exist.

However, the IMPORTANT QUESTION : I am loading the image as jpg and saving it as JPG. So, how there is a difference?!

Yes, this is because there is many not identical compression/decompression algorithms for JPG.

if you want to get into some details see this question: Reading jpg file in OpenCV vs C# Bitmap


EDIT: You can see what I mean exactly here:

auto bmp(cv::imread("c:/Testing/stack.bmp"));
cv::imwrite("c:/Testing/stack_OpenCV.jpg", bmp);
auto jpg_opencv(cv::imread("c:/Testing/stack_OpenCV.jpg"));

auto jpg_mspaint(cv::imread("c:/Testing/stack_mspaint.jpg"));
cv::imwrite("c:/Testing/stack_mspaint_opencv.jpg", jpg_mspaint);
jpg_mspaint=(cv::imread("c:/Testing/stack_mspaint_opencv.jpg"));

cv::Mat jpg_diff;
cv::absdiff(jpg_mspaint, jpg_opencv, jpg_diff);
std::cout << cv::mean(jpg_diff);

The Result: [0.576938, 0.466718, 0.495106, 0]




回答3:


As @Micha commented:

cv::Mat img = cv::imread("dir/frogImage.jpg",-1);
cv::imwrite("dir/result.bmp",img);

I was always annoyed when mspaint.exe did the same to jpeg images. Especially for the screenshots...it ruined them everytime.



来源:https://stackoverflow.com/questions/33142786/opencv-imwrite-gives-washed-out-result-for-jpeg-images

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!