python opencv顔認識

18873 ワード

Python OpenCV顔認識
ローカル二値モードヒストグラム顔認識器
画像から局所的特徴を抽出し,LBPという方式で抽出した特徴は低い次元を持つ.画像の表現は光照射の変化の影響を受けないことが分かった.局所二値モードの基本思想は,画素とその近傍を比較することによって画像の局所構成をまとめることである.
1つの画素を中心として、隣接領域と比較します.中心画素の階調値が隣接領域より大きい場合は1、そうでない場合は0とする.これにより、各画素点は最終的に1つのバイナリ数、例えば11001111を得る.したがって,8近傍の画素は,最終的には2^8種類の組合せがあり,局所二値モードと呼ばれる.
import cv2 as cv
import os
import numpy as np
import sklearn.preprocessing as sp

fd = cv.CascadeClassifier('face.xml')
def search_faces(directory):
    directory = os.path.normpath(directory)
    if not os.path.isdir(directory):
        raise IOError("     :"+ directory)
    faces = {}
    for curdir,subdirs,files in os.walk(directory): #    
        for jpeg in (file for file in files if file.endswith('.jpg')):
            path = os.path.join(curdir,jpeg)
            label = path.split(os.path.sep)[-2]#          
            if label not in faces:
                faces[label] = []
            faces[label].append(path)
    return faces
train_faces = search_faces('faces/objects/training')
codec = sp.LabelEncoder()#     
codec.fit(list(train_faces.keys()))#       
train_x,train_y = [],[]
for label,filenames in train_faces.items():
    for filename in filenames:
        image = cv.imread(filename)
        gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
        # minSize(  )     ,  。
        faces = fd.detectMultiScale(gray,1.1,3,minSize=(100,100)) #    
        for l,t,w,h in faces:
            train_x.append(gray[t:t+h,l:l+w])#    
            train_y.append(codec.transform([label])[0])
train_y = np.array(train_y)
model = cv.face.LBPHFaceRecognizer_create()#              
model.train(train_x,train_y)#    
#      /  
test_faces = search_faces('faces/objects/testing')
test_x,test_y,test_img = [],[],[]
for label,filenames in test_faces.items():
    for filename in filenames:
        image = cv.imread(filename)
        gray = cv.cvtColor(image,cv.COLOR_BGR2GRAY)
        # minSize(  )     ,  。
        faces = fd.detectMultiScale(gray,1.1,2,minSize=(100,100)) #    
        for l,t,w,h in faces:
            test_x.append(gray[t:t+h,l:l+w])#    
            test_y.append(codec.transform([label])[0])
            a,b = int(w/2),int(h/2)
            cv.ellipse(image,(l+a,t+b),(a,b),0,0,360,(255,0,255),2)
            test_img.append(image)
test_y = np.array(test_y)
#      
pred_test_y = []
for face in test_x:
    pred_code = model.predict(face)[0]
    pred_test_y.append(pred_code)
escape = False
while not escape:
    for code,pred_code,image in zip(test_y,pred_test_y,test_img):
        label,pred_label = codec.inverse_transform([code,pred_code])
        text = '{} {} {}'.format(label,'=='if code == pred_code else '!=',pred_label)
        cv.putText(image,text,(20,100),cv.FONT_HERSHEY_SIMPLEX,1,(255,255,255),2)
        cv.imshow('recongnizing...',image)
        if cv.waitKey(1000)==27:
            escape = True
            break