人臉識別(一):Ubuntu Python安裝dlib C++ library
人臉識別(四):人臉識別理論、原理、分類、概括,請針對性學習所需算法,不要全學。
人臉識別(五):基於Adaboost的人臉檢測算法,及實例教程
目錄
前言
人臉識別(二)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 庫實現人臉檢測、識別,還推廣到視頻和其他的場景中。這些都是爲學習人臉識別準備,如果有人臉識別的理論基礎最好,若是沒有理論基礎,可以先跟隨以上代碼抄一抄、調一調參數,找一找感覺。
往後一篇將重點介紹人臉識別的理論基礎,感興趣的話可以看看。
下一篇將簡要學習人臉識別的理論、算法分類,推薦讀者針對性研究: