본문 바로가기
공허의 유산/표현의 자유

[sceneform]#4. augmented face review

by 바른생활머시마 2020. 3. 2.
728x90
반응형

몇 개 샘플을 살펴보니, 대체로 구현이 비슷한 패턴으로 되어 있는 것 같아요. 그래서, 이 패턴에 좀 익숙해지고, 이 패턴의 구조를 이해하면 ARCore를 이해하는데 도움이 될 것 같아서 다른 예제도 살펴보겠습니다.

 

augmented face 예제입니다.

https://github.com/google-ar/sceneform-android-sdk/tree/master/samples/augmentedfaces

 

google-ar/sceneform-android-sdk

Sceneform SDK for Android. Contribute to google-ar/sceneform-android-sdk development by creating an account on GitHub.

github.com

실행을 하면, 여우 모양의 코/귀 3D 오브젝트를 얼굴에 씌워줍니다. (3.1절을 맞아 MBC에서 '항거'를 방영했는데, 두고 두고 계속 봐야 할 영화 같네요. 영화를 만들어 주신 분들께 감사합니다.)

추출 된 얼굴의 크기/위치/방향을 고려하여 표준 얼굴 메쉬의 포즈를 계산하고, 그 표준 얼굴 메쉬의 좌표계를 기준으로 동일한 스케일로 오브젝트의 포즈를 정해주면 되겠네요.

 말이야 간단하지만, 이를 위해서 ARCore가 해주는 기능들은 참 많고, 그것을 직접 구현하지 않고 원하는 scene을 만들 수 있으니 참 편리하죠.

 

 이런 기능들의 구현에 사용 된 코드는 사실 그리 많지 않습니다. 정확히 말하면, ARCore를 사용하면 구현 해야 할 코드의 양이 많지 않다고 해야 하죠. 코드를 살펴 보겠습니다.

 

1. contents 변환

sceneform tool을 이용해서 변환을 할 수 있는데, 처음에 샘플을 받으면, 변환이 되어 있지 않습니다. 그래서, 리소스를 불러오는 코드에서 에러가 납니다.

빌드를 한번 하면, (빌드 전에 변환에 대한 확인을 먼저 하기 때문인지) 변환이 됩니다. 이 결과 파일이 생기는 경로가 프로젝트의 경로에 있으면 자동 추가가 되고, 그렇지 않으면 sfb를 따로 추가를 해줘야 합니다. 아래와 같이 resource 폴더 내에 raw라는 폴더가 생기고, 그 안에 sfb가 생깁니다.

오류가 사라지고 빌드도 정상적으로 됩니다.

 

2. 전체 구조

activity의 코드를 살펴보면, 구조는 매우 간단합니다. 지원되는 디바이스인지 체크하는 함수와 onCreate 뿐입니다.

달리 말하면, 기본적인 Face AR을 사용하기 위한 기능들은 대부분 준비가 되어 있다는 뜻이죠.

  @Override
  @SuppressWarnings({"AndroidApiChecker", "FutureReturnValueIgnored"})
  // CompletableFuture requires api level 24
  // FutureReturnValueIgnored is not valid
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (!checkIsSupportedDeviceOrFinish(this)) {
      return;
    }
...
...  
        });
  }

  /**
   * Returns false and displays an error message if Sceneform can not run, true if Sceneform can run
   * on this device.
   *
   * <p>Sceneform requires Android N on the device as well as OpenGL 3.0 capabilities.
   *
   * <p>Finishes the activity if Sceneform can not run
   */
  public static boolean checkIsSupportedDeviceOrFinish(final Activity activity) {
   ...
    return true;
  }
}

조금 더 자세히 알아보려면, onCreate를 살펴봐야겠습니다.

 

3. onCreate

코드 구성을 보면 다음과 같이 되어 있습니다.

 

- view 정의

- model renderable 빌드

- texture 빌드

- scene의 update listener 설정

 

마법은 view 정의에서 일어나는 것 같습니다. 

    setContentView(R.layout.activity_face_mesh);
    arFragment = (FaceArFragment) getSupportFragmentManager().findFragmentById(R.id.face_fragment);

layout 자체는 별로 특별할 것이 없이 매우 단순합니다. fragment 하나만 달랑 있습니다. 그런데, 이 fragment가 매우 특별한 녀석입니다. sceneform SDK에서 정의 된 fragment로써 많은 기능들을 담고 있습니다.

com.google.ar.sceneform.samples.augmentedfaces.FaceArFragment

 이 fragment도 구현하고자 하는 기능에 따라 조정을 할 수 있는데, 이 예제처럼 fragment를 상속받아서 필요한 설정을 조정하여 사용 하면 됩니다. 무엇을 담고 있는지는 차차 살펴 보기로 하고, 프로젝트 구조를 먼저 좀 살펴 보도록 하죠. 

 

 

그 다음 단계인 model과 texture 준비 과정은, 여우 모양으로 꾸밀 때 사용되는 contents를 준비하는 과정입니다.

model은 여우 코와 눈의 3D 오브젝트를 준비하는 과정이고, texture는 얼굴에 덧입혀질 텍스쳐를 준비하는 과정입니다.

 

결국, 영상으로 보여지는 얼굴의 위치에 보이지 않는 기본 얼굴 mesh를 만들고, 거기에 3D 오브젝트를 붙이고, 텍스쳐를 입히고, 그 얼굴을 계속 tracking 하면서 contents를 그리는, 간단한(?) 예 입니다.

 

준비 된 contents를 scene에 반영하기 위해 fragment로부터 scene을 얻고, update listener에서 보이는 얼굴을 추가하고, 사라진 얼굴을 제거하는 과정을 계속 실행합니다.

 

4. Face 정보

 검출 된 Face를 정보가 어떤 것인지 보면, 이를 기반으로 어떤 기능을 만들 수 있는지 가늠하는데 도움이 될 것 입니다.

위와 같이, 검출 된 각 얼굴은, 포즈와 메쉬 정보 등을 가지고 있어서, 그 위에 다양한 효과를 구현 할 수 있습니다.

 

얼굴에 자신이 원하는 텍스쳐나 3D 오브젝트를 사용하기 위해서 디자인을 하려면, 그 메쉬가 어떻게 되어 있는지, 텍스쳐의 UV는 어떻게 되어 있는지 알아야 합니다. SDK에는 그 정보가 포함되어 있으므로, 이를 참고하면 원하는 contents를 제작하여 사용 할 수 있습니다.

 

728x90
반응형

댓글