![](/img/trans.png)
[英]Compiling C++ OpenCV code to Javascript with Emscripten
[英]cv::imdecode an image from JS to C++ (opencv, emscripten)
我正在尝试做的事情:
我所做的与此处描述的或多或少相同:
这是 javascript 部分(来自给定链接的逐字记录):
var openFile = function (e) {
const fileReader = new FileReader();
fileReader.onload = (event) => {
const uint8Arr = new Uint8Array(event.target.result);
passToWasm(uint8Arr);
};
fileReader.readAsArrayBuffer(e.target.files[0]);
};
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
console.log(dataOnHeap.byteOffset);
const res = Module._image_input(dataOnHeap.byteOffset, uint8ArrData.length);
Module._free(dataPtr);
}
这是 C++ 部分(几乎是逐字记录):
int image_input(int offset, size_t size) //query image input
{
uint8_t* pos;
pos = reinterpret_castw<uint8_t*>(offset);
cv::Mat raw_data = cv::Mat(1, size, CV_8UC1, pos);
cout << raw_data << endl;
img_object = cv::imdecode(raw_data, cv::IMREAD_GRAYSCALE);
cout << img_object << endl;
}
当我使用一些 jpg 图像进行测试时,C++ 部分上的raw_data
和 JS 部分上的uint8ArrData
包含相同的信息:这是 15253 个数字的列表,例如
[255, 216, 255, 224, ..., 184, 227, 255, 217]
现在,线
img_object = cv::imdecode(raw_data, cv::IMREAD_GRAYSCALE);
返回一个空矩阵[]
。
我做错了什么? 我是否必须在 JS 端进行一些预处理?
如提供的链接中所述,解决方案是使用 canvas 并将像素列表(以 4x480x640 数字为例)发送到 C++。
在 JS 方面你有
function sendCanvas(canvas, baseImage) {
const context = canvas.getContext('2d');
context.drawImage(baseImage, 0, 0, baseImage.width, baseImage.height);
const { width } = canvas;
const { height } = canvas;
const imgData = context.getImageData(0, 0, canvas.width, canvas.height);
const uint8ArrData = new Uint8Array(imgData.data);
// pass the width and height too !!
passToWasm(uint8ArrData, width, height);
}
const baseImage = new Image();
baseImage.src = 'test.jpg';
baseImage.onload = () => sendCanvas(canvas, baseImage);
您必须调整 function passToWasm
以再获取两个 arguments(宽度和高度)并将它们传递给 C++ 调用。
然后在 C++ 端,使用以下信息直接将图像创建为cv::Mat
:
void image_input(int offset, size_t size, int width, int height) {
// People in the doc do not need this cast trick. Why ???
uint8_t *pos;
pos = reinterpret_cast<uint8_t *>(offset);
auto cv_image = cv::Mat(width, height, CV_8UC4, pos);
}
矩阵cv_image
已准备好进行操作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.