天天看點

如何用AR Engine開發一個虛拟形象表情包?

現如今,人們在網上聊天、發帖時越來越愛用表情包,表情包一方面是一種個性化的表達方式,另一方面更能傳達出當下的心理活動,可以說在網絡社交中表情包是一個不可或缺的存在。加上近年來元宇宙的興起,3D虛拟形象廣泛應用,使用者可以通過自己的表情來控制虛拟形象的表情,做一系列專屬的表情包,更加生動形象。

那麼,如何讓虛拟形象擁有人類一樣多變的表情呢?HMS Core AR Engine的人臉表情跟蹤能力就能幫助實作,實時計算人臉各表情對應的參數值。使用者可通過自己的面部動作,控制虛拟人物的表情,最終制作成虛拟人物的各種生動的表情,以更有趣的形式配合傳達文字情緒,同時也極大友善了虛拟人物的表情制作等應用場景。

比如在社交App中,不想露臉的人可以把自己的喜怒哀樂通過虛拟形象的表情傳達,在保護隐私的同時又增加了趣味性。在直播、電商App裡,為了避免同質化,商家利用虛拟主播的表情生動性能夠給使用者帶來更生動的消費場景以及新奇的互動體驗,激發年輕人對沉浸式虛拟娛樂和數字消費的需求。在短視訊、拍照等App中,使用者利用人臉表情控制虛拟形象的表情,進行自我展示與表達,拉近人與人的距離;而在教育、文旅等App中,捕捉人臉圖像資訊,實時将其了解成人臉表情内容,用虛拟形象進行講解教學更加生動,激發使用者的學習興趣。

實作方法

AR Engine提供“人臉表情跟蹤”能力,可實時跟蹤擷取人臉圖像資訊,計算人臉的位姿,并将其了解成人臉表情内容,并轉化成各種表情參數,利用表情參數可以實作人臉表情直接控制虛拟形象的表情。AR Engine目前共提供64種表情,包含眼睛、眉毛、眼球、嘴巴、舌頭等主要臉部器官的表情動作。眼部共有21種表情,包括眼球的移動、睜閉眼、眼皮的微動作等;嘴部共有28種表情,包括張嘴噘嘴、嘴角下拉、抿嘴唇、舌頭的動作等;眉毛共有5種表情,包括擡眉、單側眉毛朝下或擡上等。其他具體表情參數可見FaceAR設計規範。

效果展示

開發步驟

開發環境要求:

JDK 1.8.211及以上。

安裝Android Studio 3.0及以上:

minSdkVersion 26及以上

targetSdkVersion 29(推薦)

compileSdkVersion 29(推薦)

Gradle 6.1.1及以上(推薦)

在華為終端裝置上的應用市場下載下傳AR Engine服務端APK(需在華為應用市場,搜尋“華為AR Engine”)并安裝到終端裝置。

測試應用的裝置:參見AREngine特性軟硬體依賴表。如果同時使用多個HMS Core的服務,則需要使用各個Kit對應的最大值。

開發準備

  1. 在開發應用前需要在華為開發者聯盟網站上注冊成為開發者并完成實名認證,具體方法請參見帳号注冊認證。
  2. 華為提供了Maven倉內建方式的AR Engine SDK包,在開始開發前,需要将AR Engine SDK內建到您的開發環境中。
  3. Android Studio的代碼庫配置在Gradle插件7.0以下版本、7.0版本和7.1及以上版本有所不同。請根據您目前的Gradle插件版本,選擇對應的配置過程。
  4. 以7.0為例:

打開Android Studio項目級“build.gradle”檔案,添加Maven代碼庫。

在“buildscript > repositories”中配置HMS Core SDK的Maven倉位址。

buildscript {
    	repositories {
        	google()
        	jcenter()
        	maven {url "https://developer.huawei.com/repo/" }
    	}
}
           

打開項目級“settings.gradle”檔案,配置HMS Core SDK的Maven倉位址

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    		repositories {
       			 repositories {
           			 	google()
            			jcenter()
            			maven {url "https://developer.huawei.com/repo/" }
       			 }
   			 }
}
           
  1. 添加依賴 在“dependencies”中添加如下編譯依賴:
dependencies {
    implementation 'com.huawei.hms:arenginesdk:{version}
}
           

應用開發

  1. 運作前驗證:檢查目前裝置是否安裝了AR Engine,若已經安裝則正常運作,若沒有安裝,App應采用合适的方式提醒使用者安裝AR Engine,如主動跳轉應用市場,請求安裝AR Engine。具體實作代碼如下
