added OpenCV

This commit is contained in:
AR Fashion
2021-12-05 23:41:02 +08:00
committed by GitHub
parent 80744fe9de
commit fad66a56e0
14 changed files with 9895 additions and 4 deletions

View File

@@ -2,20 +2,29 @@
| 日期   | 内容 |
| -- | -- |
| 2021-12-03 | 新增:微信小程序运行Go语言WebAssembly的示例。也包含网页运行Go语言的示例。 |
| 2021-12-05 | 新增:微信小程序运行OpenCV的示例。也包含网页运行OpenCV的示例。 |
| 2021-12-03 | 新增微信小程序运行Go语言的示例。也包含网页运行Go语言的示例。 |
## 介绍
将Go语言编译为WebAssembly使用微信小程序的WXWebAssembly功能运行WebAssembly。
1、将Go语言编译为WebAssembly使用微信小程序的WXWebAssembly功能运行WebAssembly。
因为Go语言能快速开发WebAssembly所以使用Go语言能为小程序快速开发WebAssembly。
2、在微信小程序中使用WebAssembly版的OpenCV让我们开发图像视觉。
[WXWebAssembly官方文档](https://developers.weixin.qq.com/miniprogram/dev/framework/performance/wasm.html)
## 网页版
在线预览和小程序版使用的是相同的wasm文件。
运行Go
[https://sanyuered.github.io/WeChat-MiniProgram-AR-WASM/go_dev/lesson1.html](https://sanyuered.github.io/WeChat-MiniProgram-AR-WASM/go_dev/lesson1.html)
运行OpenCV
[https://sanyuered.github.io/WeChat-MiniProgram-AR-WASM/go_dev/lesson1.html](https://sanyuered.github.io/WeChat-MiniProgram-AR-WASM/go_dev/lesson1.html)
## 小程序版
@@ -50,6 +59,20 @@ Go运行时会调用小程序的console.log()输出信息。
![avatar](screenshot/3-2.jpg)
## 小程序调用OpenCV的函数。
灰度化
![avatar](screenshot/4-1.jpg)
边缘检测
![avatar](screenshot/4-2.jpg)
特征点检测
![avatar](screenshot/4-3.jpg)
## 目录结构
/:小程序一侧的源代码

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

151
package_lesson2/index.js Normal file
View File

@@ -0,0 +1,151 @@
// 画布
const canvas1 = 'canvas1'
// 示例图片
const sampleImage1 = './assets/sampleImage1.jpg'
// 画布最大宽度
const maxCanvasWidth = 375
// wasm路径
global.wasm_url = '/package_lesson2/assets/opencv3.4.16.wasm.br'
// opencv_exec.js会从global.wasm_url获取wasm路径
let cv = require('./assets/opencv_exec.js');
Page({
// 画布的dom对象
canvasDom: null,
data: {
canvas1Width: 375,
canvas1Height: 150,
// 示例图片
sampleImage1Url: sampleImage1,
},
onReady() {
// 可见的画布
this.initCanvas(canvas1)
},
// 获取画布
initCanvas(canvasId) {
var _that = this;
wx.createSelectorQuery()
.select('#' + canvasId)
.fields({ node: true, size: true })
.exec((res) => {
const canvas2d = res[0].node;
// 设置画布的宽度和高度
canvas2d.width = res[0].width;
canvas2d.height = res[0].height;
_that.canvasDom = canvas2d
});
},
// 获取图像数据和调整图像大小
getImageData(image,offscreenCanvas) {
var _that = this
// const ctx = wx.createCanvasContext(canvasId);
var canvasWidth = image.width;
if (canvasWidth > maxCanvasWidth) {
canvasWidth = maxCanvasWidth;
}
// canvas Height
var canvasHeight = Math.floor(canvasWidth * (image.height / image.width));
// 离屏画布的宽度和高度不能小于图像的
offscreenCanvas.width = canvasWidth;
offscreenCanvas.height = canvasHeight;
// draw image on canvas
var ctx = offscreenCanvas.getContext('2d')
ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);
// get image data from canvas
var imgData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
return imgData
},
// 创建图像对象
async createImageElement(imgUrl) {
var _that = this
// 创建2d类型的离屏画布需要微信基础库2.16.1以上)
var offscreenCanvas = wx.createOffscreenCanvas({type: '2d'});
const image = offscreenCanvas.createImage();
await new Promise(function (resolve, reject) {
image.onload = resolve
image.onerror = reject
image.src = imgUrl
})
const imageData = _that.getImageData(image,offscreenCanvas)
return imageData
},
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()
},
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()
},
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()
},
async btnRun1() {
var _that = this;
// 将图像转换为ImageData
const image1Data = await _that.createImageElement(sampleImage1)
// 设置画布的显示大小
_that.setData({
canvas1Width: image1Data.width,
canvas1Height: image1Data.height,
})
_that.imgProcess1(image1Data, _that.canvasDom)
},
async btnRun2() {
// 同上
var _that = this;
const image1Data = await _that.createImageElement(sampleImage1)
_that.setData({
canvas1Width: image1Data.width,
canvas1Height: image1Data.height,
})
_that.imgProcess2(image1Data, _that.canvasDom)
},
async btnRun3() {
// 同上
var _that = this;
const image1Data = await _that.createImageElement(sampleImage1)
_that.setData({
canvas1Width: image1Data.width,
canvas1Height: image1Data.height,
})
_that.imgProcess3(image1Data, _that.canvasDom)
},
})

