내 얼굴도 보름달

Hyejeong Lim·2022년 11월 7일
2

project

목록 보기
2/2
post-thumbnail

2022년 10월 7일부터 10월 10일까지 세종호수공원에서 열린 세종축제 시민참여 기획프로그램에 홍익대학교 조형대학 미디어아트 크루 오픈소스랩이 참여했습니다. 저는 <내 얼굴도 보름달> 작품의 개발로 참여했습니다.

작품이미지

<내 얼굴도 보름달>은 대형 보름달에 내 얼굴을 띄워 소원을 이루는 인터랙티브 미디어 아트입니다.

특정한 위치에 선 사용자의 얼굴이 스크린 속 보름달에 띄워지고, 활짝 웃으면 간직한 소원이 이루어지는 내용을 담고 있습니다.

⚙️ 제작

<내 얼굴도 보름달>은 기획을 맡은 연주님의 아이디어로, 둘이서 함께 팀으로 작업했습니다.

'보름달에 얼굴을 둥둥 띄워보고 소원을 이뤄보자'를 주제로 아이데이션과 개발을 진행했습니다.

  1. 사용자 얼굴 인식
  2. 보름달 속에 얼굴 띄우기
  3. 웃으면 보름달이 떠오른다

야외 행사이기 때문에 인터넷 연결이 필요없도록 Node.js 패키지로 서버를 만들어 구동시켰습니다.

1. 얼굴 인식

구현 방법을 찾기 위해 미디어 파이프, TensorFlow 등의 라이브러리 튜토리얼 등을 따라해 보았고, face-api.js를 이용하여 제작하기로 결정했습니다.

사용 라이브러리

face-api.js

얼굴 인식을 위해 face.api가 가진 모델을 불러오고 HTML 환경에 웹캠을 스트림합니다.

const video = document.getElementById('video')

Promise.all([
    faceapi.nets.tinyFaceDetector.loadFromUri("/models"),
    faceapi.nets.faceLandmark68Net.loadFromUri("/models"),
    faceapi.nets.faceRecognitionNet.loadFromUri("/models"),
    faceapi.nets.faceExpressionNet.loadFromUri("/models"),
]).then(startVideo);

function startVideo() {
    navigator.getUserMedia(
        { video: {} },
        stream => video.srcObject = stream,
        err => console.error(err)
    )
}

감지된 얼굴에 네모박스를 띄워볼까요?

비디오 사이즈와 동일한 새 캔버스 객체를 생성한 후,
아까 불러온 face-api model을 이용하여 인식된 얼굴의 위치, 눈코입 랜드마크, 표정 인식 정보를 띄울 수 있습니다.

video.addEventListener('play', () => {
  const canvas = faceapi.createCanvasFromMedia(video)
  document.body.append(canvas)
  const displaySize = { width: video.width, height: video.height }
  faceapi.matchDimensions(canvas, displaySize)
  
  setInterval(async () => {
    const detections = await faceapi.detectAllFaces(video, new faceapi.TinyFaceDetectorOptions()).withFaceLandmarks().withFaceExpressions()
    const resizedDetections = faceapi.resizeResults(detections, displaySize)
    canvas.getContext('2d').clearRect(0, 0, canvas.width, canvas.height)
    faceapi.draw.drawDetections(canvas, resizedDetections)
    faceapi.draw.drawFaceLandmarks(canvas, resizedDetections)
    faceapi.draw.drawFaceExpressions(canvas, resizedDetections)
  }, 100)
})

(참고) JavaScript로 실시간 얼굴 감지 구축

2. 얼굴을 달에 띄우기

얼굴을 달 안에 넣기 위해, 박스 안의 영상을 추출합니다.

// 얼굴이 들어갈 곳을 지정해줍니다
const outputImage = document.getElementById('outputImage');

