How to save (cvWrite or imwrite) an image in OpenCV 2.4.3?

Sisay picture Sisay · Apr 17, 2013 · Viewed 27.9k times · Source

I am trying to save an OpenCV image to the hard drive.

Here is what I tried:

public void SaveImage (Mat mat) {
  Mat mIntermediateMat = new Mat();

  Imgproc.cvtColor(mRgba, mIntermediateMat, Imgproc.COLOR_RGBA2BGR, 3);

  File path =
    Environment.getExternalStoragePublicDirectory(
    Environment.DIRECTORY_PICTURES);
  String filename = "barry.png";
  File file = new File(path, filename);

  Boolean bool = null;
  filename = file.toString();
  bool = Highgui.imwrite(filename, mIntermediateMat);

  if (bool == true)
    Log.d(TAG, "SUCCESS writing image to external storage");
    else
    Log.d(TAG, "Fail writing image to external storage");
  }
}

Can any one show how to save that image with OpenCV 2.4.3?

Answer

alrikai picture alrikai · Apr 17, 2013

Your question is a bit confusing, as your question is concerning OpenCV on the desktop, but your code is for Android, and you ask about IplImage, but your posted code is using C++ and Mat. Assuming you're on the desktop using C++, you can do something along the lines of:

cv::Mat image;
std::string image_path;
//load/generate your image and set your output file path/name
//...

//write your Mat to disk as an image
cv::imwrite(image_path, image);

...Or for a more complete example:

void SaveImage(cv::Mat mat)
{
    cv::Mat img;     
    cv::cvtColor(...); //not sure where the variables in your example come from
    std::string store_path("..."); //put your output path here       

    bool write_success = cv::imwrite(store_path, img);
    //do your logging... 
}

The image format is chosen based on the supplied filename, e.g. if your store_path string was "output_image.png", then imwrite would save it was a PNG image. You can see the list of valid extensions at the OpenCV docs.

One caveat to be aware of when writing images to disk with OpenCV is that the scaling will differ depending on the Mat type; that is, for floats the images are expected to be within the range [0, 1], while for say, unsigned chars they'll be from [0, 256).

For IplImages, I'd advise just switching to use Mat, as the old C-interface is deprecated. You can convert an IplImage to a Mat via cvarrToMat then use the Mat, e.g.

IplImage* oldC0 = cvCreateImage(cvSize(320,240),16,1);
Mat newC = cvarrToMat(oldC0);
//now can use cv::imwrite with newC

alternately, you can convert an IplImage to a Mat just with

Mat newC(oldC0); //where newC is a Mat and oldC0 is your IplImage

Also I just noticed this tutorial at the OpenCV website, which gives you a walk-though on loading and saving images in a (desktop) environment.