In OpenCV, the fastest way to work with a Mat is to first copy it to an array of the appropriate primitive type, something like this:
byte[][] array = new byte[rows][cols];
for (int i = 0; i < rows; i++) {
mat.get(i, 0, array[i]);
}
However, this doesn't work in OpenCV4Android with unsigned Mat types (e.g. 8U), since Java lacks unsigned types. I could just copy to an array of the next larger primitive type (here, a short) while adding 256 to every element:
byte[] buf = new byte[cols];
short[][] array = new short[rows][cols];
for (int i = 0; i < rows; i++) {
mat.get(i, 0, buf);
for (int j = 0; j < cols; j++) {
array[i][j] = (short) (buf[i]+256);
}
}
Is there a faster way?
It's actually possible to convert the Mat to signed byte before extracting it:
mat.convertTo(mat, CvType.CV_8S);
While indeed Java doesn't support unsigned primitive types, this would make a difference only if you do actual arithmetics with the values. 8 bits are 8 bits, signed or unsigned. If you need to calculate something with the values, yes - you should use a larger type (in fact double of the original) to avoid overflows (signed byte -127:128, unsgined: 0:255) and you should do some conversion to get rid of the "sign part" ( in case of byte & 0xFF). Edit: This is a general answer, I haven't used OpenCV4Android. While in specific cases it might make sense to work with unsigned types for memory consumption reasons, my guess is that a library will actually output the values you need in the correct form for the platform?
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