How to get the Mat object from the Byte[] in openCV android?

后端 未结 5 2075
梦谈多话
梦谈多话 2020-12-29 10:46

I am working with OpenCV library in Android. I have a class which implements PictureCallBack.

The override method onPictureTaken() is as g

相关标签:
5条回答
  • 2020-12-29 10:58

    opencv has a neat way to writing Mats to files - it can generate different formats based on the file extension provided. Here is a minimal example:

        public void writeImageToFile(Mat image, String filename) {
    
        File root = Environment.getExternalStorageDirectory();
        File file = new File(root, filename);
    
        Highgui.imwrite(file.getAbsolutePath(), image);
    
        if (DEBUG)
            Log.d(TAG,
                    "writing: " + file.getAbsolutePath() + " (" + image.width()
                            + ", " + image.height() + ")");
    }
    

    if red and blue is swapped then it sounds like your byte data from onPictureTaken() is in BGRA format. You can swap it to RGBA using:

    Imgproc.cvtColor(bgrImg, rgbImg, Imgproc.COLOR_BGR2RGB);
    

    the format is actually device specific - on one device I had it comes through as YUV.

    0 讨论(0)
  • 2020-12-29 11:03

    You can use the imdecode method which comes as part of opencv (this is for emgucv but it should have a similar operation on other versions of opencv, syntax might just be different)

    Example:

    byte [] imageArray
    Mat dest
    
    CvInvoke.Imdecode(imageArray, ImreadModes.Unchanged, dest)
    
    0 讨论(0)
  • 2020-12-29 11:06

    For me, the next works fine for me:

    Java side:

        Bitmap bitmap = mTextureView.getBitmap(mWidth, mHeight);
        int[] argb = new int[mWidth * mHeight];
        // get ARGB pixels and then proccess it with 8UC4 OpenCV convertion
        bitmap.getPixels(argb, 0, mWidth, 0, 0, mWidth, mHeight);
        // native method (NDK or CMake)
        processFrame8UC4(argb, mWidth, mHeight);
    

    OpenCV side (NDK):

    JNIEXPORT jint JNICALL com_native_detector_Utils_processFrame8UC4
        (JNIEnv *env, jobject object, jint width, jint height, jintArray frame) {
    
        jint *pFrameData = env->GetIntArrayElements(frame, 0);
        // it is the line:
        Mat mFrame = Mat(height,width,CV_8UC4,pFrameData).clone();
        // your code..
        env->ReleaseIntArrayElements(frame, pFrameData, 0);
    
    }
    
    0 讨论(0)
  • 2020-12-29 11:07

    The best and easiest way is like this:

    byte[] bytes = FileUtils.readFileToByteArray(new File("aaa.jpg"));
    Mat mat = Imgcodecs.imdecode(new MatOfByte(bytes), Imgcodecs.CV_LOAD_IMAGE_UNCHANGED);
    
    0 讨论(0)
  • 2020-12-29 11:11

    You have to specify width and height of the image/Mat and channels depth.

    Mat mat = new Mat(width, height, CvType.CV_8UC3);
    mat.put(0, 0, data);
    

    Make sure you are using correct type of Mat. Maybe your data is not in 3 bytes RGB format and you should use another type e.g. CvType.CV_8UC1.
    Good luck!

    0 讨论(0)
提交回复
热议问题