摘要:Unity+SenseAR開發的AR應用,基於人臉檢測,給臉部添加裝飾物~
洪流學堂,讓你快人幾步。你好,我是你的技術探路者鄭洪智,你可以叫我大智(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、在打開的目錄進入[email protected]\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),你的技術探路者,下次見!
別走!點贊,收藏哦!
好,你可以走了。