使用 opencv 实现 WebAR 的可能性
# 前言
现在各种增强现实游戏层出不穷,各种 MR 设备也在持续更新,可以看出将来增强现实领域有很大的发展潜力…
# 效果图(半半成品)
本来是打算做一个 AR 示例的,不过时间不够了,最近状态也不好,就稍微讲下怎么用 opencv 实现 WebAR 的方向吧
# AR 怎么实现的?
AR,即为增强现实,既然我们要增强现实,那么就要识别并定位现实中的物体,获得相机的坐标,才能准确的展示虚拟画面
那么,计算机是怎么确定两张图片中对应的关系?其实就是通过特征检测,如果匹配成功,则会返回关键点数据
大家看完可以自行查看代码,这里基本不做代码上的讲解
1. 将输入图片转为灰度图
为什么要转为灰度图,当然是为了降维,减少计算量
2. 检查关键点
特征检测有很多种算法,这里我们使用的是 AKAZE
参考链接
3. 匹配关键点
这里使用的是 knnMatch(暴力匹配)
现在我们拿到了关键点的数据,该怎么用呢?其实下一步就是通过关键点估计单应性,什么是单应性呢?有什么用?
4. 查找单应性
在 opencv 中我们是使用 findHomography
# 单应性变换有什么用?
- 估计相机姿势以增强现实
- 透视去除/校正
- 图片拼接
知道了它有什么用?那么想必会更加更多大家对它的兴趣
简单的说,单应性矩阵是一个 3x3 的矩阵(投影变换),可以从一个平面上的点转换到另一个平面上
如果我们这一步返回的单应性是无效的,那么就说明两张图像没有匹配成功
参考链接:
使用代码解析单应性: https://docs.opencv.org/4.x/d9/dab/tutorial_homography.html#pose_ar
仿射和投影变换:https://www.graphicsmill.com/docs/gm5/Transformations.htm
5. 估计相机姿态
这一步需要提前进行相机校准,什么是相机校准?让我们看看下面的图片
相机是存在边缘被拉伸(畸变)的情况的,相机校准就是确定相机畸变系数,以及相机矩阵(包含了像素值,相机焦距),下面是校准后的图像
获得了相机矩阵后,我们就可以通过 solvePnP
参考链接
完整的 C++ 代码示例(Chapter3):https://github.com/MasteringOpenCV/code.git
内参和投影矩阵:http://www.info.hiroshima-cu.ac.jp/~miyazaki/knowledge/teche0092.html
# 扩展
1. 计算和匹配关键点是非常昂贵的操作,怎么优化?
答案是使用跟踪算法,我们不必每一次需要去检测关键点,这里推荐稀疏光流
1.1 光流算法是什么?
1.2 光流有什么好处?
就算目标移出摄像机外,我们任然可以继续跟踪
参考链接
2. 怎么提高精度
使用手机的陀螺仪,加速度器来实现
参考链接
3. 如何在现阶段使用 WebAR 系统?
当前 cocos 的 AR 正在开发中,但是我们还有第三方选择
easyar(国内):https://www.easyar.cn/price.html
8thwall(国外):https://www.8thwall.com/
blippar(国外):https://www.blippar.com/
# 怎么使用 opencv 开发 Web 程序
- 使用 C++ 在 Visual Studio 上面进行调试,再通过 linux 系统进行发布 wasm 版本
- 直接使用 opencv.js 版本
建议各位不要在 opencv.js 身上浪费时间,因为这货 没有文档,接口不完全一致,属性缺失
# 1. 怎么在 windows 上编译 opencv?
# 1.1 使用 docker 安装 opencv 的镜像(依赖 WSL 功能,win10 及以上)
# 1.2 创建一个容器
docker run --name 容器名 -p 80:80 -t -d 镜像名
共享文件夹
- D:/test:宿主机目录
- /usr/databases:容器机目录
# 1.3 启动容器后参照下面链接尝试编译一个示例项目
https://github.com/EdwardLu2018/wasm-ar
# 代码
文章代码:https://github.com/1226085293/mk_ar_demo
opencv 官方 C++ 示例:https://github.com/MasteringOpenCV/code.git
注意,除了只实现简单的功能外,尽量都不要使用 opencv.js,大坑