Predict person in a webcam realtime with Opencv3.0 and Python3.4

I created iPython notebook. Here is a python script converted by iPython nbconvert.


aaa



# coding: utf-8



# In[ ]:



import cv2

import csv

import os

from PIL import Image

import numpy as np





# In[ ]:



os.chdir(os.path.dirname(__file__))





# In[ ]:



cascPath = r'/home/watanabe/opencv/data/haarcascades/haarcascade_frontalface_default.xml'

faceCascade = cv2.CascadeClassifier(cascPath)

video_capture = cv2.VideoCapture(0)





# In[ ]:



def crop_face(path):

    """

    path = foulder containing person photos. createfolder in the same level as path and save faces:

    dataset/cls/0.jpg,

    dataset/set/cls/1.pg

    ...

    """

    if(len(os.listdir(path))==0):

        print('No photos in path.')

        return False

    for i,f in enumerate(os.listdir(path)):

        f = os.path.join(path,f)

        image = cv2.imread(f)

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

        faces = faceCascade.detectMultiScale(

            gray,

            scaleFactor=1.1,

            minNeighbors=5,

            minSize=(30, 30))

        if(len(faces)==0):

            continue

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

            face_photo_path = os.path.join(path,'{0}-x{1}.jpg'.format(i,x))

            print(face_photo_path)

            cv2.imwrite(face_photo_path, image[y:y+h,x:x+w])

          

# crop_face(r'dataset/person3')





# In[ ]:



bugWords={}

# people.csv should contain a label and a name:

# 0,Alice

# 1,Bob

# 2,Carol

# ...

with open(r'dataset/people.csv','r') as f:

    reader = csv.reader(f)

    for row in reader:

        bugWords[int(row[0])]=row[1]

        print(int(row[0]),row[1])

    else:

        print('Bug words were loaded.')

      





# In[ ]:



def create_csv(path):

    """

    create dataset.csv in the same folder.

    path

    |--trainset.csv <- created

    |--0

    |  |--0.jpg

    |  |--1.jpg

    |--1

    |  |--0.jpg

    |  |--1.jpg

    ...

    """

    path = os.path.basename(path)

    with open(os.path.join(path,'trainset.csv'), 'w', newline='') as f:

        writer = csv.writer(f)

        folders = os.listdir(path)

        cls = [i for i in folders if i.isdigit()]

        for cl in cls:

            pics = os.listdir(os.path.join(os.getcwd(),path,cl))

            for pic in pics:

                writepath = os.path.join(os.getcwd(),path,cl,pic)

                row = [writepath,cl]

                writer.writerow(row)

        else:

            print('{} was created.'.format(os.path.join(os.getcwd(),path,'trainset.csv')))

create_csv('dataset')

          





# In[ ]:



recognizer = cv2.face.createLBPHFaceRecognizer()





# In[ ]:



# Train recognizer with csv file

X_path=[]

X_tr=[]

y_tr=[]

with open('dataset/trainset.csv', 'r') as f:

    reader = csv.reader(f)

    print('Here are trained dataset:')

    for row in reader:

        tr_img_path=row[0]

        tr_class=int(row[1])

        # Open i

        image_pil = Image.open(tr_img_path).convert('L')

        im_gray = np.array(image_pil, 'uint8')

        X_tr.append(im_gray)

        X_path.append(tr_img_path)

        y_tr.append(tr_class)

        print(row)

    else:

        y_tr = np.array(y_tr)

        print('Finished training.')

      

recognizer.train(X_tr,y_tr)





# In[ ]:



# Capture Webcam

print('Launching a webcam.')

while True:

    # Capture frame-by-frame

    ret, frame = video_capture.read()

    if ret==True:



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



        faces = faceCascade.detectMultiScale(

            gray,

            scaleFactor=1.1,

            minNeighbors=5,

            minSize=(30, 30)

#             flags=cv2.cv.CV_HAAR_SCALE_IMAGE

        )



        # Draw a rectangle around the faces

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

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

            y_predicted, conf = recognizer.predict(gray[y: y + h, x: x + w])

            name_predicted = bugWords[y_predicted]

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

            text='{}, {}'.format(name_predicted,int(conf))

            font_size=1.4

            cv2.putText(img=frame,text=text, org=(x,y-int(2.8*font_size)),fontFace=cv2.FONT_HERSHEY_PLAIN, fontScale=font_size, color=(0,255,0),thickness=2)

            print('{}, {}'.format(name_predicted,int(conf)))

#             print('{name} in ({x1},{x2})x({x2},{y2}) with conf = {conf}'.format(**{'x1':x,'y1':y,'x2':x+w,'y2':y+h,'name':name_predicted,'conf':conf}))

        # Display the resulting frame

        cv2.imshow('WebCam', frame)



        if cv2.waitKey(1) & 0xFF == ord('q'):

            break

    else:

        break





# In[ ]:



# When everything is done, release the capture

video_capture.release()

cv2.destroyAllWindows()


  1. First, you have to collect photos to train. crop_faces allows you to crop and save faces from a photo. 
  2. You have to filter them manually. Create "dataset" foulder in the same directory as .py file. In a "dataset" foulder, foulder "0" contains face photos of person0, and foulder "1" contains face photos of person1, and so on. foulder name is later used as the y labels.
  3. create_csv allows you to create csv file containing a face photo location and a label pair.
  4. Train data by loading csv file you have just created.
  5. Loanch a webcam. You can quit by typing "p". 
csv file contains something like
dataset/0/photo0.jpg 0
dataset/0/photo1.jpg 0
dataset/1/photo0.jpg 1
dataset/1/photo1.jpg 1
Executing on iPython Notebook was not stable in my environment, so I would recommend to do it on terminal like "sudo python3 face_prediction.py."

コメント

人気の投稿