我正在做一個專案,我想使用 C OpenCV 處理我的影像。
為簡單起見,我只想轉換Uint8List回來cv::Mat。
按照本教程,我設法制作了一個不會使應用程式崩潰的管道。具體來說:
- 我在 a 中創建了一個函式,該函式
.cpp將指標指向 myUint8List,rawBytes并將其編碼為 a.jpg:
int encodeIm(int h, int w, uchar *rawBytes, uchar **encodedOutput) {
cv::Mat img = cv::Mat(h, w, CV_8UC3, rawBytes); //CV_8UC3
vector<uchar> buf;
cv:imencode(".jpg", img, buf); // save output into buf. Note that Dart Image.memory can process either .png or .jpg, which is why we're doing this encoding
*encodedOutput = (unsigned char *) malloc(buf.size());
for (int i=0; i < buf.size(); i )
(*encodedOutput)[i] = buf[i];
return (int) buf.size();
}
- 然后我在 a 中撰寫了一個
.dart呼叫我的 c 的函式encodeIm(int h, int w, uchar *rawBytes, uchar **encodedOutput):
//allocate memory heap for the image
Pointer<Uint8> imgPtr = malloc.allocate(imgBytes.lengthInBytes);
//allocate just 8 bytes to store a pointer that will be malloced in C that points to our variably sized encoded image
Pointer<Pointer<Uint8>> encodedImgPtr = malloc.allocate(8);
//copy the image data into the memory heap we just allocated
imgPtr.asTypedList(imgBytes.length).setAll(0, imgBytes);
//c image processing
//image in memory heap -> processing... -> processed image in memory heap
int encodedImgLen = _encodeIm(height, width, imgPtr, encodedImgPtr);
//
//retrieve the image data from the memory heap
Pointer<Uint8> cppPointer = encodedImgPtr.elementAt(0).value;
Uint8List encodedImBytes = cppPointer.asTypedList(encodedImgLen);
//myImg = Image.memory(encodedImBytes);
return encodedImBytes;
//free memory heap
//malloc.free(imgPtr);
//malloc.free(cppPointer);
//malloc.free(encodedImgPtr); // always frees 8 bytes
}
- 然后我通過以下方式將 c 與 dart 鏈接起來:
final DynamicLibrary nativeLib = Platform.isAndroid
? DynamicLibrary.open("libnative_opencv.so")
: DynamicLibrary.process();
final int Function(int height, int width, Pointer<Uint8> bytes, Pointer<Pointer<Uint8>> encodedOutput)
_encodeIm = nativeLib
.lookup<NativeFunction<Int32 Function(Int32 height, Int32 width,
Pointer<Uint8> bytes, Pointer<Pointer<Uint8>> encodedOutput)>>('encodeIm').asFunction();
- 最后,我通過以下方式在 Flutter 中顯示結果:
Image.memory(...)
現在,管道沒有崩潰,這意味著我沒有完全搞砸記憶體處理,但它也沒有回傳原始影像,這意味著我確實在某個地方搞砸了。
原圖:

管道輸出:

uj5u.com熱心網友回復:
感謝 Richard Heap 在評論中的指導,我設法通過更改我的矩陣定義來修復管道
cv::Mat img = cv::Mat(h, w, CV_8UC3, rawBytes);
至
vector<uint8_t> buffer(rawBytes, rawBytes inBytesCount);
Mat img = imdecode(buffer, IMREAD_COLOR);
inBytesCount的長度在哪里imgBytes。
如果您覺得這很有用,請對問題和答案都投贊成票,因為我使用業力來支付賞金。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/486905.html
