gpt4 book ai didi

javascript - cv::imcode将图像从JS解码到C++(opencv,emscripten)

转载 作者:行者123 更新时间:2023-12-02 16:33:58 24 4
gpt4 key购买 nike

我正在尝试做的是:

  • 用户在html中加载图像
  • opencv用C++接收该图像并对其做一些工作。

  • 我所做的与此处描述的大致相同:

    https://answers.opencv.org/question/222994/how-to-pass-image-data-from-javascript-to-opencv-c-webassembly/

    这是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);


    您必须使函数 passToWasm适应其他两个参数(宽度和高度),并将它们传递给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已准备好进行操作。

    关于javascript - cv::imcode将图像从JS解码到C++(opencv,emscripten),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61477860/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com