Files
Obsidian/编译opencv_version.wasm及opencv_version.js.md
2026-07-21 14:53:24 +08:00

7.0 KiB
Raw Permalink Blame History

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 命令:

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分量是0180,而不是0360)
  4. 后续 会调用 http接口将数据递交到后台服务器(目前不实现)
  5. 成功识别的图片,需要在尿检试纸的每个检测块的中心点,围绕中心点画一个半径为5像素的圆
  6. 微信摄像头的接口读取图片的图片(包括上面这一步,画的圆圈,如果成功失败图片的话),需要渲染到微信小程序canvas画布