이번 리뷰는 12월 22~23일에 진행한 세종대학교 해커톤을 참가하며 작성한 코드를 정리해보고자 합니다.
다양한 주제 중 저희 팀의 주제는 비대면 시험을 위한 AI 감독관이라는 주제였으며, 거기서 저가 맡은 역할은 응시자의 이상상황(컨닝, 시험 응시 중 사라짐 등)을 감지하는 모델을 설계하는 것이었습니다.
이상상황 정의
이상상황을 정의하는 것에 대해서 많은 고민이 있었지만, 주어진 시간안에 정상적인 구동을 보여주기 위해서 가장 일반적인 상황만을 이상상황으로 정의하였습니다. 각 경우들은 다음과 같습니다.
- 응시자의 손과 얼굴 중 하나라도 검출이 되지 않는 경우
- 응시자의 고개가 일정 각도 벗어나는 경우
1번의 경우에는 Face detector와 hands detector를 사용하면 충분히 가능한 상황이었기에, 큰 어려움은 없었지만 2번의 경우를 해결하기 위해서 어느 모델을 사용할지 많은 고민을 하였습니다.
다양한 모델을 찾던 중 head pose estimation이라는 방법론을 찾게 되었고 해당 방법론과 관련된 모델을 가져와 사용하게 되었습니다.
Pipeline
전체적인 pipeline은 다음과 같습니다.
웹캠을 통해서 입력 데이터가 들어오면, 먼저 얼굴과 손에 대한 검출을 진행합니다. 얼굴과 손을 검출하는 모델은 다양한 API 및 코드들이 존재하는데, 해당 프로젝트에서 저는 MediaPipe를 사용하였습니다.(자세한 설명은 아래에서 하겠습니다.)
그 후 예측된 face mesh를 통해 얼굴 부분만을 crop하여 이를 head pose estimator 모델에 입력으로 제공합니다. 해당 모델을 통과하면 시험 응시자가 어디를 바라보고 있는지에 대한 yaw, pitch, roll 값이 나오게 됩니다.
이러한 head pose 값과 hands detection의 추정여부를 고려하여 이상상황을 판단하는 방식으로 구성되어있습니다.
FaceMesh & Hands
위에서 설명했듯이 저는 다양한 API 중 MediaPipe라는 API를 사용하였습니다.
MediaPipe는 구글에서 제공하는 API로 Face와 hands 뿐만 아니라 hair segmentation, pose estimation 등등 정말 다양한 task를 수행하는 모델들을 제공합니다.
혹여나 관심있으신 분들을 위해 링크도 같이 올립니다. https://google.github.io/mediapipe/
MediaPipe 코드 내용 추가할 예정.
Head Pose Estimator
Head Pose Estimator에서 사용한 방법론은 CVPR2018 논문인 Fine-Grained Head Pose Estimation Without Keypoints을 사용하였습니다.
기존의 전통적인 head pose는 input face에서 keypoint를 추출한다음, 2D<->3D 대응관계를 풀어나감으로써 head pose를 계산합니다. 하지만 이 방식들은 landmark 검출 결과에 따라 성능이 크게 좌지우지될 수 있다고 합니다.
이를 해결하기 위해 해당 방법론은 300W-LP 데이터 셋을 이용해 multi loss CNN을 학습시킴으로써 내부 euler angle를 얼굴 영상으로부터 바로 추정하였다고 합니다.
위에 그림은 해당 모델의 정성적인 결과를 나타냅니다. 총 3개의 선들이 존재하는데, 파란색은 yaw, 초록색은 pitch, 붉은색은 roll을 의미합니다.
해당 값들을 통해 고개를 얼마나 숙였고, 돌렸으며, 꺾었는지를 계산할 수 있으며, 해당 값들이 일정수치 넘어가면 이상상황을 감지한다고 지정하였습니다.
다음은 해당 pretrained 모델에 저희의 데이터로 적용해본 결과입니다.
살짝 살짝 부정확한 모습도 보이긴하지만, 전반적으로 방향이 거의 다 일치하는 만족스러운 결과를 보여주었습니다.
Head Pose의 논문과 사용했던 코드의 링크는 아래와 같습니다.
논문 – https://arxiv.org/pdf/1710.00925.pdf
코드 – https://github.com/natanielruiz/deep-head-pose
후기
실시간 데모 영상 추가 예정
Head Pose Estimator 논문 내용 요약 및 설명 추가 예정
연구실에서 공부하고 여러가지 코드를 돌려보며 공부를 많이 하긴 했지만, 해커톤을 준비하면서, 그리고 참여하면서 생각보다 많은 부족함 느꼈습니다.
저가 사용한 모델들은 서칭하면 코드들이 쏟아져 나오는 task임에도 불구하고, 알맞은 코드를 선택하고, 이를 내 프로젝트에 적용하기 위해서 환경을 구축하는 것이 여간 쉬운 일이 아니었습니다.
또한 서버라는 좋은 환경에서 작업을 하다가, CPU도 느리고 GPU도 없는 노트북에서 아나콘다를 이용한 가상환경으로 작업을 하고 있으니 정말 많은 답답함?을 느꼈습니다.
하지만 이번 해커톤을 통해 의미있는 경험도 하였습니다. 밥먹을 시간 빼고 하루종일 코딩을 함으로써 체력적인 부분과 멘탈적인 부분에서 많이 힘들긴 했지만 이런 경험을 통해 오히려 강인해짐을 느꼈습니다.
또한 여러 코드들을 찾아보고 적용해보려고 시도하면서 그동안에 자신이 없던 개발과 관련된 경험들을 축적하게 되었습니다.
아직 수상결과는 어떻게 됐는지 모르지만, 수상 결과 여부와 상관없이 해커톤 참석을 통해 다양한 경험을 해볼 수 있어 만족스럽고 많은 것을 배워갈 수 있었습니다:)