cv2 마스크착용 판별 인공지능 만들기

be1le·2022년 3월 14일
12
post-thumbnail

오늘은 마스크 착용에대한 confidence, 그리고 얼굴위치를 인지하는 모델 두가지를 사용하여 동영상,혹은 사진속의 사람이 마스크를 쓰고 있는지 확인하는 실습을 해보려 한다. 주제 자체가 시국과 매우 밀접한 연관관계고, 일상생활에서 광범위하게 사용될 수 있는 실습이라 생각한다. 함께 시작해 보자!

패키지 부터 로드하기!


처음으로 cv2와 np가아닌 다른 친구들이 등장을 하였다. loda-model은 정말 익숙하게 느껴질 수도 있을거라 생각한다. 이미 완성된 모델을 h5로 불러올때 자주 사용되기 때문에!! 밑에줄을 보면 이게 정확히 무엇을 하는지는 몰라도 전처리를 해주는 건가?? 라는 합리적인 의심을 preprocess라는 이름에서 알 수 있다. 하지만 우리가 여러 실습을 할때 상당히 디테일을 도와주는 친구라고 생각을 하여 좀 자세하게 정리해 보았다!

왜 preprocess_input으로 img를 넣어야 할까?
Keras는 이미지 배치로 작동합니다! 따라서 첫 번째 차원은 가지고 있는 샘플(또는 이미지) 수에 사용됩니다.
단일 이미지를 로드하면 하나의 이미지 모양, (size1,size2,channels) 이런 모양이고,
이미지 배치를 생성하려면 추가 차원이 필요한데, (samples, size1,size2,channels)이러한 형식으로 바꿔 줍니다!
결과론 적으로 보았을때 preprocess_input기능은 모델에 필요한 형식으로 이미지를 적절하게 만들기 위한 것이다! 라고 생각해 주시면 될 것 같습니다!

모델로드 하기

이런 식으로 우리는 두가지 모델을 로드후 유기적으로 사용할 것이다. 우선 얼굴 영역을 판단하는 모델이 얼굴의 좌표를 반환하면 마스크를 판단하는 모델이 해당하는 얼굴영역에 마스크가 몇% 확률로 존재하는지에 대한 confidence(자신감)을 반환해 줄 것이다. 우리는 이러한 전체적인 흐름을 알았으니. 늘 해오던 대로 유연하게 진행할 수 있을것 같다!

실습에 사용할 video및 videoplayer준비하기.

cap이라는 변수에 실습에 사용할 video를 할당하고 밑에는 우리가 자주 보았던 videoplayer가 있다. videoplayer가 기억이 안날 수도 있으니 주석도 한번씩 읽어보면서 다시 상기시켜 보자!

for문을 돌며 얼굴을 찾아보자!

나는 실습을 진행할때 보통 모르는걸 주석으로 구석구석 달아둔뒤 해당하는 주석에 대한 설명을 스스로 구글링하여 찾거나 모델자체를 직접 찾아가서 작성자의 코멘트을 읽는 방법을 사용하는데 왜 2번인덱스가 얼굴일까에 대해서 너무나도 궁금하여서 직접 모델설명을 어렵사리 이해한 결과! 그건 모델설계자의 선택이자 자유라는 결론에 도달했다. 꼭2번인덱스가 얼굴이 아닐 수도있지만. 우리가 사용하는 모델에서는 dets.shape[2]에 해당하는 index가 얼굴의 개수 이기에 그에 맞게 코드를 작성하면 되는 것이다!

바로밑에 문단도 상당히 중요한데. confidence가 50%이하이면 그냥 해당하는 영억은 얼굴이 아니라고 생각하라고 모델에게 우리가 가이드라인을 주는 것이라고 생각하면 편하다!

왜..? 도대체 왜?

사각형의 꼭지점을 찾는 부분이다. 모델자체가 %수치로 반환을 하기에 원본이미지의 크기를 곱해주는 것까지의 이해는 어렵지 않았다. 하지만 도대체 왜? 3,4,5,6 저렇게 이쁘게 하나씩 늘어나게 되는 걸까 라는 생각을 하였다. 처음에는 내가 모르는 사각형의 꼭지점을 구하는 수식이 있는데 해당하는 수식에 따라서 3부터6까지 점진적으로 늘려야 하는 원리라도 있는것일까? 생각을 하였다. 하지만 이 또한 모델을 뜯어보면 우리 모두가 이해 할수있는 결과를 얻을 수 있다. 내가 주석에 달아 두었듯이

