简体   繁体   English

如何将图像帧相机传递给 wasm (C++) 中的函数?

[英]How to pass image frames camera to a function in wasm (C++)?

I'm trying to build a C++ function and compile it to Wasm using Emscripten.我正在尝试构建一个 C++ 函数并使用 Emscripten 将其编译为 Wasm。
What this function will do is receive an image and do some process on it and return a result.该函数将做的是接收图像并对其进行一些处理并返回结果。
My first POC was successful, the user upload image using file input and I pass the data of the image using FileReader API:我的第一个 POC 成功了,用户使用file输入上传图像,我使用FileReader API 传递图像数据:

const fileReader = new FileReader();
fileReader.onload = (event) => {
   const uint8Arr = new Uint8Array(event.target.result);
   passToWasm(event.target.result);
};

fileReader.readAsArrayBuffer(file); // I got this `file` from `change` event of the file input.

But when I implemented the camera feed and started to get frames to pass it to Wasm, I started to get exceptions in C++ side, and here's the JS implementation:但是当我实现相机提要并开始获取帧以将其传递给 Wasm 时,我开始在 C++ 端遇到异常,这是 JS 实现:

let imageData = canvasCtx.getImageData(0, 0, videoWidth, videoHeight);
var data=imageData.data.buffer;
var uint8Arr = new Uint8Array(data);
passToWasm(uint8Arr);

This one throws an exception in C++ side.这个在 C++ 端抛出异常。

Now passToWasm implementation is:现在passToWasm实现是:

function passToWasm(uint8ArrData) {
   // copying the uint8ArrData to the heap
   const numBytes = uint8ArrData.length * uint8ArrData.BYTES_PER_ELEMENT;
   const dataPtr = Module._malloc(numBytes);
   const dataOnHeap = new Uint8Array(Module.HEAPU8.buffer, dataPtr, numBytes);
   dataOnHeap.set(uint8ArrData);

   // calling the Wasm function
   const res = Module._myWasmFunc(dataOnHeap.byteOffset, uint8ArrData.length);
}

While the C++ implementation will be something like this:虽然 C++ 实现将是这样的:

void EMSCRIPTEN_KEEPALIVE checkImageQuality(uint8_t* buffer, size_t size) {
   // I'm using OpenCV in C++ to process the image data
   // So I read the data of the image
   cv::Mat raw_data = cv::Mat(1, size, CV_8UC1, buffer);

   // Then I convert it
   cv::Mat img_data = cv::imdecode(raw_data, cv::IMREAD_COLOR | cv::IMREAD_IGNORE_ORIENTATION);

   // in one of the following steps I'm using cvtColor function which causes the issue for some reason
}

The exception I'm getting because of the camera implementation says:由于相机实现,我得到的异常说:

OpenCV(4.1.0-dev) ../modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor' OpenCV(4.1.0-dev) ../modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

What is the difference between using file input and getting the data to pass it, and getting the data from a canvas as long as both of them are convert it to Uint8Array使用file输入和获取数据来传递它和从canvas获取数据之间有什么区别,只要它们都将其转换为Uint8Array

I found a solution for this (maybe suits my case only).我找到了一个解决方案(也许只适合我的情况)。
When you're trying to get an image data from canvas you get it as 4 channels (RGBA like in PNG), and depending on your image processing code you need to deal with it.当您尝试从canvas获取图像数据时,您将获得 4 个通道(如 PNG 中的 RGBA),并且根据您需要处理的图像处理代码。
My code was considering that the image should be 3 channels (RGB like in jpeg) so I had to convert it using this code:我的代码考虑到图像应该是 3 个通道(像 jpeg 中的 RGB)所以我不得不使用以下代码转换它:

canvasBuffer.toBlob(function (blob) {
  passToWASM(blob);
},'image/jpeg');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM