【WebAR】微信小程序3D、小程序AR、小程序AI等开源项目2021年3月份更新
前言
2019年7月,微信小程序宣布支持AR,笔者陆续地开发了AR、AI、3D等3个开源项目。
HTML5网页支持开发AR、AI和3D,读者会问“为什么不在小程序内嵌HTML5网页”?
因为iOS版微信中的HTML5网页不能打开手机摄像头,所以无法实现摄像头画面和虚拟模型叠加的AR效果。
Android版微信中的HTML5网页能打开手机摄像头,但其他AR开源项目是用C++编译为JavaScript,需要解决小程序的每个分包大小不能超过2MB和小程序的浏览器兼容性等问题。
一、开源项目介绍
《微信小程序3D》:在小程序中显示全景图片和3D模型,可跟随手机陀螺仪自动旋转。
sanyuered/WeChat-MiniProgram-AR-3D
《微信小程序AI》:在小程序中检测人脸特征点,并在面部位置显示3D模型或2D图像贴纸。
sanyuered/WeChat-MiniProgram-AR-TFJS
《微信小程序AR》:在小程序中检测识别图像,并在识别图像上显示2D图像贴纸。
sanyuered/WeChat-MiniProgram-WebAR
二、更新内容
《微信小程序3D》
1、通过扫描3D模型网址的二维码,替换3D模型。
2、场景中增加了光源使模型有阴影底纹。
3、设置设备像素密度(device pixel ratio)使全景图片显示更清晰等。
《微信小程序AI》
1、将人脸贴纸从2D显示改为3D显示。包含3D眼镜模型和2D猫胡须图像的演示。
2、修改了人脸检测方法:移除了face-api.js库,改为使用google的face-landmarks-detection库。
3、tensorflow.js的版本从1.x版升级到2.1版。
《微信小程序AR》
1、可以将2D图像或3D模型叠加在识别图像上。
2、该项目的人脸检测方法比开源项目《微信小程序AI》的人脸检测方法慢。
3、iOS版本的相机实时检测的速度非常慢,大约每帧3秒,去掉了实时检测的演示。
三、技术实现
1、怎样根据人脸特征点,将3D眼镜模型叠加在相机画面中的眼睛位置?
平移值:从人脸特征点映射图中,选择一个特征点,深度学习模型会检测出该特征点在世界坐标系的坐标。因为该模型没有特征点在双眼中间位置,所以挑选了双眼内侧的3个特征点,通过计算三角形的中心,表示3D模型的位置center。
var triangle = new THREE.Triangle();
triangle.set(p0, p1, p2);
const center = new THREE.Vector3();
triangle.getMidpoint(center);
旋转值:通过双眼内侧的3个特征点,计算3D模型的旋转值rotation。
const rotation = new THREE.Matrix4();
const x = p1.clone().sub(p2).normalize();
const y = p1.clone().sub(p0).normalize();
const z = new THREE.Vector3().crossVectors(x, y);
const y2 = new THREE.Vector3().crossVectors(x, z).normalize();
const z2 = new THREE.Vector3().crossVectors(x, y2).normalize();
rotation.makeBasis(x, y2, z2);
缩放值:通过变换前和变换后2个特征点之间的距离,得到3D模型的缩放值scale。(粗略的估计)
var p1 = prediction.mesh[id1];
var p1_scaled = prediction.scaledMesh[id1];
var p2 = prediction.mesh[id2];
var p2_scaled = prediction.scaledMesh[id2];
var a = p2[0] - p1[0];
var b = p2_scaled[0] - p1_scaled[0];
var scale = b / a;
2、怎样根据图像特征点,将2D猫胡须图像叠加在相机画面中的嘴巴位置?
平移值:从识别图像中选择一个叠加猫胡须的坐标A(x,y),根据图像的变换矩阵H(3x3单应性矩阵),计算该坐标在相机画面中的坐标B(_x,_y)。
var m00 = td[0], m01 = td[1], m02 = td[2],
m10 = td[3], m11 = td[4], m12 = td[5],
m20 = td[6], m21 = td[7], m22 = td[8];
var x2 = m00 * x + m01 * y + m02;
var y2 = m10 * x + m11 * y + m12;
var ws = m20 * x + m21 * y + m22;
var sc = 1.0 / ws;
var _x = x2 * sc;
var _y = y2 * sc;
return { _x, _y };
旋转和缩放值:根据图像的变换矩阵H(3x3单应性矩阵),计算图像的旋转值rotation和缩放值scale。
var m00 = td[0],
m10 = td[3],
m20 = td[6];
var norm = Math.sqrt(m00 * m00 +
m10 * m10 +
m20 * m20);
var H = td.map(function (item) {
return item / norm;
});
m00 = H[0];
m10 = H[3];
m20 = H[6];
var m01 = H[1], m02 = H[2],
m11 = H[4], m12 = H[5],
m21 = H[7], m22 = H[8];
var c1 = [m00, m10, m20];
var c2 = [m01, m11, m21];
var c3 = [
m21 * m10 - m20 * m11,
m20 * m01 - m21 * m00,
m00 * m11 - m10 * m01];
var rotation =
[
c1[0], c2[0], c3[0], 0,
c1[1], c2[1], c3[1], 0,
c1[2], c2[2], c3[2], 0,
0, 0, 0, 1
];
var scale = 1 / m22;
四、3个开源项目之间的关系
界面显示:《微信小程序3D》
人脸检测:《微信小程序AI》
图像检测:《微信小程序AR》