【人臉識別(三)】:使用face_recognition庫實現人臉識別,python實現

人臉識別(一):Ubuntu Python安裝dlib C++ library

人臉識別(二):如何使用 dlib 實現簡單的人臉識別功能

人臉識別(四):人臉識別理論、原理、分類、概括,請針對性學習所需算法,不要全學。

人臉識別(五):基於Adaboost的人臉檢測算法,及實例教程

目錄

前言

安裝face_recognition庫

人臉檢測和人臉輪廓檢測

人臉比對

檢測視頻中的人臉

人臉識別

視頻中人臉識別

CNN模型與CUDA加速人臉檢測

使用命令窗識別人臉

使用命令窗調整容忍度

使用命令窗顯示人臉之間的匹配度/距離

使用命令窗只輸出人名

使用命令窗控制CPU核數

小結


 

前言

人臉識別(二)https://blog.csdn.net/qq_39709813/article/details/105644815學習了使用dlib實現常用的人臉識別功能,今天將在dlib基礎上使用face_recognition庫實現人臉識別。

dlib的檢測精度爲99.13%,這次使用的face_recognition庫的檢測精度爲99.38%,二者都是很好的人臉識別庫,都支持機器學習等方面的應用。

face_recognition除了在程序中使用外,也可以在命令窗內直接使用。

dlib庫文件見:https://download.csdn.net/download/qq_39709813/12339920

face_recognition庫文件見:https://download.csdn.net/download/qq_39709813/12346000

本文程序實例代碼見:https://download.csdn.net/download/qq_39709813/12348320

這些內容僅供學習參考使用。

 

安裝face_recognition庫

安裝庫之前需要安裝dlib庫,因爲face_recognition是以dlib爲支撐。安裝dlib的方法見https://blog.csdn.net/qq_39709813/article/details/105614115

安裝完dlib之後,進入face_recognition_master文件夾內,打開命令窗口,進入所需要的環境,輸入:

pip3 install face_recognition

 

人臉檢測和人臉輪廓檢測

使用檢測框框取人臉部分和繪出人臉輪廓必要的68點。具體代碼保存在test1.py中,效果如下:

import face_recognition
import cv2


path = './face_images/2008_001322.jpg'

img = cv2.imread(path)
img_rgb = img[:, :, ::-1]

face_location = face_recognition.face_locations(img_rgb)  # 檢測框位置
face_landmarks_list = face_recognition.face_landmarks(img_rgb)  #面部輪廓位置

for i in range(len(face_location)):#繪製檢測狂
    rect = face_location[i]
    cv2.rectangle(img, (rect[3], rect[0]), (rect[1], rect[2]), (0, 0, 255), 2)

for word, face_landmarks in enumerate(face_landmarks_list):#繪製面部輪廓點
    for key, marks in face_landmarks.items():
        for i in range(len(marks)):
            point = marks[i]
            cv2.circle(img,(point[0], point[1]),2,(0,255,0))
            # img[point[1], point[0]]= [255,255,255]

cv2.imshow('img', img)
cv2.waitKey(0)
print("finish")

 

人臉比對

實現兩張人臉的比對,如果是同一人,輸出true,否則輸出false。具體代碼保存在test2.py中,效果如下:

import face_recognition

path_know = './people_i_know/obama.jpg'
path_unknow = './unknow_people/unknow2.jpg'

know = face_recognition.load_image_file(path_know)# 已知人的面部輪廓位置
unknow = face_recognition.load_image_file(path_unknow)# 未知人的面部輪廓位置

know_encoding = face_recognition.face_encodings(know)[0]# 已知人面部編碼
unknow_encoding = face_recognition.face_encodings(unknow)[0]# 未知人面部編碼

result = face_recognition.compare_faces([know_encoding],unknow_encoding)# 對比兩個面部編碼
print(result)

 

檢測視頻中的人臉

