MindAR을 사용해서 Face Mask 씌우기
MindAR 이란?
MindAR은 이미지 트랙킹과 페이스 트랙킹을 제공하는 웹 증강 현실 오픈소스 라이브러리이다. AFRAME (웹 기반의 가상 현실(AR) 프레임워크) 통합으로 시작하여 three.js와 직접적인 결합이 가능하다.
실습 내용
공식 document에 나와 있는 웹캠 이미지 내에서 페이스 트랙킹을 하여 얼굴 영역 위에 3D 이미지를 씌우는 예시를 실습해 보았고, 예시와 다르게 마스크를 씌운 웹캠 이미지만 띄우도록 하였다.
이 실습 내용은 얼굴 표정을 나타내는 52개의 blendshape로 웹캠 이미지 내에서 얼굴을 감지하고 감지된 blendshape를 사용해 머리 부분에 아바타를 씌우는 것을 제어하는 것이다.
blendshape이란 3D 모델에서 다양한 모델의 표정을 생성하기 위해서 사용하는 기술로 예시에서는 52개를 사용하였다. (자세한 목록은 document에서 확인 가능)
실습한 코드는 아래에 정리해 두었다.
1. 라이브러리 목록 (importmap으로 라이브러리 추가, 예시 코드와 동일)
<script type="importmap">
{
"imports": {
"three": "https://unpkg.com/three@0.160.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.160.0/examples/jsm/",
"mindar-face-three": "https://cdn.jsdelivr.net/npm/mind-ar@1.2.5/dist/mindar-face-three.prod.js"
}
}
</script>
2. 웹캠 영역 관련 div html 코드
<div id="webcam-container">
<img id="webcam" src="{{ url_for('video_feed') }}" alt="Webcam Feed"/>
<div id="facemask-container"></div>
</div>
3. JavaScript 코드
예시 코드와 거의 동일하지만 그대로 가져왔을 때 null 에러가 발생하여 69행은
avatar = new Avatar();
로 수정해주었다.
import * as THREE from 'three';
import {GLTFLoader} from 'three/addons/loaders/GLTFLoader.js';
import {MindARThree} from 'mindar-face-three';
class Avatar {
constructor() {
this.gltf = null;
this.morphTargetMeshes = [];
}
async init() {
const url = "https://assets.codepen.io/9177687/raccoon_head.glb";
const gltf = await new Promise((resolve) => {
const loader = new GLTFLoader();
loader.load(url, (gltf) => {
resolve(gltf);
});
});
gltf.scene.traverse((object) => {
if ((object).isBone && !this.root) {
this.root = object; // as THREE.Bone;
}
if (!(object).isMesh) return
const mesh = object;
if (!mesh.morphTargetDictionary || !mesh.morphTargetInfluences) return
this.morphTargetMeshes.push(mesh);
});
this.gltf = gltf;
}
updateBlendshapes(blendshapes) {
const categories = blendshapes.categories;
let coefsMap = new Map();
for (let i = 0; i < categories.length; ++i) {
coefsMap.set(categories[i].categoryName, categories[i].score);
}
for (const mesh of this.morphTargetMeshes) {
if (!mesh.morphTargetDictionary || !mesh.morphTargetInfluences) {
continue;
}
for (const [name, value] of coefsMap) {
if (!Object.keys(mesh.morphTargetDictionary).includes(name)) {
continue;
}
const idx = mesh.morphTargetDictionary[name];
mesh.morphTargetInfluences[idx] = value;
}
}
}
}
let mindarThree = null;
let avatar = null;
const setup = async () => {
mindarThree = new MindARThree({
container: document.querySelector("#facemask-container"),
});
const {renderer, scene, camera} = mindarThree;
const light = new THREE.HemisphereLight(0xffffff, 0xbbbbff, 1);
scene.add(light);
const anchor = mindarThree.addAnchor(1);
avatar = new Avatar();
await avatar.init();
avatar.gltf.scene.scale.set(2, 2, 2);
anchor.group.add(avatar.gltf.scene);
}
const start = async () => {
if (!mindarThree) {
await setup();
}
await mindarThree.start();
const {renderer, scene, camera} = mindarThree;
renderer.setAnimationLoop(() => {
const estimate = mindarThree.getLatestEstimate();
if (estimate && estimate.blendshapes) {
avatar.updateBlendshapes(estimate.blendshapes);
}
renderer.render(scene, camera);
});
}
start();
[출처]
[1] MindAR Documentation https://hiukim.github.io/mind-ar-js-doc/
[2] MindAR More Examples - ThreeJS Blendshapes https://hiukim.github.io/mind-ar-js-doc/more-examples/threejs-face-blendshapes/
MindAR | mind-ar-js
MindAR is an opensource web augmented reality library. It supports Image Tracking and Face Tracking.
hiukim.github.io