Reputation: 431
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.
Upvotes: 5
Views: 7232
Reputation: 4994
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));
Upvotes: 4
Reputation: 71
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.
Upvotes: 1