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

156 lines
7.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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画布