我正在嘗試DepthFrame將從 Intel Realsense D455 相機獲得的物件轉換Mat為 Java 中的 OpenCV 物件。我可以使用獲取像素的目標深度,DepthFrame.getDistance(x,y)但我正在嘗試獲取整個矩陣,以便我可以獲取以米為單位的距離值,類似于他們的 Github repo中的示例代碼,該代碼使用 C 。
我可以使用以下函式將從相機流(VideoFrame或彩色DepthFrame)獲得的任何彩色影像轉換為 a,Mat因為它們是每像素 8 位:
public static Mat VideoFrame2Mat(final VideoFrame frame) {
Mat frameMat = new Mat(frame.getHeight(), frame.getWidth(), CV_8UC3);
final int bufferSize = (int)(frameMat.total() * frameMat.elemSize());
byte[] dataBuffer = new byte[bufferSize];
frame.getData(dataBuffer);
ByteBuffer.wrap(dataBuffer).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().get(dataBuffer);
frameMat.put(0,0, dataBuffer);
return frameMat;
}
但是,未著色的DepthFrame值是每像素 16 位,并且上面的代碼在CV_8UC1替換為時會出錯CV_16UC1。出現錯誤是因為在 OpenCV 函式的 Java 包裝器中Mat.put(row, col, data[]),有一個型別檢查只允許Mat處理 8 位:
// javadoc:Mat::put(row,col,data)
public int put(int row, int col, byte[] data) {
int t = type();
if (data == null || data.length % CvType.channels(t) != 0)
throw new UnsupportedOperationException(
"Provided data element number ("
(data == null ? 0 : data.length)
") should be multiple of the Mat channels count ("
CvType.channels(t) ")");
if (CvType.depth(t) == CvType.CV_8U || CvType.depth(t) == CvType.CV_8S) {
return nPutB(nativeObj, row, col, data.length, data);
}
throw new UnsupportedOperationException("Mat data type is not compatible: " t);
}
因此我嘗試使用Mat接受陣列的建構式并撰寫以下方法:
public static Mat DepthFrame2Mat(final DepthFrame frame) {
byte[] dataBuffer = new byte[frame.getDataSize()];
frame.getData(dataBuffer);
ByteBuffer buffer = ByteBuffer.wrap(dataBuffer).order(ByteOrder.LITTLE_ENDIAN).asReadOnlyBuffer().get(dataBuffer);
Log.d(TAG, String.format("DepthFrame2Mat: w: %s h: %s capacity: %s remaining %s framedatasize: %s databufferlen: %s framedepth: %s type: %s " ,
frame.getWidth(), frame.getHeight(), buffer.capacity(), buffer.remaining(), frame.getDataSize(), dataBuffer.length, frame.getBitsPerPixel(), frame.getProfile().getFormat()));
return new Mat(frame.getHeight(), frame.getWidth(), CV_16UC1, buffer);
}
但現在我不斷收到錯誤E/cv::error(): OpenCV(4.5.5) Error: Assertion failed (total() == 0 || data != NULL) in Mat, file /build/master_pack-android/opencv/modules/core/src/matrix.cpp, line 428
使用log函式中看到的命令,我正在檢查是否data為空或null,但不是。此外,DepthFrame位深度和型別似乎也是正確的:
D/CvHelpers: DepthFrame2Mat: w: 640 h: 480 capacity: 614400 remaining 0 framedatasize: 614400 databufferlen: 614400 framedepth: 16 type: Z16
這個錯誤的原因可能是什么?有沒有更好的方法來處理這種轉換?
注意:我已經在網上查看了諸如this和examples之類的SO問題,但是,它們都是用C 撰寫的。我不想僅僅為了創建一個Mat.
uj5u.com熱心網友回復:
即使不是直接的 OpenCV API 解決方案,在 Java 中將位元組陣列轉換為短陣列似乎也可以:
public static Mat DepthFrame2Mat(final DepthFrame frame) {
Mat frameMat = new Mat(frame.getHeight(), frame.getWidth(), CV_16UC1);
final int bufferSize = (int)(frameMat.total() * frameMat.elemSize());
byte[] dataBuffer = new byte[bufferSize];
short[] s = new short[dataBuffer.length / 2];
frame.getData(dataBuffer);
ByteBuffer.wrap(dataBuffer).order(ByteOrder.LITTLE_ENDIAN).asShortBuffer().get(s);
frameMat.put(0,0, s);
return frameMat;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/442195.html
