简体   繁体   English

OpenCV Mat 到 JavaCV Mat 的转换

[英]OpenCV Mat to JavaCV Mat conversion

I am in the process of writing an Android application that uses JavaCV for some facial recognition.我正在编写一个使用 JavaCV 进行面部识别的 Android 应用程序。 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.我遇到了一个小问题,我需要从onCameraFrame(CvCameraViewFrame inputFrame)函数返回到org.bytedeco.javacpp.opencv_core.Matorg.opencv.core.Mat转换为org.bytedeco.javacpp.opencv_contrib.FaceRecognizer需要。

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:https://github.com/bytedeco/javacpp/issues/38#issuecomment-140728812中记录了一种更简单、更有效的方法,简而言之:

To JavaCPP/JavaCV:到 JavaCPP/JavaCV:

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

To official Java API of OpenCV: OpenCV的官方Java API:

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

EDIT : OpenCVFrameConverter now provides an easier and safer way to do this, for example:编辑OpenCVFrameConverter现在提供了一种更简单、更安全的方法来执行此操作,例如:

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.您可以使用 java.awt.image.BufferedImage 作为接口。

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 .只需将您的org.opencv.core.Mat对象转换为java.awt.image.BufferedImage ,然后将结果对象转换为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: 1) 将 org.opencv.core.Mat 转换为 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: 2) 将 java.awt.image.BufferedImage 转换为 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.您可以更深入地研究 JNI 的内容,但对于测试用例,这应该足够了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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