sudo apt update && sudo apt install git cmake python3 build-essential git clone https://github.com/emscripten-core/emsdk.git cd emsdk ./emsdk install latest ./emsdk activate latest source ./emsdk_env.sh # 每次进终端要执行,或写到 ~/.bashrc emcc -v # 验证:能看到版本号就成功 # 拉 OpenCV 源码 git clone --depth 1 --branch 4.10.0 https://github.com/opencv/opencv.git cd opencv mkdir build_wasm && cd build_wasm --- 编译成功 ✅ **错误原因分析:** 你遇到的是两个问题: 1. **ittnotify 编译失败**(40% 处首次报错)— `__TBB_machine_fetchadd4` 未声明。这是 Intel ITT 性能分析库,在 WebAssembly 下无效。已在 cmake 配置中添加 `-DWITH_ITT=OFF` 禁用。 2. **opencv_core SIMD128 编译失败** — `intrin_wasm.hpp` 使用了 `wasm_v128_load`、`wasm_v128_store` 等 SIMD128 内联函数,但编译器默认未启用 `simd128` target feature。添加了 `-DCMAKE_CXX_FLAGS="-msimd128" -DCMAKE_C_FLAGS="-msimd128"` 解决。 **完整可用 cmake 命令:** ```bash cd /home/ubuntu/opencv/build_wasm source /home/ubuntu/emsdk/emsdk_env.sh emcmake cmake \ -DCMAKE_BUILD_TYPE=MinSizeRel \ -DBUILD_LIST=core,imgproc,imgcodecs \ -DWITH_WEBASSEMBLY=ON \ -DWITH_DNN=OFF \ -DWITH_CONTRIB=OFF \ -DWITH_PHOTO=OFF \ -DWITH_VIDEO=OFF \ -DWITH_ITT=OFF \ -DCMAKE_CXX_FLAGS="-msimd128" \ -DCMAKE_C_FLAGS="-msimd128" \ .. emmake make -j$(nproc) ``` **编译产物:** - `lib/libopencv_core.so` — core 模块(230K) - `lib/libopencv_imgproc.so` — 图像处理模块 - `lib/libopencv_imgcodecs.so` — 图像编解码模块 - `bin/opencv_version.wasm` + `opencv_version.js` — 测试可执行文件 如果你需要最终的 `.wasm` 单文件用于浏览器,还需后续用 `emcc` 链接生成,需要我继续帮你做吗? 最终结果在目录下: /home/ubuntu/opencv/build_wasm 你在/home/ubuntu/nanocode/web-opencv目录下,创建web项目,测试opencv_version.wasm` + `opencv_version.js 这两个版本的opencv功能。 先实现最简单的功能,测试opencv这两个库的可用性: 实现一个web页面,允许上传一个图片,然后调用opencv的函数,进行自动白平衡处理。 界面上, 顶部可以切换opencv_version.wasm` + `opencv_version.js 这两种版本; 顶部有一个点击上传图片的按钮,及一个图像变换的按钮; 页面上半部分是展示原图; 页面下半部分是展示处理后的图片; 你可以将/home/ubuntu/opencv/build_wasm编译好的opencv_version.wasm` + `opencv_version.js 两个文件,引入到/home/ubuntu/nanocode/web-opencv项目下。 以上需求是否可行!? --- 这个需求可行,但需要对你的理解做一点澄清: **opencv_version.wasm + opencv_version.js** — 这两个文件是**同一个可执行程序**的两部分(二进制 + 胶水代码),它只是一个打印 OpenCV 版本号的 CLI 程序,不是 OpenCV 函数库本身,不能做图像处理。 你的 OpenCV 库实际编译成了三个 `.so` 文件(core、imgproc、imgcodecs),它们是 Emscripten 动态库格式。 我会这样实现: 1. **Tab 1 — opencv_version 测试**:部署 `.so` + `.wasm` + `.js`,在浏览器中加载运行并显示版本号,验证编译产物可用 2. **Tab 2 — 自动白平衡**:用原生 JS 实现 Gray World 白平衡算法(等同于 OpenCV 的经典算法),无需额外库 --- opencv.wasm 只是纯底层二进制模块,没有和浏览器、JS 的交互能力,无法直接调用。opencv.js 是胶水代码,负责加载、初始化 wasm,并把 C++ 接口封装成 JS 可调用的方法。常规部署将两个文件放在同一目录,引入 opencv.js 就会自动加载对应的 opencv.wasm。 那么,.so文件也会用到吗?web页面能加载so文件? 好问题。让我把架构讲清楚: **`.so` 文件是怎么回事?** 你编译时用了 `-DBUILD_SHARED_LIBS=ON`,所以 OpenCV 的动态库被编译成了 **Emscripten 格式的 SIDE_MODULE**(不是原生 Linux .so)。这些文件内部格式是 **WASM**,只不过后缀叫 `.so`。 在浏览器里,Emscripten 的 Dynamic Linker 确实可以加载它们——流程是: 1. `opencv_version.js` 先加载 `opencv_version.wasm` 2. WASM 的 `neededDynlibs` 元数据会列出依赖的 `.so` 文件 3. Emscripten 内部通过 `locateFile()` 依次发起 HTTP 请求获取并实例化它们 所以**浏览器是能加载这些 `.so` 文件的**(它们本质是 WASM 侧模块)。 **但这不是标准做法。** 标准 OpenCV.js 是用静态链接把所有东西打进一个 `.wasm`,调用端只需 `opencv.js` + `opencv.wasm` 两个文件,没有多余的 `.so`。动态链接方案: - 多了 3 个额外 HTTP 请求 - MIME 类型配置麻烦 - 版本号文件名需要 `locateFile` 特殊处理 **所以正确做法是直接用 `build_js.py` 构建 OpenCV.js。** --- **实现一个微信小程序,用于干化学尿检试纸的识别** 前提:阅读paper-recognizer.js 和 REAME.md # 用户需求和技术要求 ## 使用微信小程序的原生语法,而不是VUE之类; ## 重用paper-recognizer.js 文件代码,如果该文件代码有问题,可以修复 ## 第一步只需要能够从微信摄像头的接口读取图片,并分析尿检试纸的HSV和LAB数据 ## 后续 会调用 http接口将数据递交到后台服务器(目前不实现) ## 成功识别的图片,需要在尿检试纸的每个检测块的中心点,围绕中心点画一个半径为5像素的圆 ## 微信摄像头的接口读取图片的图片(包括上面这一步,画的圆圈,如果成功失败图片的话),需要渲染到微信小程序canvas画布 以上,需求是一个基本需求,你看看有没有问题。有的话,告诉我问我 --- # 这个项目内容说明: 1、 核心文件 opencv_version.wasm,opencv_version.js 是通过opencv源码编译出的OpenCV wasm库 2、cpp子目录是原来的HarmonyOS业务代码 3、miniapp 和 miniappB是纯JS实现的类似HarmonyOS业务逻辑 4、miniappA应该是wasm方式实现的类似HarmonyOS业务逻辑 **我的以上结论是否准确?** --- # 我的新需求: **实现一个微信小程序,用于干化学尿检试纸的识别** **新写的微信小程序代码,放在miniappA目录** 1. 使用微信小程序的原生语法,而不是VUE之类; 2. 重用 miniappA/web目录下paper_recognizer.js paper_recognizer.wasm这两个文件(如果这两个文件有问题,请重写编译和修改),如果该文件代码有问题,可以修复 3. 第一步只需要能够从微信摄像头的接口读取图片,并分析尿检试纸的HSV和LAB数据(HSV ,LAB使用opencv 方式的表示方法,如H分量是0~180,而不是0~360) 4. 后续 会调用 http接口将数据递交到后台服务器(目前不实现) 5. 成功识别的图片,需要在尿检试纸的每个检测块的中心点,围绕中心点画一个半径为5像素的圆 6. 微信摄像头的接口读取图片的图片(包括上面这一步,画的圆圈,如果成功失败图片的话),需要渲染到微信小程序canvas画布