简体   繁体   中英

OpenCV Mat to JavaCV Mat conversion

I am in the process of writing an Android application that uses JavaCV for some facial recognition. I have come across a slight problem where I need to convert from an org.opencv.core.Mat that the onCameraFrame(CvCameraViewFrame inputFrame) function returns to a org.bytedeco.javacpp.opencv_core.Mat that the org.bytedeco.javacpp.opencv_contrib.FaceRecognizer requires.

I have found similar questions here and here but neither got a working solution.

There's an easier, more efficient way documented at https://github.com/bytedeco/javacpp/issues/38#issuecomment-140728812 , in short:

To JavaCPP/JavaCV:

Mat mat2 = new Mat((Pointer)null) { { address = mat.getNativeObjAddr(); } };

To official Java API of OpenCV:

Mat mat = new Mat(mat2.address());

EDIT : OpenCVFrameConverter now provides an easier and safer way to do this, for example:

OpenCVFrameConverter.ToMat converter1 = new OpenCVFrameConverter.ToMat();
OpenCVFrameConverter.ToOrgOpenCvCoreMat converter2 = new OpenCVFrameConverter.ToOrgOpenCvCoreMat();
Mat mat = ...;
org.opencv.core.Mat cvmat = converter2.convert(converter1.convert(mat));
Mat mat2 = converter2.convert(converter1.convert(cvmat));

You can use java.awt.image.BufferedImage as interface.

Just convert your org.opencv.core.Mat object to java.awt.image.BufferedImage and then take the result object to convert it to org.bytedeco.javacpp.opencv_core.Mat .

Now, these are the functions that you will need:

1) Convert org.opencv.core.Mat to java.awt.image.BufferedImage:

public BufferedImage matToBufferedImage(Mat frame) {       
        int type = 0;
        if (frame.channels() == 1) {
            type = BufferedImage.TYPE_BYTE_GRAY;
        } else if (frame.channels() == 3) {
            type = BufferedImage.TYPE_3BYTE_BGR;
        }
        BufferedImage image = new BufferedImage(frame.width() ,frame.height(), type);
        WritableRaster raster = image.getRaster();
        DataBufferByte dataBuffer = (DataBufferByte) raster.getDataBuffer();
        byte[] data = dataBuffer.getData();
        frame.get(0, 0, data);
        return image;
    }

2) Convert java.awt.image.BufferedImage to org.bytedeco.javacpp.opencv_core.Mat:

public Mat bufferedImageToMat(BufferedImage bi) {
        OpenCVFrameConverter.ToMat cv = new OpenCVFrameConverter.ToMat();
        return cv.convertToMat(new Java2DFrameConverter().convert(bi)); 
    }

Make sure to have all the necessary jars and imports.

You could go deeper into JNI stuff, but for test use cases, this should be enough.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM