首页 > 解决方案 > 从 cv::normalize 接收错误“表达式的类型为 v128 但预期为 i32”

问题描述

我正在尝试使用 opencv 运行快速 wasm 程序。我遇到了性能问题,所以合乎逻辑的步骤是包含 SIMD。但是我收到了几个错误,但我不知道如何处理它:

wasm streaming compile failed: CompileError: wasm validation error: at offset 132077: type mismatch: expression has type v128 but expected i32 active_contour.js:1:18033
falling back to ArrayBuffer instantiation active_contour.js:1:18079
failed to asynchronously prepare wasm: CompileError: wasm validation error: at offset 132077: type mismatch: expression has type v128 but expected i32 active_contour.js:1:17587
CompileError: wasm validation error: at offset 132077: type mismatch: expression has type v128 but expected i32 active_contour.js:1:15820
CompileError: wasm validation error: at offset 132077: type mismatch: expression has type v128 but expected i32 active_contour.js:1:15830
Uncaught (in promise) RuntimeError: abort(CompileError: wasm validation error: at offset 132077: type mismatch: expression has type v128 but expected i32).

我正在尝试运行程序:

使用生成 make 文件

emcmake cmake -DOpenCV_DIR=/home/user/tools/opencv/build_js_simd/ ..
make

其中build_js_simd是使用构建 opencv 目录

emcmake python ./opencv/platforms/js/build_js.py build_js_simd --build_wasm --simd.

最后我使用python -m SimpleHTTPServer来运行index.html

我有以下代码,在cv::normalize行之前一切正常,上面似乎出现了错误。

#include <iostream>
#include <opencv2/opencv.hpp>
#include <emscripten/bind.h>
#include <vector>
#include <wasm_simd128.h>


std::vector<int> active_contour(const int &in_addr1,  const size_t width1, const size_t height1, const int &in_addr2,  const size_t width2, const size_t height2){
    

    uint8_t *in_data1 = reinterpret_cast<uint8_t *>(in_addr1);
    uint8_t *in_data2 = reinterpret_cast<uint8_t *>(in_addr2);

    cv::Mat input(height1, width1, CV_8UC4, in_data1);
    cv::Mat initLS(height2, width2, CV_8UC4, in_data2);

    cv::cvtColor(input, input, cv::COLOR_RGBA2GRAY);
    cv::cvtColor(initLS, initLS, cv::COLOR_RGBA2GRAY);

    cv::Mat resNorm;
    cv::normalize(input, resNorm, 0, 255, cv::NORM_MINMAX, CV_8UC3); 
   int numRows = resNorm.rows;
   int numCols = resNorm.cols;



        //Source: https://stackoverflow.com/questions/26681713/convert-mat-to-array-vector-in-opencv
    
    std::vector<int> array;
    if (resNorm.isContinuous()) {
        array.assign(resNorm.datastart, resNorm.dataend); // <- has problems for sub-matrix like mat = big_mat.row(i)
        array.assign(resNorm.data, resNorm.data + resNorm.total()*resNorm.channels());
        } 
    else {
        for (int i = 0; i < resNorm.rows; ++i) {
            array.insert(array.end(), resNorm.ptr<uchar>(i), resNorm.ptr<uchar>(i)+resNorm.cols*resNorm.channels());
        }
    }
    array.push_back(numCols);
    array.push_back(numRows);
    return array;
    
}

EMSCRIPTEN_BINDINGS(active_contour_module){
    //emscripten::class_<cv::Mat>("Mat");
    emscripten::register_vector<int>("array");
    emscripten::function("active_contour", &active_contour, emscripten::allow_raw_pointers());
}

接下来我使用以下CMakeLists.txt

cmake_minimum_required(VERSION 3.19)
project(active_contour)
find_package(OpenCV 4.1 REQUIRED)
set(CMAKE_BUILD_TYPE RELEASE)
add_executable  (${PROJECT_NAME} main.cpp)
target_compile_options(${PROJECT_NAME} PUBLIC 
                        -O3
                        -msimd128
                         )
target_link_options(${PROJECT_NAME} PUBLIC 
                        --bind 
                        -sALLOW_MEMORY_GROWTH=1 
#                        -sINLINING_LIMIT=1
#                        -sFILESYSTEM=0
#                        -sMAXIMUM_MEMORY=4GB
#                        -sASSERTIONS=1
#                        -sDISABLE_EXCEPTION_CATCHING=2
#                        -sSAFE_HEAP=1
#                        -sSTACK_OVERFLOW_CHECK=2
#                        -sDEMANGLE_SUPPORT=1
                        )
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})

有人知道如何处理吗?

标签: javascriptc++opencvwebassemblyemscripten

解决方案


推荐阅读