OpenCV imwrite not writing image - c++

I was trying to write an image to a folder using OpenCV imwrite function.
The code compiles and runs successfully but the image is not saving in the folder/path.I am getting output from 'imshow' and my image is in CV_8UC1 format.
find the code below
Mat reflection = function which computes image
imshow("output image", reflection);
imwrite("E:/New folder/img.bmp", reflection);
so I checked current folder writing and modified code like this
bool check = imwrite("./img.bmp", reflection);
this 'bool check' status is 'false' and not writing the image.
I've also checked folder permission with guidelines from microsoft help my "E/New Folder/" is permitted to write. still, the image is not saving.
I am okay with any image format .jpg, .png and .bmp.
I am using windows 7, OpenCV 3.0, visual studio 2017.
Please help me and thanks for reading it

Opencv doesn't seem to support saving BMP files check the imwrite docs. Changing the filename to img.png should work. Also using ./ in windows is not valid, this is used in unix systems to represent the current working directory see Windows current directory.
Updating it to
bool check = imwrite(".\img.png", reflection);
or
bool check = imwrite("img.png", reflection);
Should work

OpenCV do support bmp, just use as follows.
bool check = imwrite("img.bmp", reflection);

Related

Decrease in the quality of the image in flycapture

I am using flycapture sdk sample program to capture image form the flycapture.
My problem is that when i capture the image using the flycapture installed application the size of image is about 1.3 - 1.5 Mb. But when the take the same image using my program which consist of flycapture sample program. The size of the image is about 340K to 500K(max).Image format is .tiff
There is reduction in the quality of the image due to which my program is not able to get any valuable information form the image.
Using the following approach to save the image:
FlyCapture2::Camera camera;
FlyCapture2::Image image;
camera.RetrieveBuffer(&image);
ostringstream saveImage;
saveImage << "Image-" << "-" << i << ".tiff";
image.Save(saveImage.str().c_str());
And using the windows application following the approach mentioned in the link:
http://www.ptgrey.com/Content/Images/uploaded/FlyCapture2Help/flycapture/03demoprogram/saving%20images_flycap2.html
Please let me of any other details required
I am not 100% sure about this, since the documentation I found was for Java and not c++, but it is probably very similar.
You are using :
image.Save(saveImage.str().c_str());
to save your image, but are you sure it is saved as a tiff? the documentation (the java one), doesn't go deep into this, I am not sure if it is like OpenCV's imwrite that it automatically deduces the type and does it or not. So you should check that. There was one overload that you can pass the ImageFileFormat... this should be set to the TIFF one.
Another overload let's you specify the TIFF Options... in here you may tune it to have a different compression method. Notice that there is JPEG compression method... which would make something wayyy lighter but lossy... You may try with None, or the one that OpenCV uses LZW.

Read H.265 and VP9 frame?

I'm trying to compare 3 videos that are encoded by H.264, H.265, and VP9.
All of them are made by a same YUV video.
I want to use OpenCV's function to read each frame of the video and do some comparison:
VideoCapture vCap1, vCap2, vCap3;
vCap1.open("h264.mp4");
vCap2.open("h265.mp4");
vCap3.open("vp9.webm");
Mat frame1, frame2, frame3;
while (vCap1.read(frame1) && vCap2.read(frame2) && vCap3.read(frame3))
{
//do something
}
The vCap1 opened successfully, but vCap2 and vCap3 won't open.
Did I miss something to include to make it work?
Or OpenCV even not support the other 2 formats?
After using google :-) I found that
http://answers.opencv.org/question/10741/videocapture-format-supported-by-opencv/
Especially you have the needed codecs installed on your system. You can visit also
http://www.fourcc.org/codecs.php
for codecs.
The documentation from OpenCV is indeed not very helpful. :-)
What I would try if you are running under linux:
strace -xfo dump
and take a look in the system calls. Maybe you can find some hints of missing codec files, used configuration files and or other failed system function calls. If so, you have a startpoint.

OpenCV imwrite() not saving image

