Unity SenseAR教程:人臉檢測之放置臉部掛飾【含源碼】

摘要:Unity+SenseAR開發的AR應用,基於人臉檢測,給臉部添加裝飾物~

洪流學堂,讓你快人幾步。你好,我是你的技術探路者鄭洪智,你可以叫我大智(vx: zhz11235)。

之前探索了SenseAR的手勢識別發射愛心,還有深入探索的第二集

後來很多同學問能不能出個人臉檢測的教程,諾,他來了!

對SenseAR還不太熟悉的同學可以看下大智的視頻:

最終效果

這個教程中使用了最新的SenseAR,可以在很短時間內實現人臉檢測,給臉上添加裝飾。

facepoint.gif

建立工程

注意必須使用Unity 2018.4版本,建議使用2018.4中國增強版最新版。
路徑中一定不要有中文!!!路徑中一定不要有中文!!!路徑中一定不要有中文!!!,否則打包可能出現問題。

創建工程.gif

安裝SenseAR 插件

在Packamager中搜索SenseAR XR plugin,我在這用的是最新版的1.1.0-preview.2版本。

安裝sensear.gif

導入示例工程

SenseAR是個新鮮的東西,之前都沒接觸過,所以最好的開始就是先看下示例,看看能做什麼。
如何導入示例工程呢?

1、在Project窗口的Packages中找到SenseAR XR Plugin目錄
2、在目錄上右鍵菜單中選擇Show in Explorer
3、在打開的目錄進入[email protected]\Samples~目錄
4、將目錄中的Example文件夾拖到Unity的Project窗口的Assets文件夾中。

具體流程看到下圖:

導入example.gif

查看示例

導入之後呢,你會發現這裏面有很多很多的場景,人臉檢測場景是這個FaceMesh

哇,還有那麼多其他場景都是什麼用呢?可以看下大智的視頻:

**這個場景是沒辦法在電腦上運行的,只能發佈到Android手機上運行。**咱們可以先發布看一下現在有什麼功能。

發佈過程

發佈有以下幾步:
1、確保安裝好了Android發佈的環境(JDK目前Unity已經內置了,Android SDK需要自行下載,可以使用Android Studio管理Android SDK),以及Unity的Android Support(推薦在Unity Hub中安裝)。

android support.gif

2、在Unity的Build Settings中將平臺切換爲Android。

切換到android.gif

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

最後的效果是這樣子的:

facepoint.gif

更多探索

上面呢,咱們提到了兩種思路,其中第一種思路雖然SenseAR沒有內置,但是咱們或可以根據頂點的位置來找到眼睛、鼻子、嘴巴對應的位置點。
大智已經做了探索有如下結論:臉部的網格固定是11510個頂點

大概思路如下,你可以和大智一起探索哦:根據射線檢測到的點,計算出離點擊點最近的頂點,這個頂點順序大概率是不會變的,可以作爲錨定的座標點

本教程源碼及後續更新

由於源碼後續可能會更新,就不直接打包傳在這裏了。
本工程的持續更新源碼可以在洪流學堂公衆號回覆face獲取。


好了,今天就絮絮叨叨到這裏了。
沒講清楚的地方歡迎評論。

我是大智(vx: zhz11235),你的技術探路者,下次見!

別走!點贊收藏哦!

好,你可以走了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章