boolean isInstallArEngineApk =AREnginesApk.isAREngineApkReady(this);
if (!isInstallArEngineApk) {
    // ConnectAppMarketActivity.class為跳轉應用市場的Activity。
startActivity(new Intent(this, com.huawei.arengine.demos.common.ConnectAppMarketActivity.class));
    isRemindInstall = true;
}
           
  1. 建立AR場景:AR Engine提供5種場景,包括運動跟蹤(ARWorldTrackingConfig)、人臉跟蹤(ARFaceTrackingConfig)、手部識别(ARHandTrackingConfig)、人體跟蹤(ARBodyTrackingConfig)和圖像識别(ARImageTrackingConfig)。

    調用ARFaceTrackingConfig接口,建立人臉跟蹤。

// 建立ARSession。
mArSession = new ARSession(this);
// 根據要使用的具體場景,選用具體的Config來初始化ARSession。
ARFaceTrackingConfig config = new ARFaceTrackingConfig(mArSession);
           

建立人臉跟蹤ARSession後,可通過config.setXXX方法配置場景參數

//設定相機的打開方式,外部打開或内部打開,其中外部打開隻能在ARFace中使用,推薦使用内部打開相機的方式。
mArConfig.setImageInputMode(ARConfigBase.ImageInputMode.EXTERNAL_INPUT_ALL);
           
  1. 配置人臉跟蹤AR場景參數,啟動人臉跟蹤場景:
mArSession.configure(mArConfig);
mArSession.resume();
           
  1. 建立FaceGeometryDisplay類,此類是擷取人臉幾何資料,并在螢幕上渲染資料
public class FaceGeometryDisplay {
//初始化與面幾何體相關的OpenGL ES渲染,包括建立着色器程式。
void init(Context context) {...
}
}
           
  1. 在FaceGeometryDisplay類中建立,onDrawFrame方法,用face.getFaceGeometry()方法來擷取人臉Mesh
public void onDrawFrame(ARCamera camera, ARFace face) {
    ARFaceGeometry faceGeometry = face.getFaceGeometry();
    updateFaceGeometryData(faceGeometry);
    updateModelViewProjectionData(camera, face);
    drawFaceGeometry();
    faceGeometry.release();
}
           
  1. 在FaceGeometryDisplay類中建立方法updateFaceGeometryData()傳入人臉Mesh資料進行配置 用OpenGl來設定表情參數
private void  updateFaceGeometryData(ARFaceGeometry faceGeometry){
FloatBuffer faceVertices = faceGeometry.getVertices();
FloatBuffer textureCoordinates =faceGeometry.getTextureCoordinates();
//擷取人臉Mesh紋理坐标點數組,在渲染時,與getVertices()傳回的頂點資料配合使用。 
}
           
  1. 建立FaceRenderManager類,此類來管理與人臉資料相關的渲染:
public class FaceRenderManager implements GLSurfaceView.Renderer {
//構造函數初始化上下文和activity
public FaceRenderManager(Context context, Activity activity) {
    mContext = context;
    mActivity = activity;
}
//設定ARSession,擷取最新資料
public void setArSession(ARSession arSession) {
    if (arSession == null) {
        LogUtil.error(TAG, "Set session error, arSession is null!");
        return;
    }
    mArSession = arSession;
}
//設定ARConfigBase,擷取配置模式。
public void setArConfigBase(ARConfigBase arConfig) {
    if (arConfig == null) {
        LogUtil.error(TAG, "setArFaceTrackingConfig error, arConfig is null.");
        return;
    }
    mArConfigBase = arConfig;
}
//設定外置攝像頭打開方式
public void setOpenCameraOutsideFlag(boolean isOpenCameraOutsideFlag) {
    isOpenCameraOutside = isOpenCameraOutsideFlag;
}
...
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config) {
mFaceGeometryDisplay.init(mContext);
}
}
           
  1. 最後在FaceActivity中 調用方法:通過設定這些方法來實作最終的效果
public class FaceActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
mFaceRenderManager = new FaceRenderManager(this, this);
mFaceRenderManager.setDisplayRotationManage(mDisplayRotationManager);
mFaceRenderManager.setTextView(mTextView);

glSurfaceView.setRenderer(mFaceRenderManager);
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
}
}
           

具體實作可參考示例代碼。