7.0 KiB
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
编译成功 ✅
错误原因分析:
你遇到的是两个问题:
-
ittnotify 编译失败(40% 处首次报错)—
__TBB_machine_fetchadd4未声明。这是 Intel ITT 性能分析库,在 WebAssembly 下无效。已在 cmake 配置中添加-DWITH_ITT=OFF禁用。 -
opencv_core SIMD128 编译失败 —
intrin_wasm.hpp使用了wasm_v128_load、wasm_v128_store等 SIMD128 内联函数,但编译器默认未启用simd128target 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 动态库格式。
我会这样实现:
- Tab 1 — opencv_version 测试:部署
.so+.wasm+.js,在浏览器中加载运行并显示版本号,验证编译产物可用 - 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 确实可以加载它们——流程是:
opencv_version.js先加载opencv_version.wasm- WASM 的
neededDynlibs元数据会列出依赖的.so文件 - 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目录
- 使用微信小程序的原生语法,而不是VUE之类;
- 重用 miniappA/web目录下paper_recognizer.js paper_recognizer.wasm这两个文件(如果这两个文件有问题,请重写编译和修改),如果该文件代码有问题,可以修复
- 第一步只需要能够从微信摄像头的接口读取图片,并分析尿检试纸的HSV和LAB数据(HSV ,LAB使用opencv 方式的表示方法,如H分量是0
180,而不是0360) - 后续 会调用 http接口将数据递交到后台服务器(目前不实现)
- 成功识别的图片,需要在尿检试纸的每个检测块的中心点,围绕中心点画一个半径为5像素的圆
- 微信摄像头的接口读取图片的图片(包括上面这一步,画的圆圈,如果成功失败图片的话),需要渲染到微信小程序canvas画布