在檢檢測人臉的基礎上,結合opencv實現在視頻流中的人臉識別功能。具體代碼保存在test3.py中,效果如下:

import face_recognition
import cv2

video_capture = cv2.VideoCapture('./video/short_hamilton_clip.mp4')
# video_capture = cv2.VideoCapture(0)

while True:
    ret, frame = video_capture.read()
    img_rgb = frame[:, :, ::-1]

    face_location = face_recognition.face_locations(img_rgb)
    # face_location = face_recognition.face_locations(img_rgb, model="cnn")# 使用CNN模型

    for (top, right,bottom, left) in face_location:
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)#繪製檢測框
    cv2.imshow('image',frame)

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

video_capture.release()
cv2.destroyAllWindows()

 

人臉識別

檢測人臉之後,通過對 面部特徵的編碼,將其轉化爲特徵向量,通過比對兩張臉之間的特徵向量確定人臉是否認識。

其中path_know是已經認識人的文件路徑,path_unknow是需要識別的文件路徑。這就需要事先把認識的人和不認識的人分別放在people_i_know和unknow_people文件夾中。

程序輸出的是需要識別的人的具體名字或者unknow,具體的代碼保存在test4.py中,效果如下:

import face_recognition
import os

path_know = './people_i_know'
path_unknow = './unknow_people'

know = {}
for path in os.listdir(path_know):#建立已知人的面部特徵字典庫
    img = face_recognition.load_image_file(path_know+'/'+path)
    encoding = face_recognition.face_encodings(img)[0]
    name = path.split('.')[0]
    know[name] = encoding

match = {}
for path in os.listdir(path_unknow):
    img = face_recognition.load_image_file(path_unknow+'/'+path)
    encoding = face_recognition.face_encodings(img)[0]# 獲取未知人的面部特徵
    name = path.split('.')[0]
    match[name] = 'unknow'
    for key, value in know.items():
        if face_recognition.compare_faces([value],encoding)[0]:#與庫裏的特徵進行比對
            match[name] = key
            break

print(match)

for key, value in match.items():
    print(key+' is '+ value)

 

視頻中人臉識別

在人臉識別之上,結合opencv實現視頻中的人臉識別。具體代碼保存在test5.py中,效果如下:

import face_recognition
import cv2
import numpy as np
import os

# video_capture = cv2.VideoCapture(0)q
video_capture = cv2.VideoCapture('./video/hamilton_clip.mp4')

path_know = './people_i_know'

known_face_encodings = []
known_face_names = []

for path in os.listdir(path_know):
    img = face_recognition.load_image_file(path_know+'/'+path)
    encoding = face_recognition.face_encodings(img)[0]
    known_face_encodings.append(encoding)
    name = path.split('.')[0]
    known_face_names.append(name)


# Initialize some variables
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True

while True:
    # Grab a single frame of video
    ret, frame = video_capture.read()

    # Resize frame of video to 1/4 size for faster face recognition processing
    small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)

    # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
    rgb_small_frame = small_frame[:, :, ::-1]

    # Only process every other frame of video to save time
    if process_this_frame:
        # Find all the faces and face encodings in the current frame of video
        face_locations = face_recognition.face_locations(rgb_small_frame)
        face_encodings = face_recognition.face_encodings(rgb_small_frame, face_locations)

        face_names = []
        for face_encoding in face_encodings:
            # See if the face is a match for the known face(s)
            matches = face_recognition.compare_faces(known_face_encodings, face_encoding)
            name = "Unknown"

            # # If a match was found in known_face_encodings, just use the first one.
            # if True in matches:
            #     first_match_index = matches.index(True)
            #     name = known_face_names[first_match_index]

            # Or instead, use the known face with the smallest distance to the new face
            face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
            best_match_index = np.argmin(face_distances)
            if matches[best_match_index]:
                name = known_face_names[best_match_index]

            face_names.append(name)

    process_this_frame = not process_this_frame


    # Display the results
    for (top, right, bottom, left), name in zip(face_locations, face_names):
        # Scale back up face locations since the frame we detected in was scaled to 1/4 size
        top *= 4
        right *= 4
        bottom *= 4
        left *= 4

        # Draw a box around the face
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

        # Draw a label with a name below the face
        cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
        font = cv2.FONT_HERSHEY_DUPLEX
        cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)

    # Display the resulting image
    cv2.imshow('Video', frame)

    # Hit 'q' on the keyboard to quit!
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()

 

