Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OpenCV Android imwrite give me a blue image

I have implemented a camera using CvCameraViewListener2, when I do imwrite, the picture save turn blue Here is my code

public Mat onCameraFrame(final CvCameraViewFrame inputFrame) {
    img_rgb = inputFrame.rgba();

    return img_rgb;

}

public void captureImage(View v){
    Mat mInter= new Mat(img_rgb.width(),img_rgb.height(),CvType.CV_32FC3);
    File path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    String filename = "temp.jpg";
    File file = new File(path, filename);
    Boolean bool = null;
    filename = file.toString();
    if(img_rgb.height() > img_rgb.width()){
        Core.flip(img_rgb,mInter,1);
        bool = Imgcodecs.imwrite(filename, mInter);
    }
    else{
    bool = Imgcodecs.imwrite(filename,mInter);}
    if (bool == true)
        Log.i(TAG, "SUCCESS writing image to external storage");
    else
        Log.i(TAG, "Fail writing image to external storage");
    String PathName = "";
    Intent i = new Intent(getApplication(),Result.class);
    i.putExtra(EXTRA_MESSAGE ,filename);
    startActivity(i); 

And the result:

enter image description here

I cannot find the problem, I have try to convert mat into other color but no result.

like image 310
adams Avatar asked Apr 04 '16 12:04

adams


1 Answers

  1. According to documentation for flip function : http://docs.opencv.org/java/2.4.2/org/opencv/core/Core.html#flip(org.opencv.core.Mat, org.opencv.core.Mat, int) mInter should have same type as img_rgb, which has type CvType.CV_32FC4. So correct initialization will be

    Mat mInter = new Mat(img_rgb.width(), img_rgb.height(), CvType.CV_32FC4);
    
  2. In case if(img_rgb.height() > img_rgb.width()) is false, mInter contains empty image. So you should save img_rgb :

    else bool = Imgcodecs.imwrite(filename, img_rgb);
    
  3. Imwrite docs http://docs.opencv.org/3.0-beta/modules/imgcodecs/doc/reading_and_writing_images.html:

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.

So you need to convert it from rgba to bgr using convert :

cv::cvtColor (input, input_bgr, CV_RGBA2BGR)
  1. img_rgb can be used from different threads, so synchronization should be added.
like image 149
taarraas Avatar answered Oct 17 '22 17:10

taarraas