<p style="text-align: center;"><em>야 이 드라마에 나오는 거 진짜야?</em></p> <p style="text-align: center;">드라마 스타트업 방영 이후 유독 이런 질문을 하는 지인들이 많아졌습니다.</p> <p style="text-align: center;">도대체 뭐가 나오길래 그러는지 궁금해 드라마를 현재 2회째 정주행하고 있는데요.</p> <img class="size-full wp-image-19647 aligncenter" src="https://www.wishket.com/media/newscenter/624/1.jpg" alt="" width="350" height="233" /> <p style="text-align: center;">음.. 다른 건 잘 모르겠고 “저 얼굴이 개발자”라는 게 가장 비현실적인 것 같습니다. 아니 무슨 개발자가 이렇게 생겼..</p> <p style="text-align: center;">아차차.. 물론 오늘 주제가 “남주혁이 어떻게 개발자인가”인건 아니고요, “야 이 드라마에 나오는 거 진짜야?”에 대한 첫 번째 대답으로 “남도산의 프로토타입 따라 하기”를 준비해봤습니다.</p> <p style="text-align: center;">최연소 수학올림피아드 출신 개발자 남도산 씨는 직접 개발한 사물 인식 카메라와 함께 등장합니다.</p> <p style="text-align: center;">아버지의 지원을 받은 지 어언 3년째, 오늘은 “돈만 축내는 장손놈!”을 외치며 난입한 아버지를 꼭 설득시켜야 할텐데요.</p> <img class="size-full wp-image-19648 aligncenter" src="https://www.wishket.com/media/newscenter/624/2.gif" alt="" width="960" height="540" /><p style="text-align: center;">아버지의 얼굴을 변기로 인식하는 장면</p><img class="size-full wp-image-19649 aligncenter" src="https://www.wishket.com/media/newscenter/624/3.gif" alt="" width="960" height="540" /> <p style="text-align: center;">안타깝게도 사물인식 카메라가 사소한 오류를 내고 맙니다. 바로 아버지의 얼굴을 ‘변기’로 인식해버린 건데요. 분노에 찬 아버지는 ‘패륜 기계’의 제작자 남도산 씨를 몽둥이로 응징합니다.</p> <br/><br/> <img class="size-full wp-image-19650 aligncenter" src="https://www.wishket.com/media/newscenter/624/4.png" alt="" width="350" height="198" /> <p style="text-align: center;">흠.. 흐음...</p> <p style="text-align: center;">이 기계.. 문득 만들고 싶다는 욕심이 생겼습니다.</p> <p style="text-align: center;">그.래.서. 오늘의 주제는 얼굴 인식 AI 만들기입니다. 아 물론 이 AI는 적당히 멍청한 탓에 김원해 배우님의 얼굴만 변기로 인식할 겁니다.</p> <br/><br/> <img class="size-full wp-image-19651 aligncenter" src="https://www.wishket.com/media/newscenter/624/5.png" alt="" width="600" height="467" /><p style="text-align: center;">패륜이 등장</p> <p style="text-align: center;">설명의 편의를 위해 앞으로 이 AI의 이름을 "패륜이"라 부르겠습니다. 오늘 패륜이가 김원해 배우님을 알아볼 방법은 다음과 같은데요.</p> <br/><br/> <img class="size-full wp-image-19652 aligncenter" src="https://www.wishket.com/media/newscenter/624/6.png" alt="" width="600" height="179" /><p style="text-align: center;">패륜 AI가 변기 및 얼굴을 인식하는 프로세스</p> <p style="text-align: center;">1. 우선 (영상에서 변환된) 사진을 받으면 2. 패륜이는 사진 속에서 사람의 얼굴 찾아내고 3. 그 얼굴들을 미리 준비한 김원해 배우님 얼굴과 비교해서 4. 유사도가 높은 얼굴에 변기 표시를 할 겁니다.</p> <p style="text-align: center;"> 라이브러리는 numpy, dlib, opencv를 활용했으며, 환경은 mac OS와 windows에서 로컬로 진행했습니다. 접근법은 <a href="https://github.com/kairess/simple_face_recognition%EB%A5%BC">https://github.com/kairess/simple_face_recognition</a>를 참고했습니다.</p> <p style="text-align: center;">*본문에선 김원해 배우님을 "도산아빠"로 칭하겠습니다.</p> <br/><br/><br/> <h3>01 Video Capture / Writer</h3>목표 : 비디오를 사진으로 나누기 & 사진을 비디오로 만들기 사용 라이브러리 : openCV 기본적으로 패륜이는 사진에서 얼굴을 찾아내는 친구입니다. 하지만 우리는 영상에서 이 기능을 수행해야 하죠. 즉, 영상에서 변기를 찾기 위해선 1. 영상을 사진으로 나눠 패륜이에게 전달하고, 2. 패륜이가 편집한 사진을 다시 영상으로 만들어줄 영상편집자가 필요합니다. 이번 장에서 소개할 영상편집자는 [openCV]의 [VideoCapture]와 [VideoWriter]입니다. <img class="size-full wp-image-19653 aligncenter" src="https://www.wishket.com/media/newscenter/624/7.png" alt="" width="600" height="179" /><p style="text-align: center;">두 번째 장에서 진행할 "영상/사진 변환"</p> <br/> 역할을 정리하자면, 1. <strong>[Video Capture]</strong>는 영상을 사진으로 변경하는 기능을 수행하며 2. 패륜이가 얼굴을 찾아 사진을 편집하면 3. <strong>[Video Writer]</strong>는 편집된 사진을 다시 영상으로 만들어줍니다. <br/> 우선 패륜이를 빼고, 영상 편집자가 제대로된 역할을 하는지 간단한 텍스트를 삽입하는 시험을 해봤는데요. 아래의 사진과 같이 영상편집이 잘 되는 걸 확인할 수 있었습니다. <img class="size-full wp-image-19654 aligncenter" src="https://www.wishket.com/media/newscenter/624/8.gif" alt="" width="960" height="540" /><p style="text-align: center;">video_tester.py의 결과물</p> <br/> 이제 영상/사진 변환 과정을 완료했으니 본격적으로 패륜이에게 일을 맡길 수 있겠네요. *비디오 편집 테스트 코드 <a href="https://t1.daumcdn.net/brunch/service/user/5uIw/file/OtWwvu-YNcJf5Qo_X3nYRC6j7Dk.py">video_tester.py</a> <br/><br/><br/> <h3>02-1 Face Detection</h3>목표 : 사진 속에서 사람의 얼굴 찾아내기 사용 라이브러리 : dlib.get_frontal_face_detector, 사진을 받은 패륜이의 첫 번째 미션은 사진 속 ‘얼굴’을 찾는 겁니다. 하지만 아쉽게도 영상 속에는 얼굴 말고도 휴지부터 몽둥이, 컵라면, 테이블까지 다양한 물건들이 존재하죠. <img class="size-full wp-image-19655 aligncenter" src="https://www.wishket.com/media/newscenter/624/9.png" alt="" width="600" height="254" /><p style="text-align: center;">두 번째 장에서 진행할 "얼굴 찾기"</p> <br/><br/> 따라서 패륜이가 가장 먼저 해야 할 일은 사진 속 다양한 물체로부터 ‘얼굴’을 구분해내는 것인데요. 이번 장에서 패륜이는 <strong>[dlib]의 [get_frontal_face_detector]</strong>라는 모델에게 도움을 받을겁니다. 이 모델은 HOG라는 방식을 사용해 얼굴을 인식하는데요. <img class="size-full wp-image-19656 aligncenter" src="https://www.wishket.com/media/newscenter/624/10.png" alt="" width="426" height="277" /><p style="text-align: center;">출처: Hackevolve.com</p> <br/> HOG는 각 픽셀의 밝기 변화를 통해 얼굴의 윤곽을 찾아냅니다. 간단히 말하자면 오른쪽 사진처럼 단순화된 윤곽을 보며 이 물체가 얼굴인지 아닌지 확인하는 방법인 거죠. (*분량 관계상 HOG에 대한 기술적 설명은 잘 <a href="https://medium.com/@jongdae.lim/%EA%B8%B0%EA%B3%84-%ED%95%99%EC%8A%B5-machine-learning-%EC%9D%80-%EC%A6%90%EA%B2%81%EB%8B%A4-part-4-63ed781eee3c">정리된 블로그의 링크</a>를 첨부하겠습니다) <br/><br/> 그런데.. 이렇게 찾아낸 얼굴들을 그대로 쓰자니 정보가 너무 많아 보입니다. <img class="size-full wp-image-19657 aligncenter" src="https://www.wishket.com/media/newscenter/624/11.png" alt="" width="600" height="260" /><p style="text-align: center;">9만 개의 숫자가 3층으로 쌓여 만든 도산아빠의 사진</p> <br/> 비교 기준으로 사용될 도산아빠의 사진만 해도 약 9만 개의 픽셀, 27만 개의 숫자로 구성될 정도죠. 아직 어린(?) 패륜이에게 27만 개는 너무 많은 숫자입니다. 심지어 굴곡이 없는 이마나 볼 쪽의 픽셀들은 얼굴을 구분에 별로 도움도 안 되는데 말이죠. 이 문제를 해결하기 위해 다음 장에서 할 일은 얼굴의 진짜 '특징'들을 뽑아내는 겁니다. <br/><br/><br/> <h3>02-2 Landmark predict</h3>목표 : 얼굴의 특징 뽑아내기 사용 라이브러리 : dlib.shape_perdictor 여러분은 “옆 사람의 외모를 설명해주세요”라는 질문을 들으면 어떻게 하실 건가요? 아마 대부분 “눈은 동그랗고, 코는 오뚝하며 턱은 짧아"와 같은 대답을 하실 겁니다. <span style="text-decoration: underline;">“얼굴의 상단 30%는 검고, 이하 70%는 하얀데, 중간에 붉은 지점이 있고..”</span> 라고 설명할 분은.. 아마 없겠죠. 이는 눈, 코, 턱 등이 사람의 얼굴을 구분하는 중요한 특징이기 때문일 텐데요. AI도 사람과 비슷한 방법을 사용합니다. 보다 쉽고 정확한 설명(혹은 인식)을 위해 사람의 얼굴을 약 68개의 주요 지점으로 분류하죠. 이 "주요 지점"들은 랜드마크라고 불리는데요. 이번 장에서 패륜이는 <strong>[dlib]의 [shape_predictor]</strong>를 활용하여 사진 속 등장인물들의 얼굴 위에 이 랜드마크들을 표시합니다. <img class="size-full wp-image-19658 aligncenter" src="https://www.wishket.com/media/newscenter/624/12.png" alt="" width="600" height="260" /><p style="text-align: center;">landmark.py를 통해 도산아빠 얼굴에 랜드마크를 표시</p> <br/> 이 과정을 거치면 패륜이는 도산아빠의 눈, 눈썹, 코, 입술, 턱선을 알아볼 수 있게 됩니다. 휴.. 계산할게 9만 개에서 68개로 감소했으니 우리의 패륜이, 한숨 트였네요. *랜드마크 표시 테스트 코드 <a href="https://t1.daumcdn.net/brunch/service/user/5uIw/file/xinH9sRyW9c_xMNhb2sCVLuICuc.py">landmark_tester.py</a> <br/><br/><br/> <h3>03 face_recognition, Calculating distance</h3>김원해 씨와 사진 내 등장인물의 특징 비교하기 사용 라이브러리 : dlib.face_recognition, numpy linalg 앞선 과정에서 패륜이는 사진 속 얼굴을 찾아 눈, 눈썹, 코, 입, 턱의 위치를 알아냈는데요. 이번엔 이 얼굴들을 서로 비교하여 "변기인지 아닌지"를 구분하는 작업을 할 겁니다. <img class="size-full wp-image-19659 aligncenter" src="https://www.wishket.com/media/newscenter/624/13.png" alt="" width="600" height="254" /><p style="text-align: center;">세 번째 장에서 진행할 얼굴 비교 및 변기 표시</p> <br/> 사람이 아닌 패륜이는 얼굴 사진이 아닌, "숫자가 된 무언가로"로 얼굴 간 유사도를 계산해야 하는데요. 이를 위해 패륜이는 <strong>[dlib]의 [Face_recognition_model]</strong>을 사용합니다. 이 모델은 전체 이미지와 랜드마크 정보를 주면 "얼굴 점수"를 알려주는 역할을 하죠. <img class="size-full wp-image-19660 aligncenter" src="https://www.wishket.com/media/newscenter/624/14.png" alt="" width="600" height="222" /><p style="text-align: center;">Face recognition model의 구조</p> <br/> 패륜이는 1) 영상 편집자가 일을 하기 전에 미리 도산아빠의 사진을 모델에게 줘서 점수화해두고, 2) 영상 편집자가 사진을 주면 사진 속 배우들의 얼굴을 모델에게 가져다줍니다. <img class="size-full wp-image-19661 aligncenter" src="https://www.wishket.com/media/newscenter/624/15.png" alt="" width="600" height="175" /> <br/><br/><br/> 이제 이 과정을 통해 받은 "얼굴 점수"를 서로 비교할 건데요. 비교는 "얼굴 점수" 사이의 거리를 계산하여 진행합니다. 화면 속 "얼굴 점수"를 좌표에 배치하여 다음과 같은 결과를 얻었다고 가정해봅시다. <img class="size-full wp-image-19662 aligncenter" src="https://www.wishket.com/media/newscenter/624/16.png" alt="" width="600" height="445" /><p style="text-align: center;">실제로는 훨씬 복잡한 차원의 계산으로 구성됨</p> <br/><br/><br/> 영상 속 도산아빠는 미리 저장해둔 자신의 얼굴과 0.39로 가깝지만 남도산씨는 기준 사진과 약 0.72로 멀리 <strong>배치되어있습니다.</strong> 여기서 패륜이는 미리 저장해뒀던 도산아빠를 기준으로 원을 그려 원 안의 얼굴들을 도산아빠로 인식하기로 합니다. <img class="size-full wp-image-19663 aligncenter" src="https://www.wishket.com/media/newscenter/624/17.png" alt="" width="600" height="453" /><p style="text-align: center;">기준거리 설정에 따라 변기 인식도가 달라짐</p> <br/> 문제는.. 철산이와 도산아빠가 제법 닮았다는 건데요. 이러면 원의 반지름이 커질 경우 패륜이는 철산이도 도산아빠로 인식하게 됩니다. 영상의 프레임마다 각 등장인물의 "얼굴 점수"는 다르니, 영상 속 도산아빠는 모두 도산아빠로 인식하면서 철산이는 도산아빠로 인식하지 않는 반지름을 찾아야 하는데요. 저는 몇 차례 시도 끝에 반지름의 길이를 0.45로 설정했습니다. 이제 패륜이는 원 안의 얼굴을 toilet으로, 원 밖의 얼굴을 Face라고 표시할 인식할 수 있게 되었죠. 마침내 패륜이는 영상 속에서 도산아빠를 인식하고, 얼굴 위에 변기 표시를 할 수 있게 되었습니다. 이 과정을 다시 한번 요약하면 다음과 같습니다. <p style="text-align: center;"><img class="size-full wp-image-19664 aligncenter" src="https://www.wishket.com/media/newscenter/624/18.png" alt="" width="600" height="254" />라이브러리를 포함한 최종 프로세스</p> <br/><br/><br/> 드. 디. 어 찾아온 결과 시간, 제 패륜이는 김원해 배우님을 변기로 인식했을까요? <img class="size-full wp-image-19665 aligncenter" src="https://www.wishket.com/media/newscenter/624/19.gif" alt="" width="768" height="432" /> <img class="size-full wp-image-19666 aligncenter" src="https://www.wishket.com/media/newscenter/624/20.gif" alt="" width="768" height="432" /> <br/> 다행히, 김원해 배우님의 얼굴은 "Toilet"으로, 다른 배우분들의 얼굴은 “face”라고 인식되는 걸 확인할 수 있습니다. 드라마 속 모델과는 달리 아직 물체 인식이 아닌 얼굴 인식만 할 수 있다는 점과, dlib 모델의 특성상 측면 얼굴을 잘 인식하지 못한다는 점이 약간 아쉽긴 하네요. 휴... 오늘은 이렇게 드라마 스타트업의 패륜 AI를 만들어봤는데요. 사실 남도산의 프로토타입은 아버지의 얼굴만 제외하면 나머지 물건들인 "컵라면", "화장실 휴지"등은 정말 훌륭하게 인식합니다. 이 정도로 자질구레(?)한 오브젝트까지 다 트레이닝을 시키려면, 이거.. 시간이 걸려도 엄청 오래 걸렸을 텐데 3년이라는 시간 동안 데이터 라벨링과 모델 트레이닝을 시켜왔을 남도산씨에게 존경의 박수를 보냅니다. 앞으로 남도산씨와, 이 프로토타입의 발전이 기대되네요:) <br/> 아, 혹시 제가 만든 패륜이를 직접 만나고 싶다면 아래의 파일을 확인해보세요. (*저작권 문제로 영상은 포함하지 않았습니다) <a href="https://t1.daumcdn.net/brunch/service/user/5uIw/file/RD1tgnCuctGOw4kbxAMsAT5-Spg.py">video_tester.py</a>