I am trying to save an image from OpenCV on my mac and I am using the following code and so far it has not been working.
cv::imwrite("/Users/nickporter/Desktop/Gray_Image.jpg", cvImage);
Can anyone see why this might not be saving?
OpenCV does have problems in saving to JPG images sometimes, try to save to BMP instead:
cv::imwrite("/Users/nickporter/Desktop/Gray_Image.bmp", cvImage);
Also, before this, make sure you image cvImage is valid. You can check it by showing the image first:
namedWindow("image", WINDOW_AUTOSIZE);
imshow("image", cvImage);
waitKey(30);
I met the same problem and one possible reason is that the target folder to place your image. Suppose you want copy A.jpg to folder "C:\\folder1\\folder2\\", but in fact when folder2 doesn't exist, the copy cannot be successful(It is from my actual test, not from official announcement). And I solved this issue by checking whether the folder exists and create one folder if it doesn't exist. Here is some code may it help using c++ & boost::filesystem. May it help.
#include <boost/filesystem.hpp>
#include <iostream>
std::string str_target="C:\\folder1\\folder2\\img.jpg";
boost::filesystem::path path_target(str_target);
boost::filesystem::path path_folder=path_target.parent_path();//extract folder
if(!boost::filesystem::exists(path_folder)) //create folder if it doesn't exist
{
boost::filesystem::create_directory(path_folder);
}
cv::imwrite(str_target,input_img);
I also suggest to check folder permissions. Opencv quietly returns from imwrite without any exception even if output folder doesn't have write permissions.
I've just had a similar problem, loading in a jpg and trying to save it back as a jpg. Added this code and it seem to be fine now.
vector<int> compression_params;
compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
compression_params.push_back(100);
And you need to include the param in your writefile.
cv::imwrite("/Users/nickporter/Desktop/Gray_Image.jpg", cvImage, compression_params);
OpenCV 3.2 imwrite() seems to have a problem to write jpg file with Windows Debug mode. I use this way instead of imwrite().
cv::Mat cvImage;
#ifdef DEBUG
IplImage image = IplImage(cvImage);
cvSaveImage("filename.jpg", &image);
#else
cv::imwrite("filename.jpg", cvImage);
#endif
The following function can be dropped into your code to support writing out jpg images for debugging purposes.
You just need to pass in an image and a filename for it. In the function, specify a path you wish to write to & have permission to do so with.
void imageWrite(const cv::Mat &image, const std::string filename)
{
// Support for writing JPG
vector<int> compression_params;
compression_params.push_back( CV_IMWRITE_JPEG_QUALITY );
compression_params.push_back( 100 );
// This writes to the specified path
std::string path = "/path/you/provide/" + filename + ".jpg";
cv::imwrite(path, image, compression_params);
}
Although it is not true for your case. This problem may arise if the image path given as argument to the cv::imwrite function exceeds the allowed maximum path length (or possibly allowed file name length) for your system.
for linux see: https://unix.stackexchange.com/questions/32795/what-is-the-maximum-allowed-filename-and-folder-size-with-ecryptfs
for windows see: https://www.quora.com/What-is-the-maximum-character-limit-for-file-names-in-windows-10

list file extensions supported by OpenCV

In OpenCV, I see imread() and VideoCapture() both take a string to a file path of multiple extensions. Is there a way to get a list of extensions that are supported by them? For example, getting a list of "jpg", "png", "mov", "mpg", etc.? I assume this is system dependent and others have needed to query this at runtime.
Furthermore, how is support determined? If have something like the below code and the Mat I get back always seems partially corrupted (I can see a bit of the image). It doesn't seem to change regardless of the frame number I ask for. I can play this video in my video player "totem", but I'm not even sure if totem and OpenCV are even using the same codec for this file.
Mat fromVideo(std::string _videoPath, int frame) {
VideoCapture capture(_videoPath);
Mat f;
for (int i = 0; i < frame; i++) {
capture >> f;
}
return f;
}
For imread() (more info here):
Windows bitmaps - *.bmp, *.dib (always supported)
JPEG files - *.jpeg, *.jpg, *.jpe (see the Notes section)
JPEG 2000 files - *.jp2 (see the Notes section)
Portable Network Graphics - *.png (see the Notes section)
Portable image format - *.pbm, *.pgm, *.ppm (always supported)
Sun rasters - *.sr, *.ras (always supported)
TIFF files - *.tiff, *.tif (see the Notes section)
For VideoCapture():
AVI files - *.avi
It seems that AVI is the only format with decent cross-platform support. See here for more info.
Use the method cv::VideoCapture::isOpened() to make sure that the constructor was successful in initializing the VideoCapture object.
Note that even if it was possible to get a list of supported container formats from OpenCV (AVI, MKV for instance) with their typical filename extensions, you would still need to know the exact list of supported codecs (and even then the exact file you want to open might be corrupted, etc...). So a list of filename extensions is not enough to accurately describe what is internally supported by OpenCV, and the simplest solution at the OpenCV API level is this isOpened() method.
Just update:
cv::VideoCapture cap("D:\\test.mp4")
works for me.

cvLoadImage for IplImage working, but cv::imread for cv::Mat not workign

I am facing a weird issue where I am unable to read a basic image file from the filesystem using cv::imread. Hence the below results into imageInput having null data, with rows and cols set to 0.
cv::Mat imageInput = cv::Mat();
imageInput = cv::imread("abc.jpg",cv::IMREAD_COLOR);
Interestingly, after commenting out the above code, the below code is able to read the iamge:
//cv::Mat imageInput = cv::Mat();
//imageInput = cv::imread("abc.jpg",cv::IMREAD_COLOR);
IplImage *rImg;
rImg = cvLoadImage("abc.jpg", CV_LOAD_IMAGE_COLOR);
rImg gets a width of 3296, and height of 2256 as expected.
I am clueless how this is possible. Please help.
The build seems to be fine in both cases. I tried using both opencv-2.4.5 and opencv-2.4.6
I have been able to figure out the issue now.
The issue was mention of release build static libraries instead of debug-build static libraries.
Earlier for the VC++ project, I was including the following lib dependencies in debug mode : opencv_core245.lib;opencv_highgui245.lib;opencv_imgproc245.lib;opencv_video245.lib
Upon changing it to opencv_core245d.lib;opencv_highgui245d.lib;opencv_imgproc245d.lib;opencv_video245d.lib, I am able to read images using imread without any issues.