CNN模型與CUDA加速人臉檢測

使用CNN模型批量檢測視頻、圖片中的人臉,通過使用GPU加速,速度是原先的3倍左右。程序結果不輸出圖像,僅僅輸出文字結果。具體代碼保存在test6.py中,效果如下:

import face_recognition
import cv2

# Open video file
video_capture = cv2.VideoCapture("./video/hamilton_clip.mp4")

frames = []
frame_count = 0

while video_capture.isOpened():
    # Grab a single frame of video
    ret, frame = video_capture.read()

    # Bail out when the video file ends
    if not ret:
        break

    # Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
    frame = frame[:, :, ::-1]

    # Save each frame of the video to a list
    frame_count += 1
    frames.append(frame)

    # Every 128 frames (the default batch size), batch process the list of frames to find faces
    if len(frames) == 128:
        batch_of_face_locations = face_recognition.batch_face_locations(frames, number_of_times_to_upsample=0)

        # Now let's list all the faces we found in all 128 frames
        for frame_number_in_batch, face_locations in enumerate(batch_of_face_locations):
            number_of_faces_in_frame = len(face_locations)

            frame_number = frame_count - 128 + frame_number_in_batch
            print("I found {} face(s) in frame #{}.".format(number_of_faces_in_frame, frame_number))

            for face_location in face_locations:
                # Print the location of each face in this frame
                top, right, bottom, left = face_location
                print(" - A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right))

        # Clear the frames array to start the next batch
        frames = []

 

使用命令窗識別人臉

命令窗允許我們直接在文件夾中直接識別人臉,而不需要載入IDLE中。但注意使用有face_recognition包的環境。

同上,people_i_know存放已經知道的人臉圖像,unknow_people存放需要識別的圖像。

方法如下:

face_recognition ./people_i_know/ ./unknow_people/

 

使用命令窗調整容忍度

此處的--tolerance 0.54即爲容忍度設置參數,方法如下:

face_recognition --tolerance 0.54 ./people_i_know/ ./unknow_people/

 

使用命令窗顯示人臉之間的匹配度/距離

通過設置參數--show-distance true即可,方法如下:

face_recognition --show-distance true ./people_i_know/ ./unknow_people/

 

使用命令窗只輸出人名

設置參數 |cut -d ',' -f2即可,方法如下:

face_recognition --show-distance true ./people_i_know/ ./unknow_people/ |cut -d ',' -f2

 

使用命令窗控制CPU核數

設置 --cpus -1使用最大核數,具體核數可以自定義,方法如下:

face_recognition --cpus -1 ./people_i_know/ ./unknow_people/

 

展望

人臉識別的內容很豐富,本文的內容到此結束,以上內容可以作爲入門人臉識別的參考例程。更多開發的內容,希望讀者可以結合自己所需的場景進行探索、開發。

 

小結

至此,我們已經可以使用dlib 或者 face_recognition 庫實現人臉檢測、識別,還推廣到視頻和其他的場景中。這些都是爲學習人臉識別準備,如果有人臉識別的理論基礎最好,若是沒有理論基礎,可以先跟隨以上代碼抄一抄、調一調參數,找一找感覺。

往後一篇將重點介紹人臉識別的理論基礎,感興趣的話可以看看。

 

下一篇將簡要學習人臉識別的理論、算法分類,推薦讀者針對性研究:

人臉識別(四):人臉識別理論、原理、分類、概括,請針對性學習所需算法,不要全學。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章