Barracuda 여행기 | 2. 실시간 얼굴(눈) 탐지

VIV LAB·2023년 5월 22일
1

Barracuda 여행기

목록 보기
2/3
post-thumbnail

이 글은 Barracuda 여행기 1편 | 1. 실시간 손 탐지 파티클 적용 에서 이어집니다.

안녕하세요. 비브스튜디오스 연구소의 서비스개발팀 정인호 연구원입니다.
오늘은 지난 포스팅 Barracuda 여행기 1편 | 1. 실시간 손 탐지 파티클 적용에 이어 Barracuda를 이용한 실시간 얼굴(눈) 탐지 프로젝트를 소개해드리려 합니다.

일반적으로 실시간 탐지(Real-time Detection) 모델은 복잡한 후처리 과정이 필요해 모델의 후처리를 담당하는 Compute Shader코드와 Compute Buffer의 세팅이 조금 까다로운데 이번 포스팅에서는 이에 관한 내용과 모델의 구조를 간단하게나마 이해하는 것을 목표로 해보겠습니다.

Postprocess of Detection Model

1

Detection 모델을 공부해보지 않은 사람들에게 input/output을 떠올려보라 한다면 대부분 위와 같은 이미지가 떠오를 것입니다. 이처럼 Input이미지가 들어갔을 때 "짠"하고 깔끔한 output이미지가 나온다면 얼마나 좋을까요?

안타깝게도 현실은 이렇지 못합니다.

2

모델의 실제 output은 모델크기에 따라 수백, 수천 개의 Bounding Box를 포함합니다. 이들 중 불필요한 bounding box들을 제거해주어야 깔끔한 output이 나오게 됩니다. 대략적인 후처리 과정은 다음과 같습니다.

  • Bounding box가 object가 아닌 부분을 탐지 → object score가 threshold보다 낮은 box들 제거
  • 하나의 object를 여러 bounding box가 탐지 → IoU score를 이용한 NMS(Non-Max Suppression)알고리즘 수행

알고리즘에 대한 구체적인 내용은 생략하고, Compute Shader/Compute Buffer 구현 과정에서 어떤 문제가 발생하는지 살펴보겠습니다.


Problem

3

Object의 위치와 class를 판별해주는 Detection모델은 단순한 분류 모델보다 훨씬 오랜 기간에 걸쳐 개발되어왔습니다. 여러 가지 어려움이 있었겠지만, 그중 하나는 이미지 내에 몇 개의 object가 존재하는지 모른다는 것입니다.

제가 이번 프로젝트에서 애를 먹었던 부분이 바로 이 부분입니다. Barracuda 패키지를 이용해 모델의 output을 얻고 Compute Shader로 후처리를 해야 하는데, 몇 개의 bounding box가 살아남는지 모르는 상황인 것입니다.


_postBuffer = new ComputeBuffer(Config.InputSize, sizeof(float));

그래픽스 API를 사용할 때 일반적인 버퍼의 생성 과정은 위 코드와 같습니다. 버퍼 안에 몇개의 element가 들어가는지, 하나의 element는 몇 byte를 차지하는지 하나하나 지정해주어야 합니다.

만약 제가 마주친 상황처럼 버퍼 안에 몇개의 element가 들어가는지 매 프레임마다 달라진다면 어떻게 해야할까요?


_post1Buffer = new ComputeBuffer(BoundingBox.Max, BoundingBox.Size, ComputeBufferType.Append);

_countBuffer = new ComputeBuffer(1, sizeof(uint), ComputeBufferType.Raw);

// ...

ComputeBuffer.CopyCount(_post1Buffer, _countBuffer, 0);

이런 경우 버퍼를 생성할 때 ComputeBufferType.Append 파라미터를 추가해주면 됩니다. 간략한 사용 방식은 다음과 같습니다.

  • 버퍼는 가장 큰 사이즈를 가정하여 일단 크게 생성
  • 버퍼 내에 현재 몇 개의 element가 포함되어 있는지를 나타내는 count value를 들고 다녀야 함
  • count value를 들고 다니는 별도의 compute buffer 생성
  • Shader 작업이 끝나면 ComputeBuffer.CopyCount 메서드를 이용해 countvalue를 전달해 주어야 함

처음에는 이 문제를 마주쳤을 때 버퍼의 사이즈를 dynamic하게 바꿀 수 있는 설정이 있을 것으로 생각했지만 위와 같이 조금은 번거롭게 느껴질 수 있는 방식으로 구현이 되어있습니다.

특히 count buffer를 따로 들고 다녀야 하는 부분이 번거롭게 느껴졌는데 크로스 플랫폼을 지원해야 하는 유니티의 입장에서 제가 모르는 사정이 있지 않을까요....?🧐


Face Detection Model

Mediapipe-IrisBlazeFace
45
  • Mediapipe-Iris : Face Detection → 눈 영역 crop → 눈, 홍채 좌표
    • 굉장한 성능(시선 추적 가능) / 전처리&후처리 복잡해서 모델이 무거움
  • BlazeFace : Face Detection + 눈,코,입,귀 좌표
    • 적당한 성능 / 가벼움

이번 프로젝트의 목적은 실시간 눈 탐지였고 대표적으로 위 두 모델이 존재합니다. 저 같은 경우 홍채 추적까지 할 필요는 없었기 때문에 조금 더 가벼운 BlazeFace 모델을 사용했습니다. 뿐만 아니라 Iris모델은 사실상 두 번의 detection을 해야 하므로 두 배 귀찮다는 사실!


Result

6

마지막으로 결과를 보여드리며 이번 포스팅을 마무리하겠습니다.
다음에도 재밌는 프로젝트로 인사드리겠습니다.

감사합니다.

Reference

profile
VIV LAB은 Visual AI와 VR,MR,AR기술을 기반으로 버추얼프로덕션과 디지털휴먼 제작, VFX/CGI 등 AI기술의 연구 개발을 수행하는 비브스튜디오스의 제작 기술 연구소 입니다.

0개의 댓글