x1 = int(dets[0, 0, i, j] * w)

코드에서 3번째 인덱스(편의상j라고 하겠다.)j또한 펼쳐보면 즉우리가 j의 세계에 들어간다면!
j또한 [sum1, sum2, sum3, sum4]이런식의 array형태로 되어있다. 근데 왜 3,4,5,6 번째 인덱스를 가져오는 것일까 사실 이유는 이와 같다.

모델 설계자의 마음대로

우리는 왜? 라는 질문이 이미 완성된 모델을 사용할때는 독이 될 수 있다는걸 인지 하여야 한다. 글로쓰면 이렇게 2분도 안걸리는 이야기를 작성자는 궁금해 잠이 안와 3시간을 구글이란 바다에서 표류하였다. 이미 어째서 dets.shape[2] 이 코드가 얼굴의 개수를 담고있는 index인지 알기위해 1시간 반을 찾아 다니고 그이유가 모델 설계자의 마음이란걸 알고난 후로도 정신을 못차리고 3시간을 투자한 것이다. 결국 "모델 설계자가 개인적으로 정해둔 규칙"이라는 정답을 얻기위하여. 이 글을 읽는 많은 사람들은 누군가가 이미 완성된 모델의 구조에 대하여 너무 디테일한 궁금증을 안갖길 바란다. 가끔은 정말 중요한 개념이 함축된 궁금증일 수도 있지만, 대부분은 그렇게 영양가 높은 궁금증은 아닐거라는게 작성자의 생각이다. 모두함께 소중한시간을 더 중요한 개념을 알아가는것에 할애하는 습관을 갖도록 하자!

"늘 하던걸로 해줘"

나의 opencv 시리즈를 쭉 읽어오신 분들이라면로또되세요 이제 우리가 무엇을 해야할지 알고 있을거라 생각한다. 그렇다. 바로!


"늘 해오던 전처리, resizing,차원변형" 을 해주고 난뒤 이번 실습에서는 위에서 설명했던 함수
preprocess_input 으로 컴퓨터가 좋아하는 순서대로 배치를 바꾼 img를 input값에 대입해주고 나면 이제 우리는 우리가 원하는 결과를 얻을 수 있다. 사실 위의 img에서 3번째 구문

face_input = cv2.cvtColor(face_input, cv2.COLOR_BGR2RGB)
이 부분은 해당모델이 RGB로 학습 되어 있기 때문에 다시 우리에게 cv2에게 편한 BGR채널로 바꿔주는 것이다. 이 부분또한 모델의 특징중 하나일 뿐이니 너무 깊은 사색에 빠지지 않길 바란다!

출력하기

모델실습의 꽃이라고 생각한다. 내가 4시간반을 구글링하며 먼길을 돌아와도 해당하는 실습의 결과를 보면 모든 노고가 눈녹듯이 사라지는 기분이다. 이제 출력을 담당하는 코드를 작성하고 결과물을 확인해 보자!이렇게 간단하게만 적어주면!


이렇게 모두가 마스크를 안썻을때는 빨간 사각형을 실시간으로 그려주고,

이렇게 모두가 마스크를 쓴다면 녹색 사각형을 실시간으로 그려주게 된다.

cap이라는 변수에 할당되는 video만 바꿔준다면 다른 영상에도 얼마든지 적용해 볼수있는 것이다.
주석이 길어서 그렇지. 사실상 코드실행부는 30줄이 조금 넘는다. 이렇게 짧은 코드로 이처럼 훌륭한 실습을 할 수 있다니... 신기하면서도 뿌듯하다!!

글을 마치며

정말 시국에 이보다 적합한 ai실습이 있을까 싶다. 다들 건강히 코로나를 극복해서 평화롭던 일상으로 빨리 돌아오기를 바란다.

profile
그저 그런 개발자가 되지 않겠습니다.

0개의 댓글