Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenCV Mat到JavaCV Mat的转换_Java_Android_Opencv_Javacv - Fatal编程技术网

OpenCV Mat到JavaCV Mat的转换

OpenCV Mat到JavaCV Mat的转换,java,android,opencv,javacv,Java,Android,Opencv,Javacv,我正在编写一个Android应用程序,它使用JavaCV进行面部识别。我遇到了一个小问题,我需要从org.opencv.core.Mat转换成onCameraFrame(CvCameraViewFrame inputFrame)函数返回到org.bytedeco.javacpp.opencv_core.Mat所需的org.bytedeco.javacpp.opencv\u contrib.FaceRecognizer函数 我发现了类似的问题,但都没有找到有效的解决方案。您可以使用java.awt

我正在编写一个Android应用程序,它使用JavaCV进行面部识别。我遇到了一个小问题,我需要从
org.opencv.core.Mat
转换成
onCameraFrame(CvCameraViewFrame inputFrame)
函数返回到
org.bytedeco.javacpp.opencv_core.Mat
所需的
org.bytedeco.javacpp.opencv\u contrib.FaceRecognizer
函数


我发现了类似的问题,但都没有找到有效的解决方案。

您可以使用java.awt.image.buffereImage作为接口

只需将您的org.opencv.core.Mat对象转换为java.awt.image.BufferedImage,然后将结果对象转换为org.bytedeco.javacpp.opencv\u core.Mat

现在,您将需要以下功能:

1) 将org.opencv.core.Mat转换为java.awt.image.buffereImage:

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) 将java.awt.image.buffereImage转换为org.bytedeco.javacpp.opencv_core.Mat:

public Mat bufferedImageToMat(BufferedImage bi) {
        OpenCVFrameConverter.ToMat cv = new OpenCVFrameConverter.ToMat();
        return cv.convertToMat(new Java2DFrameConverter().convert(bi)); 
    }
确保有所有必要的罐子和进口品


您可以更深入地了解JNI内容,但对于测试用例来说,这就足够了。

有一种更简单、更有效的方法,简而言之:

到JavaCPP/JavaCV:

Mat mat2 = new Mat((Pointer)null) { { address = mat.getNativeObjAddr(); } };
要获取OpenCV的官方Java API,请执行以下操作:

Mat mat = new Mat(mat2.address());
编辑:现在提供了一种更简单、更安全的方法,例如:

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));

是的,悲哀的主题2 java独立opencv包装器,两者基本上不兼容。一定有办法。我正在编写一个使用JavaCV的Android应用程序:我强烈建议您在新代码中使用官方的opencvjavaapi。但是如果您真的必须这样做,您可能需要编写一些本机代码来进行转换,并通过JNI调用它,除非有某种方法可以将OpenCV的
Mat.dataAddr()
的长结果诱使到bytdeco指针中,以便将其传递给bytedeco Mat构造函数!!在
javacv
@user924Yes中,有一个,它被称为“索引器”:这个工作的util更新库到javacpp预设:ffmpeg 4.1-1.4.4是“OpenCVFrameConverter.ToOrgOpenCvCoreMat”,没有找到它,表示符号无法解析。它仍然在那里,没有任何更改: