洪流学堂,让你快人几步。你好,我是你的技术探路者郑洪智,你可以叫我大智(vx: zhz11235)。
之前探索了
SenseAR的手势识别发射爱心
,还有
深入探索的第二集
。
后来很多同学问能不能出个
人脸检测
的教程,诺,他来了!
对SenseAR还不太熟悉的同学可以看下大智的视频:
最终效果
这个教程中使用了最新的SenseAR,可以在很短时间内实现人脸检测,给脸上添加装饰。
建立工程
注意必须使用Unity 2018.4版本,建议使用2018.4中国增强版最新版。
路径中一定不要有中文!!!
,
路径中一定不要有中文!!!
,
路径中一定不要有中文!!!
,否则打包可能出现问题。
安装SenseAR 插件
在Packamager中搜索SenseAR XR plugin,我在这用的是最新版的
1.1.0-preview.2
版本。
导入示例工程
SenseAR是个新鲜的东西,之前都没接触过,所以最好的开始就是先看下示例,看看能做什么。 如何导入示例工程呢?
1、在Project窗口的Packages中找到
SenseAR XR Plugin
目录 2、在目录上右键菜单中选择
Show in Explorer
3、在打开的目录进入
com.unity.xr.arstand@1.1.0-preview.2\Samples~
目录 4、将目录中的
Example
文件夹拖到Unity的Project窗口的Assets文件夹中。
具体流程看到下图:
查看示例
导入之后呢,你会发现这里面有很多很多的场景,人脸检测场景是这个
FaceMesh
。
哇,还有那么多其他场景都是什么用呢?可以看下大智的视频:
这个场景是没办法在电脑上运行的,只能发布到Android手机上运行。
咱们可以先发布看一下现在有什么功能。
发布过程
发布有以下几步: 1、确保安装好了Android发布的环境(JDK目前Unity已经内置了,Android SDK需要自行下载,可以使用Android Studio管理Android SDK),以及Unity的Android Support(推荐在Unity Hub中安装)。
2、在Unity的Build Settings中将平台切换为Android。
3、配置工程的Player Settings。
-
Package Name修改一下,别是默认的那个,我这设置为 com.Company.FaceMesh
-
Mininum API Level设置为 Android 7.0 API level 24
4、 在手机上安装SenseAR2.3,下载地址是
http://openar.sensetime.com/sdks
可能需要先卸载旧版本:小米预装版本SenseAR在应用设置里面名称为ARServer,OPPO预装版本SenseAR的名字为ARUnit
5、将手机
开启开发者模式
,USB连接到电脑上
6、记得打开FaceMesh场景,点击Unity菜单栏
File > Build and Run
,选择一个存放apk的路径。
如果发布遇到错误,可以对照这篇文章检查: SenseAR常见问题总结
体验人脸检测App
如果打开黑屏检查下是否安装了SenseAR2.3,下载地址是
http://openar.sensetime.com/sdks
最开始要同意使用摄像头的权限。
开发
好,到这呢,我们已经体验了一把SenseAR的人脸检测了,但是好像只是显示了一个虚拟的人脸,如何在脸上添加一些装饰物呢?
在人脸上添加装饰物有两个思路:
-
有没有一些预制的锚点,比如眼睛、鼻子、嘴巴、耳朵的位置,然后挂在对应的位置
-
可不可以通过点击脸上的某个点,在对应的位置添加装饰物
大智根据这两个思路看了一下,SenseAR中并没有预制特殊位置的锚点,所以第一个思路暂时不太可行,下面去尝试下第二个思路。
点击脸上的某个点,需要物理系统中的射线检测,必要条件是要有脸部的碰撞网格,那
能不能给脸部添加碰撞网格(MeshCollider)呢
?
根据这个思路,我们找到了FaceMesh场景中的AR Session Origin物体上的两个组件:ARFaceManager和DisplayFaceInfo。
ARFaceManager是SenseAR package中的代码,咱们最好不要修改。这个组件会将识别到的人脸,使用ARFace Prefab中的设置显示出来。
DisplayFaceInfo组件是这个示例中的代码,它获取了ARFaceManager中的相关信息并显示在UI上。
咱们来看下ARFace这个Prefab上面都有什么东西,打开大门的钥匙或许就在这个物体上:
这上面的组件依次是:
-
Transform:决定了它的位置、旋转、缩放
-
AR Face:包含了脸部的信息,仅包含数据
-
AR Face Mesh Visualizer: 获取AR Face中的数据,并且可视化地显示出来(会自动更新mesh以及MeshCollider)。 如果想更深入了解,可以读一下这个组件的代码。
-
Mesh Collider:网格碰撞器,可用于射线检测
-
Mesh Filter:设置mesh的数据
-
Mesh Renderer:将mesh网格数据和材质关联起来,显示到场景中
-
材质球:Mesh Renderer组件使用的材质
分析完这个ARFace的Prefab,就发现,这不是已经有了钥匙了嘛,有了Mesh Collider就可以用射线检测的方式在脸上添加物体了。
改造DisplayFaceInfo代码
using
UnityEngine
;
using
UnityEngine
.
UI
;
using
UnityEngine
.
XR
.
ARFoundation
;
[
RequireComponent
(
typeof
(
ARFaceManager
)
)
]
public
class
DisplayFaceInfo
:
MonoBehaviour
{
[
SerializeField
]
Text
m_FaceInfoText
;
public
Text
faceInfoText
{
get
{
return
m_FaceInfoText
;
}
set
{
m_FaceInfoText
=
value
;
}
}
ARFaceManager
m_FaceManager
;
void
Awake
(
)
{
m_FaceManager
=
GetComponent
<
ARFaceManager
>
(
)
;
}
void
Update
(
)
{
if
(
m_FaceManager
.
subsystem
!=
null
&&
faceInfoText
!=
null
)
{
faceInfoText
.
text
=
$"Supported number of tracked faces:
{
m_FaceManager
.
supportedFaceCount
}
\n"
+
$"Max number of faces to track:
{
m_FaceManager
.
maximumFaceCount
}
\n"
+
$"Number of tracked faces:
{
m_FaceManager
.
trackables
.
count
}
"
;
}
// !!!下面是添加的代码
if
(
Input
.
GetMouseButtonUp
(
0
)
)
{
var
camera
=
GetComponent
<
ARSessionOrigin
>
(
)
.
camera
;
var
ray
=
camera
.
ScreenPointToRay
(
Input
.
mousePosition
)
;
if
(
Physics
.
Raycast
(
ray
,
out
var
hit
,
1000
)
)
{
var
go
=
GameObject
.
CreatePrimitive
(
PrimitiveType
.
Sphere
)
;
go
.
transform
.
localScale
=
Vector3
.
one
*
0.01f
;
// 设置父物体为人脸,这样物体会跟随人脸移动
go
.
transform
.
SetParent
(
hit
.
transform
)
;
go
.
transform
.
position
=
hit
.
point
;
}
}
}
}
添加的代码只有最后的十来行,都是射线检测相关的内容,如果你对射线检测还不熟悉,可以看下大智的一个射线检测详解视频:
https://www.bilibili.com/video/av24858288
最后的效果是这样子的:
更多探索
上面呢,咱们提到了两种思路,其中第一种思路虽然SenseAR没有内置,但是咱们或可以根据顶点的位置来找到眼睛、鼻子、嘴巴对应的位置点。 大智已经做了探索有如下结论:脸部的网格固定是11510个顶点
大概思路如下,你可以和大智一起探索哦:根据射线检测到的点,计算出离点击点最近的顶点,这个顶点顺序大概率是不会变的,可以作为锚定的坐标点
本教程源码及后续更新
由于源码后续可能会更新,就不直接打包传在这里了。 本工程的持续更新源码可以在
洪流学堂
公众号回复
face
获取。
好了,今天就絮絮叨叨到这里了。 没讲清楚的地方欢迎评论。
我是大智(vx: zhz11235),你的技术探路者,下次见!
别走!
点赞
,
收藏
哦!
好,你可以走了。

被折叠的 条评论
为什么被折叠?