// 인식한 얼굴을 띄워주는 함수
async function extractFaceFromBox(inputImage, box) {
    const regionsToExtract = [
        new faceapi.Rect(box.x, box.y, box.width, box.height)
    ]

    let faceImages = await faceapi.extractFaces(inputImage, regionsToExtract)

    if (faceImages.length == 0) {
        console.log('얼굴을 찾을 수 없습니다')
    }
    else {
        faceImages.forEach(cnv => {
            outputImage.style.backgroundImage = `url(${cnv.toDataURL()})`;
            outputImage.style.backgroundBlendMode = 'difference';
        })
    }
}

(참고) How to extract the detected faces from face-api.js

CSS로 얼굴 주변에 투명도를 준 radial-gradient을 설정하면 보름달처럼 보입니다.

3. 웃으면 달이 떠오르도록

face-api.js의 표정 인식 모델을 사용하면 표정에서 드러나는 감정을 읽을 수 있습니다.

인식된 얼굴이 있을 경우, 해당 얼굴의 표정을 읽어 추출된 happy 값을 변수에 저장합니다.
변수에 따라 달의 CSS를 변경시켜 줍니다.

happiness = detection.expressions.happy;

// 웃으면 올라오도록
if (happiness > 0.1) {
	console.log('웃다');
	if (pos < 140) pos += 8;
}
// 안웃으면 내려가도록
else {
	if (pos > 0) pos -= 2;
}

outputImage.style.bottom = pos + "px";
outputImage.style.width = 150 + pos * 3 + "px";
outputImage.style.height = 150 + pos * 3 + "px";

happiness의 값이 높아짐에 따라, 얼굴이 포함된 달의 y좌표 및 달의 크기를 변경해주었습니다.
최대값을 정해둔 이유는 달이 너무 커지거나 화면 위로 올라가지 않도록 설정해 둔 것입니다.

집에서도 체험해 보세요!

[<내 얼굴도 보름달> 체험해보기]
현재 헤로쿠 무료 호스팅 기능이 막혀, 깃허브 링크로 대체합니다.

⛔️ Registration of backend webgl failed 오류가 난다면!

해결 : 크롬 설정에서 가속엔진 활성화 시키기

Node.js 패키지 생성 및 실행 - Node.js package, npm init, npm run

🎊 행사

세종호수공원 정문 바로 밑 터널에서 오픈소스랩이 준비한 전시가 진행되었습니다.

10000안시의 빔 프로젝터를 설치하여 행사가 시작되는 터널 데크 부분에 크게 비추었습니다.

행사의 대문 역할을 하는 <내 얼굴도 보름달>을 보고 찾아 와 얼굴을 띄워보고, 입구에서 <두개의 달> 게임을 즐기며 상품을 받고, 터널 안쪽을 걸으며 <노래하는 달>과 기념사진을 찍을 수 있습니다.

노란 발자국에 위에 서면 전방에 있는 웹캠에 얼굴이 비치게 됩니다.

키가 작은 아이들을 위해 발 받침대도 준비했습니다.

지나가는 시민 분들께 권유하면 대부분 모두 참여해주셨습니다.

보름달이 멀리서도 크게 보이니 아이 얼굴을 띄워보고 싶어 찾아오는 부모님들이 많이 계셨습니다.

달에 띄워진 본인의 모습을 너무 재밌어 하여 오래 즐기다 간 아이도 있었고, 부끄럼이 많아 달을 띄우지 못한 수줍은 아이도 있었습니다.

또 어린이 뿐 아닌 남녀노소 즐겁게 체험해 주셨습니다.

✍️ 회고

이렇게 큰 야외 전시에 참여하는 건 처음이었는데, 추후 다른 전시를 진행하는데 좋은 밑거름이 된 것 같다. 직접 재료를 준비하거나 업체랑 컨택도 해보고, 시민 분들도 잘 참여해 주셔서 뿌듯했다. 팀랩이나 디스트릭트 등, 미디어아트 전시로 유명한 기업들이 전시를 열기 위해 돈을 번다는 말이 기억에 남는다. 진행하는 순간을 정신없이 즐겨서 그런지, 시간 가는 줄도 몰랐고 즐거운 경험이었다. 행사 리드한 예지언니, 참여한 멤버분들, 도와주신 학생분들, 업체 직원분들에게 고맙다.

profile
@limteract

0개의 댓글