ML/머신러닝

[openCV]얼굴인식 기술을 이용한 화면 잠금해제

KAU 2020. 3. 17. 14:51

cv2라이브러리를 이용하면 얼굴인식 라이브러리를 이용할 수 있습니다.

opencv 중에서도 haarcascade_frontalface_default.xml가 얼굴인식 xml입니다!

 

저는 주피터 환경에서 실행시켰는데 코랩에서는 실행이 잘 되지 않더라고요. 

코랩도 시도 중입니다.

 

코드에서 오류가 난다면 haaracascade 오류일 가능성이 있습니다.

그럴 경우 절대 경로를 지정해주면 좋습니다. 

file_name_path = 'C:/Users/jeong min/Desktop/Facial-Recognition-master/Facial-Recognition-master/faces/'+str(count)+'.jpg' 

위는 파일 저장 경로인데 실행 환경마다 라이브러리마다 조금씩 다를 수 있으나 

절대 경로를 위와 같이 지정해주면 사진이 저장되고 저장된 폴더에서 사진을 불러와 학습됩니다.

videocapture(0) 이 노트북에 내장되어 있는 캠을 켜는 코드입니다!

 

<학습 데이터 모으기>

import cv2 
import numpy as np 

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


def face_extractor(img): 

    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 
    faces = face_classifier.detectMultiScale(gray,1.3,5) 

    if faces is(): 
        return None 

    for(x,y,w,h) in faces: 
        cropped_face = img[y:y+h, x:x+w] 

    return cropped_face 


cap = cv2.VideoCapture(0) 
count = 0 

while True: 
    ret, frame = cap.read() 
    if face_extractor(frame) is not None: 
        count+=1 
        face = cv2.resize(face_extractor(frame),(200,200)) 
        face = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY) 

        file_name_path = 'C:/Users/jeong min/Desktop/Facial-Recognition-master/Facial-Recognition-master/faces/'+str(count)+'.jpg' 
        cv2.imwrite(file_name_path,face) 

        cv2.putText(face,str(count),(50,50),cv2.FONT_HERSHEY_COMPLEX,1,(0,255,0),2) 
        cv2.imshow('Face Cropper',face) 
    else: 
        print("Face not Found") 
        pass 

    if cv2.waitKey(1)==13 or count==100: 
        break 

cap.release() 
cv2.destroyAllWindows() 
print('Colleting Samples Complete!!!')

 

100장의 사진이 저장 된다

 

<학습시키기>

import cv2 
import numpy as np 
from os import listdir 
from os.path import isfile, join 
data_path = 'C:/Users/jeong min/Desktop/Facial-Recognition-master/Facial-Recognition-master/faces/' 
#faces폴더에 있는 파일 리스트 얻기  
onlyfiles = [f for f in listdir(data_path) if isfile(join(data_path,f))] 
#데이터와 매칭될 라벨 변수  
Training_Data, Labels = [], [] 
#파일 개수 만큼 루프  
for i, files in enumerate(onlyfiles):     
    image_path = data_path + onlyfiles[i] 
    #이미지 불러오기  
    images = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) 
    #이미지 파일이 아니거나 못 읽어 왔다면 무시 
    if images is None: 
        continue     
    #Training_Data 리스트에 이미지를 바이트 배열로 추가  
    Training_Data.append(np.asarray(images, dtype=np.uint8)) 
    #Labels 리스트엔 카운트 번호 추가  
    Labels.append(i) 

#훈련할 데이터가 없다면 종료. 
if len(Labels) == 0: 
    print("There is no data to train.") 
    exit() 

#Labels를 32비트 정수로 변환 
Labels = np.asarray(Labels, dtype=np.int32) 
#모델 생성  
model = cv2.face.LBPHFaceRecognizer_create() 
#학습 시작  
model.train(np.asarray(Training_Data), np.asarray(Labels)) 
print("Model Training Complete!!!!!")

학습 완료

 

<테스트하기>

import cv2 
import numpy as np 
from os import listdir 
from os.path import isfile, join 
##### 여기서부터는 Part2.py와 동일  
data_path =  'C:/Users/jeong min/Desktop/Facial-Recognition-master/Facial-Recognition-master/faces/' 
onlyfiles = [f for f in listdir(data_path) if isfile(join(data_path,f))] 
Training_Data, Labels = [], [] 
for i, files in enumerate(onlyfiles): 
    image_path = data_path + onlyfiles[i] 
    images = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE) 
    if images is None: 
        continue     
    Training_Data.append(np.asarray(images, dtype=np.uint8)) 
    Labels.append(i) 
if len(Labels) == 0: 
    print("There is no data to train.") 
    exit() 
Labels = np.asarray(Labels, dtype=np.int32) 
model = cv2.face.LBPHFaceRecognizer_create() 
model.train(np.asarray(Training_Data), np.asarray(Labels)) 
print("Model Training Complete!!!!!") 
#### 여기까지 Part2.py와 동일  

#### 여긴 Part1.py와 거의 동일  
face_classifier = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') 

def face_detector(img, size = 0.5): 
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) 
    faces = face_classifier.detectMultiScale(gray,1.3,5) 
    if faces is(): 
        return img,[] 
    for(x,y,w,h) in faces: 
        cv2.rectangle(img, (x,y),(x+w,y+h),(0,255,255),2) 
        roi = img[y:y+h, x:x+w] 
        roi = cv2.resize(roi, (200,200)) 
    return img,roi   #검출된 좌표에 사각 박스 그리고(img), 검출된 부위를 잘라(roi) 전달 
#### 여기까지 Part1.py와 거의 동일  
#카메라 열기  
cap = cv2.VideoCapture(0) 

while True: 
    #카메라로 부터 사진 한장 읽기  
    ret, frame = cap.read() 
    # 얼굴 검출 시도  
    image, face = face_detector(frame) 
    try: 
        #검출된 사진을 흑백으로 변환  
        face = cv2.cvtColor(face, cv2.COLOR_BGR2GRAY) 
        #위에서 학습한 모델로 예측시도 
        result = model.predict(face) 
        #result[1]은 신뢰도이고 0에 가까울수록 자신과 같다는 뜻이다.  
        if result[1] < 500: 
            #????? 어쨋든 0~100표시하려고 한듯  
            confidence = int(100*(1-(result[1])/300)) 
            # 유사도 화면에 표시  
            display_string = str(confidence)+'% Confidence it is user' 
        cv2.putText(image,display_string,(100,120), cv2.FONT_HERSHEY_COMPLEX,1,(250,120,255),2) 
        #75 보다 크면 동일 인물로 간주해 UnLocked!  
        if confidence > 75: 
            cv2.putText(image, "Unlocked", (250, 450), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 255, 0), 2) 
            cv2.imshow('Face Cropper', image) 
        else: 
           #75 이하면 타인.. Locked!!!  
            cv2.putText(image, "Locked", (250, 450), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2) 
            cv2.imshow('Face Cropper', image) 
    except: 
        #얼굴 검출 안됨  
        cv2.putText(image, "Face Not Found", (250, 450), cv2.FONT_HERSHEY_COMPLEX, 1, (255, 0, 0), 2) 
        cv2.imshow('Face Cropper', image) 
        pass 
    if cv2.waitKey(1)==13: 
        break 
cap.release() 
cv2.destroyAllWindows()

confidence 83퍼센트로 언락되는 모습
face detection using CV2.ipynb
0.01MB

주피터 환경에서 위의 파일을 실행해보실 수 있습니다!