加载中...

微信小程序运行WebAssembly版OpenCV

微信小程序运行WebAssembly版OpenCV
目录
收起
介绍
网页版
小程序版
灰度化
边缘检测
特征点检测
技术难点
常见问题

介绍

相比使用JavaScript版本的OpenCV,微信小程序使用WebAssembly版本的OpenCV,体积较小,运行速度较快。

网页版

在线预览,和小程序版使用的是相同的wasm文件。

https://sanyuered.github.io/WeChat-MiniProgram-AR-WASM/opencv_dev/lesson2.html

小程序版

https://github.com/sanyuered/WeChat-MiniProgram-AR-WASM

首页

New Image

灰度化

imgProcess1(imageData, canvasDom) {
		// 读取图像
		let src = cv.imread(imageData);
		let dst = new cv.Mat();
		// 灰度化
		cv.cvtColor(src, dst, cv.COLOR_RGBA2GRAY, 0);
		// 显示图像
		cv.imshow(canvasDom, dst);
		// 回收对象
		src.delete();
		dst.delete()
	}
New Image

边缘检测

imgProcess2(imageData, canvasDom) {
		let src = cv.imread(imageData);
		let dst = new cv.Mat();

		// 灰度化
		cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);
		// 边缘检测
		cv.Canny(src, dst, 50, 100, 3, false);

		cv.imshow(canvasDom, dst);
		src.delete();
		dst.delete()
	}
New Image

特征点检测

	imgProcess3(imageData, canvasDom) {
		let src = cv.imread(imageData);
		let dst = new cv.Mat();

		// 灰度化
		cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);

		var orb = new cv.ORB();
		var keypoints = new cv.KeyPointVector();
		var descriptors = new cv.Mat();
		// 特征点
		orb.detect(src, keypoints)
		// 特征点的描述因子
		orb.compute(src, keypoints, descriptors)
		// 绘制特征点
		cv.drawKeypoints(src, keypoints, dst)

		cv.imshow(canvasDom, dst);
		src.delete();
		dst.delete()
	}
New Image

技术难点

1、如何获取OpenCV的wasm文件?

从OpenCV官方网站下载opencv.js,该js中包含了Base64编码的wasm文件。从opencv.js文件中的变量wasmBinaryFile提取Base64编码,将Base64编码转换为二进制文件。下方地址中的3.4.16表示OpenCV版本号,可以更改为其它版本号。

下载地址:https://docs.opencv.org/3.4.16/opencv.js

2、OpenCV 3的wasm文件有5MB大小,怎样部署到小程序2MB的分包里?

将.wasm压缩为.wasm.br,文件大小变为1.14MB。符合了小程序的分包大小限制。

3、小程序如何运行OpenCV的wasm?

错误示例:

WXWebAssembly.instantiate(wasmBinaryFile, {})

正确示例:

WXWebAssembly.instantiate(wasmBinaryFile, info)

对象info来自opencv.js文件。

4、小程序不支持new Function()和Function.Apply(),无法编译和运行opencv.js。

将opencv.js的new Function()和Function.Apply()的代码改写。

文件修改的位置使用了IsWechat变量标识。具体修改请见源代码。

const IsWechat = true;

5、opencv.js有3个地方使用了new Function(),2个修改简单,1个修改复杂。

修改前:

 return new Function("body", "return function " + name + "() {\n" + 
''    "use strict";'' + 
"    return body.apply(this, arguments);\n" + "};\n")(body)

修改后:

var f1 = function (body) {
        return function () {
            "use strict";
            return body.apply(this, arguments);
        }
 }
 return f1(body)

6、opencv如何在小程序里读取和显示图像?

使用ImageData读取图像,使用Canvas显示图像。

常见问题

1、调用了其它OpenCV函数,发生错误?

js调用OpenCV函数的变量数量、变量类型、变量位置等要和调用OpenCV的C++写法一样。不能和Python写法一样。

2、这个支持OpenCV的全部API吗?

支持OpenCV 3.4.16版本(目前OpenCV 3的最新版本)的API。因为OpenCV 4体积比OpenCV 3大,所以没有考虑把OpenCV 4放进小程序。项目包含的opencv3.4.16.wasm文件是OpenCV官方编译的。

3、这个需要的小程序基础库的最低版本是多少?

WXWebAssembly依赖的基础库

全局访问 :基础库 v2.13.0

允许传入brotli压缩的.wasm文件:基础库 v2.14.0

在 Worker 内使用 :基础库 v2.15.0

在小程序插件使用 :基础库 v2.18.1

wx.createOffscreenCanvas()依赖的基础库

全局访问和小程序插件:基础库2.16.1

4、使用方法cv.imread(图片,0)将彩色图片转换为灰色图片,不起作用。

WebAssembly版本的OpenCV和C++版本的OpenCV有些差异,方法cv.imread()只接受一个输入参数。

使用cv.cvtColor(图片)方法代替cv.imread(图片,0)。

let src = cv.imread(imageData);
let dst = new cv.Mat();
// 灰度化
cv.cvtColor(src, src, cv.COLOR_RGBA2GRAY, 0);

5、小程序使用OpenCV能做什么?

图像处理、运动估计、人脸识别、目标识别、图像分割、运动跟踪、增强现实等。