156 lines
7.0 KiB
Markdown
156 lines
7.0 KiB
Markdown
|
||
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画布
|
||
|