라즈베리파이에서 Picamera 이용 실시간 얼굴인식 및 눈 찾기

메카 2017-06-12 (월) 14:15 1년전 9851  

    이번 강좌는 라즈베리파이, 파이카메라 그리고 Python를 이용하여 사람 얼굴과  눈 검출을 소개한다.

사용된 특징은 Haar featrure기반이며, cascade classifier를 이용하여 얼굴을 검출한다. Haar feature는 앞 강좌의 자동차 검출을 참조하기 바랍니다. 

 

1) 정지 영상의 사람 얼굴 검출

    사람 얼굴을 검출하기위해 Haar-like 특징을 사용하며, cascade 기반의 학습 데이터는 "haarcascade_frontalface_default.xml" 파일을 사용하였다. 소그 코드는 아래와 같다. 

 

import numpy as np
import cv2

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

while True:
    img = cv2.imread('image.jpg')
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    faces = faceCascade.detectMultiScale(gray, 1.3,5)
    for(x,y,w,h) in faces:
        cv2.rectangle(img, (x,y),(x+w,y+h),(0,255,0),2)
        
    cv2.imshow('image', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cv2.destroyAllWindows()

 

 

CascadeClassifier()함수를 이용하여 학습 XML 파일 'haarcascade_frontalface_default.xml'을 로딩한다. 입력 영상은 imread() 함수를 이용하여 불러온다. cvtColor()함수는 입력 영상의 색상을 Gray영상으로 바꾸는 일을 해준다. detectMultiScale()함수는 입력 영상으로부터 얼굴을 검출하는 함수이다. 속성은 다음과같다. 

 gray : 입력 영상

1.3 : scaleFactor(이미지 스케일)

5 : minNeighbors(얼굴검출 후보들의 개수)

rectangle()함수는 사각형을 그리는 함수로써, 얼굴이 존재하는 부분에 사각형을 그린다. 여기서, x와 y는 사각형의 시작위치이며, w와 h는 가로와 세로의 크기이다. (0,255,0)는 사각형의 색상이며, 2는 선의 굵기이다. 결과 영상은 아래와 같다. (사진은 인터넷에서 가져온 것임)

 ff103f49d77b8f518f6fb7a62f33586a_1497246 

 ff103f49d77b8f518f6fb7a62f33586a_1497246 

 ff103f49d77b8f518f6fb7a62f33586a_1497246 

 ff103f49d77b8f518f6fb7a62f33586a_1497246 

 

왼쪽 영상은 원본 영상이며, 오른쪽 영상은 얼굴을 찾은 결과 영상이다. 윗줄은 영상에 한사람이 있는 경우이며, 아랫줄 영상은 사람이 여러명일 경우이다. 

 

 

 2) 실시간 얼굴 및 눈 검출

    얼굴을 검출하기위한 학습 데이터는 위와 같이 "haarcascade_frontalface_default.xml" 파일을 사용하며, 눈을 검출하기위해 "haarcascade_eye.xml"파일을 사용한다. 코드를 살펴보면 아래와 같다.

from picamera.array import PiRGBArray

from picamera import PiCamera

 

import cv2

import time

 

# Import the face detection haar file

face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')

eye_cascade = cv2.CascadeClassifier('haarcascade_eye.xml')

 

# Used in Screen resolution and positioning later

widths = 440

heights = 320

 

# initialise servo values

servox = 0

servoy = 0

 

# initialize the camera and grab a reference to the raw camera capture

camera = PiCamera()

camera.resolution = (widths, heights)

camera.framerate = 32

camera.hflip = True

rawCapture = PiRGBArray(camera, size=(widths, heights))

 

# allow the camera to warmup

time.sleep(0.1)

 

# Init flags with their default values

showVideo = True

  

cv2.namedWindow('VideoOutput')

 

# Main Loop

while(True):

 

 

    # capture frames from the camera

    for image in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):

            frame = image.array  

            gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 

            faces = face_cascade.detectMultiScale(gray, 2, 5) 

            if (len(faces) > 0): 

                faceFound = True

            else:

                faceFound = False

 

          if (faceFound) :

              for idx,(x,y,w,h) in enumerate(faces):

                cv2.rectangle(frame,(x,y),(x+w,y+h),(255,0,0),2)

                 roi_gray = gray[y:y+h,x:x+w]

                 roi_color = frame[y:y+h,x:x+w]

                 eyes=eye_cascade.detectMultiScale(roi_gray, 2,5)

                  for eidx,(ex,ey,ew,eh) in enumerate(eyes):

                       cv2.rectangle(roi_color,(ex,ey),(ex+ew,ey+eh),(0,0,255),2) 

 

            # Output the video

            if (showVideo):

                cv2.imshow('VideoOutput', frame)

 

            # clear the stream in preparation for the next frame

            rawCapture.truncate(0)

 

            # Check for keypresses

            key = cv2.waitKey(1) & 0xFF

            if key == ord("q"):

                print "Q Pressed"

                break

    cv2.destroyAllWindows()


 

  

 줌인 기능등 여러가지 기능이 포함되어있지만 여기서는 생략을 하였다. VideoOutput의 윈도우 이름을 가진 결과 영상은 아래와 같다.

                           ff103f49d77b8f518f6fb7a62f33586a_1497318 

 

캐리커쳐 영상이지만 얼굴과 눈이 잘 검출된다. 

  
 

 

 

 


누렁이음머어어 2018-03-28 (수) 19:35 1년전
안녕하세요  질문이 간절히 있습니다...
눈을 인식하는데, 눈사이 중점과  카메라사이  연장선의 지평면에 대한 각도를 측정하는것이 가능할까요?
주소
모바일 버전으로 보기