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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With