View File

@@ -0,0 +1,4 @@
{
"usingComponents": {},
"navigationBarTitleText": "Lesson 2"
}

View File

@@ -0,0 +1,19 @@
<view class="page">
<view class="page__bd">
<view class="weui-panel">
<view class="weui-panel__hd">图像处理</view>
<view class="weui-panel__bd">
<image src="{{sampleImage1Url}}" mode="aspectFit" class="inputImage"></image>
<!-- canvas v2-->
<canvas id="canvas1" type="2d" class="visibleCanvas"
style="width:{{canvas1Width}}px;height:{{canvas1Height}}px;"></canvas>
<view class="weui-media-box">
<button bindtap="btnRun1" class="marginTop10" type="primary">灰度化</button>
<button bindtap="btnRun2" class="marginTop10" type="primary">边缘检测</button>
<button bindtap="btnRun3" class="marginTop10" type="primary">特征点检测</button>
</view>
</view>
</view>
</view>
</view>

View File

@@ -0,0 +1,21 @@
/**index.wxss**/
.button-sp-area{
margin: 0 auto;
padding-top: 15px;
width: 60%;
}
.mini-btn{
margin-right: 5px;
}
.weui-panel__hd{
font-weight:bold;
color:#333;
}
.visibleCanvas{
margin:auto;
}
.inputImage{
width:375px;
}

View File

@@ -1,6 +1,6 @@
<view class="page">
<view class="page__bd">
<!-- Video Mask -->
<view class="weui-panel">
<view class="weui-panel__hd">Go和小程序互操作</view>
<view class="weui-panel__bd">
@@ -16,5 +16,21 @@
</view>
</view>
</view>
<view class="weui-panel">
<view class="weui-panel__hd">小程序使用OpenCV</view>
<view class="weui-panel__bd">
<view class="weui-media-box weui-media-box_text">
<view class="weui-media-box__desc">
使用WXWebAssembly.instantiate初始化OpenCV运行环境。
</view>
<view class="weui-media-box__info">
<navigator url="/package_lesson2/index" class="marginTop10">
<button class="weui-btn" type="primary">Lesson 2</button>
</navigator>
</view>
</view>
</view>
</view>
</view>
</view>

View File

@@ -13,6 +13,10 @@
{
"type": "folder",
"value": "go_dev"
},
{
"type": "folder",
"value": "opencv_dev"
}
]
},
@@ -55,7 +59,7 @@
"useCompilerPlugins": false
},
"compileType": "miniprogram",
"libVersion": "2.15.0",
"libVersion": "2.16.1",
"appid": "wxb4cdacc73d2d71c7",
"projectname": "WeChat-WebAR",
"debugOptions": {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 26 KiB

BIN
screenshot/4-1.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

BIN
screenshot/4-2.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

BIN
screenshot/4-3.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB