회고

[웹 개발] 얼굴 인식 기반 실시간 출결 관리 프로젝트

진행 기간

1차) 2020.04.23~2020.06.24

2차 개선) 2020.08.01~2020.08.20

전체 코드(v2)

 

youjeongsue/Face-recognition-service-for-lecture

Face recognition을 활용한 수업보조 프로젝트입니다(React, Django). - youjeongsue/Face-recognition-service-for-lecture

github.com

프로젝트

기능

주요 기능은 다음과 같다.

 

  • ip 카메라를 활용한 수업 화면 송출
  • 실시간 얼굴 인식 및 시각화(수업 화면에 box 표시)
  • 출석 체크
  • 얼굴 box 클릭 시 해당 학생의 정보 제공

구조

프론트-백-AI 서버 간의 개략적인 구조

  1. 스마트폰 카메라로 찍고 있는 화면을 웹에 송출함과 동시에
  2. 화면의 프레임을 모델 서버로 보내서 얼굴을 인식하고
  3. 인식한 정보(얼굴 위치 및 인적사항)를 다시 웹에서 띄운다.

이 모든 과정을 최소한의 딜레이로 수행하기 위해서, 위 그림과 같은 구조를 설계하였다.

프론트와 백은 내가, 수업 화면 송출을 위한 카메라 앱 개발은 동혁님께서, face recognition 모델 및 서버 개발은 태호님께서 맡아주셨다!

데모

1차

1차 데모 영상

2차

2차 데모 영상

회고

실시간 딥러닝 서비스

저렇게 작은 얼굴까지 잘 인식한다 오예!

이번 프로젝트가 특별했던 이유가, 일반적으로 많이 구현하는 CRUD 서비스가 아니라 실시간으로 이뤄져야 하는 딥러닝 기반 서비스라는 점 때문이었다. 나도 CRUD 형태만 만들어봤었기 때문에 이렇게 실시간으로 동작하는 앱은 어떻게 만들어야 할지 고민이 많았다. 실시간으로 시각화가 이뤄지는 다른 서비스들도 찾아다녀 봤지만 내부적으로 어떻게 동작하는지는 알 수 없어서, 우리 나름대로의 구조가 짜졌다. 자세한 구조는 아래와 같다.

 

영상 송출 → (모델 서버에 프레임 전송 후 box 위치가 담긴 json 받음 → box 컴포넌트 랜더링 -> 랜더링 완료 후 프레임 재전송) → 종료까지 무한 반복

결과적으로 하고자 했던 기능들은 모두 성공적으로 구현했지만, 적절한 구조인지 더 발전시킬 요소는 없는지 피드백을 받을 수 있으면 좋겠다는 생각이 들었다(사실상 그런 기회는 거의 없다..ㅠㅠ). 애정이 있는 프로젝트라 그런지 더욱 완성도 있게 디벨롭시키고 싶은 욕심이 난다. 하게 된다면 Redis, Memcached 등을 공부해서 데이터베이스에 최대한 접근을 덜 하도록 개선시키고 싶다.

 

프로젝트를 계속 발전시키고 그걸 지켜보는 것은 정말 보람찬 일인 것 같다. 개발을 공부하면서 성장하는 나의 모습을 보며, 더 열심히 해야겠다는 동기부여가 된다.

 

 

프론트엔드

프론트엔드 개발을 본격적으로 해본 것은 이번 프로젝트가 처음이다.

백만 다뤄보다가 프론트를 다뤄본 소감은, 정말 섬세하고 꼼꼼하게 개발해야 한다는 것이다. 게다가 디자인도 맡아야 한다면 감각적이기까지 해야 한다(나의 디자인 감각이 꽝이라는 걸 깨달았다 ㅎㅎ). 프로젝트가 완성도 있어 보이려면 시각적인 부분을 신경 써야 한다고 포트폴리오 관련 세미나에서 들었었는데, 그 부분을 아주 실감했다.

 

그리고 프론트엔드를 단순히 디자인과 관련된 영역이라고 생각했던 지난날의 생각들이 잘못되었음을 알았다. 간접적으로라도 경험해본 적이 없어서 몰랐던 것이었다. 프론트는 사용자들의 행동 패턴을 바탕으로 홈페이지의 모든 것을 설계하고 구현하는 엄청난 작업이었다. 게다가 프론트엔드의 생태계는 매우 빨리 변하기 때문에 항상 공부하고 개선안을 연구해야 한다고 들었다. 프론트 공부하시는 분들이 대단하다고 느껴졌다.

 

프론트 개발은 의외로 매우 재미있었다! 화면을 구성하는 여러 가지의 컴포넌트를 설계하여 원하는 동작을 할 수 있도록 만들고, 디자인을 첨가하여 보기 좋게 만들어가다 보면 그만큼 뿌듯할 수가 없었다. 코드를 바꾸면 바로바로 화면이 바뀌는 게 재미있던 것 같다.

 

이로써 웹을 구성하는 프론트와 백을 모두 경험해보았다. 이제부터는 더욱 데이터 엔지니어의 관점에서 공부를 진행할 예정이다.

 

 

일정관리

프로젝트는

주제 선정부터 프로젝트 구조 설계, 백엔드까지 3주 + 리액트 튜토리얼 3주 + 프로젝트에 리액트 적용 2주

로 진행되었다. 처음인 점을 감안해도 두 달이나 진행할 내용이 아니었다. 특히 튜토리얼 3주... 변명을 해보자면 해당 학기에 프로젝트 6개를 동시에 진행하는 상황이었다 ㅠㅠ 이번 학기야 말로 일정관리의 중요성을 뼈저리게 느낀 학기였다. 동시에 많은 프로젝트를 진행하는 것만큼 일정관리를 더욱 빡빡하게 했어야 했다는 아쉬움이 남는다.

 

 

트러블슈팅

1. ip 카메라 개발 이슈

초기에 ip 카메라 어플도 자체 제작해서 사용해보자고 얘기를 했었고, 다른 개발자분께서 맡아서 진행을 해주셨었다.

하지만 개발 난이도가 너무 높고, 대체할 수 있는 어플이 있었으며 남은 시간이 얼마 없는 문제로

기존에 개발되어 있는 카메라 어플을 사용하기로 하였다. (중간에 나도 도와서 좀 건드려봤는데 네트워크 지식이 아직 없어서인지 진짜 어려웠다....)

 

그 어플을 사용해서 ip 연결을 하려고 했는데, 다들 관련 경험이 없어서 애를 먹고 있는 상황이었다.

그때 내가 공유기 포트포워딩으로 해결할 수 있을 것 같다고 제안했고,

네트워크 관련 지식이 있는 다른 팀원이 포트포워딩을 해줘서 연결에 성공했다!

 

이렇게 해서 프로젝트의 정말 중요한 기능 중 하나인, 수업 화면 실시간 송출을 구현했다. 팀원들의 지식을 조합해 문제를 해결한 의미 있는 경험이었다.

 

 

2. [React] Reducer 패턴을 적용한 리팩토링

1차 프로젝트를 진행할 때, React 내부 action 관리를 난잡하게 해서(api가 필요한 컴포넌트마다 다 흩어져 있었다..) 2차에서는 Reducer 패턴을 적용시켜 리팩토링을 해보려고 했었다.

 

그러다 Invalid hook calls. 에러를 만났다. 최대한 원래 코드에서 조금씩 변형시키며 원인을 찾아보려고 노력했는데, 도무지 찾을 수 없었다. 그렇게 며칠 동안 삽질을 하다가 더 이상 여유시간이 없어 1차에서 사용했던 패턴을 사용하기로 결정하였다. 결과적으로 기능은 잘 작동했지만, 야심 차게 계획했던 리팩토링 시도가 무마돼서 아쉬운 마음이다.

 

이제는 단순히 기능을 구현하는 것이 목표인 단계를 넘어서, 사용하는 라이브러리를 제대로 이해하고 써야 하는 단계인 것 같다. 이번 에러만 봐도 hook에 관련된 이슈인데, hook이 무엇인지도 모르니 해결할 방법이 없는 것이었다.

 

라이브러리나 프레임워크는 도구이다. 어디에 사용하는 도구인지, 도구의 특성이나 강점은 무엇인지 파악하고 사용해야 제대로 사용할 수 있다. 모르고 사용하면 이렇게 될 수 있다는 것을 경험했다. 리액트 그리고 장고에 대해서도 더 자세히 알아보고 싶다. 공부하게 되면 다시 리팩토링에 도전할 생각이다.

 

 

3. [React] 무한 재랜더링 오류

제목과 같이 특정 컴포넌트가 무한 재랜더링 되는 오류이다. 그 컴포넌트가 DB에 접근해야 하기 때문에, 무한으로 요청을 보내는 심각한 문제였다. 이 문제 또한 리액트의 hook, 특히 useEffect를 잘 이해하지 못해 생긴 문제이다.

 

해당 컴포넌트에 대해 설명해보자면

  1. 버튼을 클릭하면 업데이트되는 landmarks 값을 받아와서
  2. 모델 서버에 해당 landmarks가 누구인지 요청해 id를 받아오고
  3. 그 id에 해당하는 학생이 누구인지 DB에서 받아온다.

재랜더링을 막기 위해 여러 방법을 연구하다가, 결국은 useEffect로 해결할 수 있다는 것을 알아냈다. 구글링으로 찾아봤던 useEffect 예제들과는 다르게 적용시켜야 해서 알아내는데 오래 걸렸던 것 같다.

 

useEffect(function(), [var])과 같은 형태로 사용해야 하는데,

두 번째 인자는 변화를 감지할 대상 변수, 첫 번째 인자는 변수가 변했을 때 수행할 함수라고 이해한 상태이다.

아닐 수도 있다..

 

4. [React] 다른 컴포넌트의 state 가져오기

기능을 구현하던 중, 다른 컴포넌트를 가져와야 하는 상황이 생겼다. 이것도 custom hook이었다!!

그리고 이렇게 활용하는 방식을 'state 끌어올리기'라고 하더라. 여기에 대해서는 나중에 정리해야지..

 

 

수상

영광스럽게도 이 프로젝트로 두 건의 성과를 냈다.

 

경희대학교 캡스톤디자인 경진대회 최우수상
경희대학교 캠퍼스타운 1차 통과

 

캡스톤디자인 경진대회는 이번 학기 동안 경희대 전체에서 

수상으로 상금도 얻어서 그동안 어려웠던 일들을 다 까먹은 것 같다🤣

 

캠퍼스타운은 스타트업을 지원해주는 프로그램이다.

경희대학교뿐만 아니라 실제 스타트업에서도 많이들 나온다고 한다.

 

이번 1차는 4:1 정도의 경쟁률이었다고 하는데 붙어서 정말 놀라고 좋았다!!

그런데 상황상 스타트업(사업계획서 쓰고 이런 것들..)에 집중하기 어려워서 이후의 과정은 참여하지 않기로 했다 ㅠㅠ

 

어쨌든 정말 좋은 경험이 됐다.

이거 끝났으니 또 다른 일을 벌여봐야겠다 ㅎㅎ