본문 바로가기

Theory/DeepLearning

Python에서 OpenCV를 이용해서 초간편하게 사람 얼굴, 몸을 인식하기

요즘 학습된 모델을 바로 적용하는 것이 유행인것 같네요. 어렵고 장비빨(^^)이 필요한 학습은 우수한 분들께 맡기고, 저처럼 실력이 미천한 아이들은 그걸 따라 사용하는 것 만으로도 즐거운 일이죠~^^. 아무튼 그런 시류에 맞춰 저도 요즘 구글이 배포한 학습이 완료된 모델을 단순히 제 PC에 설치만(^^)해서 테스트해보았는데. 엄청 좋은 결과가 나오더라구요. 그 과정을 이제 몇 번 나눠서 쭈욱 블로그에 올릴건데요. 그 처음으로, 딥러닝같은 아이가 아니라, 그냥 OpenCV만 사용한 과정을 먼저 쭈욱 이야기하려고 합니다. 

결론은 오늘은 제가 OpenCV라는 신기한 아이를 처음 접하고, 단 몇일만에 Python을 이용해서 예제를 따라한 내용을 제가 블로그질(^^)을 하는 원래의 습관처럼 적겠다는 거죠. ^^ 

import numpy as np
import cv2
from matplotlib import pyplot as plt
%matplotlib inline

일단 시작은 이렇게 합니다.^^. 아 저는 Python은 3.6이고, anaconda 5.1 버전인데... 최신 OpenCV가 설치가 되지 않았습니다. 그래서, 저는 conda install -c conda-forge opencv=3.2로 설치를 했습니다. 그리고, haarcascades 파일들의 경로를 입력해야하는데, 그걸 제가 mac에서 찾지를 못해서.ㅠㅠ. 그 파일들만 따로 OpenCV Github사이트에서 받았습니다.

저 사이트죠^^

그걸 저렇게 잘 다운로드 해 줬죠. 저 파일들만 봐도, 안경쓴 눈, 그냥 눈, 얼굴, 몸, 상반신, 하반신, 웃는 입 등을 알 수 있도록 되어 있죠.

face_cascade = cv2.CascadeClassifier(
    './data/haarcascades/haarcascade_frontalface_default.xml')

사용할 아이는 위와 같이 합니다. 테스트용 사진.ㅠㅠ. 뭐 저는 저희 아가 미바뤼죠^^

image = cv2.imread('./img_MiBaRui3.jpg')
grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

plt.figure(figsize=(12,8))
plt.imshow(grayImage, cmap='gray')
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.show()

이렇게 읽어봅니다.

ㅎㅎ 우리딸... 많이 컸어요^^ 53개월 아기의 위엄을 보여주고 있네요^^ 그리고 위에서 지정한 얼굴 인식을 시도해보죠.

faces = face_cascade.detectMultiScale(grayImage, 1.03, 5)

print(faces.shape)
print("Number of faces detected: " + str(faces.shape[0]))

짠~

넵.. 두 개의 얼굴을 잡네요. 와우~

faces

그럼...

저렇게 잡은 얼굴의 박스 좌표를 알려줍니다.

for (x,y,w,h) in faces:
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,255,0),2)

cv2.rectangle(image, ((0,image.shape[0] -25)), 
              (270, image.shape[0]), (255,255,255), -1);
cv2.putText(image, "PinkWink test", (0,image.shape[0] -10), 
            cv2.FONT_HERSHEY_TRIPLEX, 0.5,  (0,0,0), 1);

plt.figure(figsize=(12,12))
plt.imshow(image, cmap='gray')
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.show()

그걸 이용해서 박스를 이미지에 덮는거죠^^

아하~ 어떤가요... 대단하죠. 영상인식이 뭔지 모르는 일자 무식도 여기까지 해볼 수 있습니다.^^

body_cascade = cv2.CascadeClassifier('./data/haarcascades/haarcascade_fullbody.xml')
body = body_cascade.detectMultiScale(grayImage, 1.01, 10)

for (x,y,w,h) in body:
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3)

plt.figure(figsize=(12,12))
plt.imshow(image, cmap='gray')
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.show()

이번에는 몸 전체를 찾으라고 해보죠~^^ 그러면 방금 얼굴을 찾은 사진에 몸도 추가로 표시하게 됩니다.

짠~~~^^ 이번에는 반복문을 이중으로 사용해서 몸은 다찾고, 찾은 몸안에 있는 얼굴만 찾으라고 하는 거죠...

image = cv2.imread('./img_MiBaRui3.jpg')
grayImage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

body_cascade = cv2.CascadeClassifier('./data/haarcascades/haarcascade_fullbody.xml')
body = body_cascade.detectMultiScale(grayImage, 1.01, 10)

for (x,y,w,h) in body:
    cv2.rectangle(image,(x,y),(x+w,y+h),(0,0,255),3)
    
    body_image_gray = grayImage[y:y+h, x:x+w]
    body_image_color = image[y:y+h, x:x+w]
    
    faces_in_body = face_cascade.detectMultiScale(body_image_gray)

    for (xf,yf,wf,hf) in faces_in_body:
        cv2.rectangle(body_image_color,(xf,yf),(xf+wf,yf+hf),(0,255,0),2)
        
        
plt.figure(figsize=(12,12))
plt.imshow(image)
plt.xticks([]), plt.yticks([])  # to hide tick values on X and Y axis
plt.show()

너무나 쉽게^^ 이렇게 말이죠....

어떤가요.... 괜찮죠... ㅎㅎ.. 물론 딥러닝을 이용한 멋진 결과보다는 좀 떨어질 수 있지만, OpenCV라는 아이를 이용해서 간결하고 쉽게 접근해 보았습니다. 다음에는 더 재미있는 걸로 접근해 볼께요^^

반응형