文章目錄
opencv + face_recognition —— 人臉識別案例
0. 版本信息
-
版本信息
產品 版本 python 3.7 anaconda 4.8.3 jupyter 6.0.3 opencv 3.4.2 dlib 19.17.99 face_recognition 1.3.0 -
安裝 face_recognition 的方法
- 打開Anaconda Prompt,進入命令行
pip install cmake -i "https://pypi.doubanio.com/simple/"
- 度盤下載:dlib , 提取碼:84du
pip install dlib-19.17.99-cp37-cp37m-win_amd64.whl
pip install face_recognition -i "https://pypi.doubanio.com/simple/"
1. 導包
import face_recognition
import cv2
import os
2. 識別圖片中的面部
# 讀取圖片
img = cv2.imread("./peoples.jpg")
# 轉換 BGR(opencv使用) 爲 RGB(face_recognition使用)
rgb_img = img[:, :, ::-1]
# 識別圖片中的臉部(可能存在多個臉)
face_locations = face_recognition.face_locations(rgb_img)
# 遍歷人臉位置信息
for top, right, bottom, left in face_locations:
# 對人臉畫框
cv2.rectangle(img, (left, top), (right, bottom), (0, 255, 0), 2)
# 後面顯示還是用img顯示(BGR),不要用rgb_img顯示,否則你會得到意向不到的“阿凡達”特效,哈哈
# 展示,按q退出
cv2.imshow("img", img)
if cv2.waitKey() == ord("q"):
cv2.destroyAllWindows()
3. 實現攝像頭中的面部追蹤
# 捕獲0號攝像頭
video_capture = cv2.VideoCapture(0)
while True:
# 讀取攝像頭信息
# ret表示是否正常捕獲到圖像
# frame表示當前幀,即一張圖片
ret, frame = video_capture.read()
# 開始處理
if ret:
# 轉換 BGR(opencv使用) 爲 RGB(face_recognition使用)
rgb_img = frame[:, :, ::-1]
# 識別圖片中的臉部(可能存在多個臉)
face_locations = face_recognition.face_locations(rgb_img)
# 遍歷人臉位置信息
for top, right, bottom, left in face_locations:
# 對人臉畫框
cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2)
cv2.imshow("video", frame)
if cv2.waitKey(1) == ord("q"):
break
video_capture.release()
cv2.destroyAllWindows()
4. 人臉追蹤+識別,分析出不同的人
- 準備一個文件夾(或者數據庫),放入你的人臉圖片(一張圖片一個臉),例如
- ./face_images/xiaowang.jpg
- ./face_images/lilei.jpg
- 讀取已經準備好的人臉圖片信息
# 人姓名 person_names = [] # 人面部信息 person_face_encodings = [] img_dir = "./face_images/" files = os.listdir(img_dir) for file in files: if file.endswith("jpg") or file.endswith("png"): # 去除文件後綴類型 name, _ = os.path.splitext(file) person_names.append(name) # 拼接圖片完整路徑 img_path = os.path.join(img_dir, file) # 解析出已有圖片的臉部信息 img_file = face_recognition.load_image_file(img_path) face_endocing = face_recognition.face_encodings(img_file)[0] person_face_encodings.append(face_endocing)
- 捕獲攝像頭,並對比已知的人臉信息
# 捕獲攝像頭 video_caputre = cv2.VideoCapture(0) while True: ret, frame = video_caputre.read() if ret: # 轉換 BGR(opencv使用) 爲 RGB(face_recognition使用) rgb_img = frame[:, :, ::-1] # 識別圖片中的臉部 face_locations = face_recognition.face_locations(rgb_img) # 對識別出的面部區域編碼 face_encodings = face_recognition.face_encodings(rgb_img, face_locations) # 遍歷人臉,進行識別 for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings): # 畫框 cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2) # 將圖中的面部與已有的面部進行對比,得到姓名 matches = face_recognition.compare_faces(person_face_encodings, face_encoding) name = "Unknown" for index, match in enumerate(matches): if match: name = person_names[index] break # 寫姓名 cv2.putText(frame, name, (left, top - 10), cv2.FONT_ITALIC, 1, (0, 255, 0), 2) cv2.imshow("video", frame) if cv2.waitKey(1) == ord("q"): break video_caputre.release() cv2.destroyAllWindows()
5. 人臉追蹤+識別,分析出不同的人(優化)
- 準備的人臉信息部分同前面的小節4
- 優化後的代碼,參考自官方示例
# 優化點 # 1. 縮小原圖,再進行識別,提高了識別的速度 # 2. 交替,每隔一幀,進行一次識別,降低了識別的頻次 video_capture = cv2.VideoCapture(0) # 初始化變量 face_locations = [] # 臉部位置列表 face_encodings = [] # 臉部編碼列表 face_names = [] # 臉的人名列表 process_this_frame = True # 是否識別當前幀 while True: # 讀取幀 ret, frame = video_capture.read() # 讀取失敗,就退出 if not ret: break # 縮放當前幀爲1/4,以提高後面的識別速度 small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) # 轉換BGR爲RGB,方便face_recognition使用 rgb_small_frame = small_frame[:, :, ::-1] # 識別處理 if process_this_frame: # 獲取當前幀的人臉位置、編碼 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: # 人名、近似度的默認值 name = "Unknown" similarity = 0.0 # 計算當前臉與已知的臉的歐氏距離,越小越相近 face_distances = face_recognition.face_distance(person_face_encodings, face_encoding) # 將當前人臉編碼與已知的所有人臉編碼進行比對,確定是否匹配 matches = face_recognition.compare_faces(person_face_encodings, face_encoding) # 獲取第一個匹配的人名 for index, match in enumerate(matches): if match: name = person_names[index] similarity = face_distances[index] break face_names.append((name, similarity)) # 交替 True, False, True, ... # 保證每隔一幀進行一次識別,而不是每一幀都識別 process_this_frame = not process_this_frame # 顯示面部的框、人名 for (top, right, bottom, left), (name, similarity) in zip(face_locations, face_names): # 由於前面是從小圖的中識別的臉,因此此處要擴大回原來的比例 top *= 4 right *= 4 bottom *= 4 left *= 4 # 畫臉的框 cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2) # 畫文字 cv2.putText(frame, "%s, %.2f" % (name, similarity), (left, top - 10), cv2.FONT_HERSHEY_DUPLEX, 1.0, (0, 255, 0), 1) cv2.imshow('Video', frame) if cv2.waitKey(1) == ord('q'): break video_capture.release() cv2.destroyAllWindows()
6. 人臉追蹤,打上馬賽克
- 馬賽克處理
# 方法-爲圖片某個區域打上馬賽克 def do_mosaic(img, top, right, bottom, left, step): for i in range(top, bottom, step): for j in range(left, right, step): for y in range(0, step): for x in range(0, step): frame[i + y, j + x] = frame[i, j]
- 爲人臉打上馬賽克
# 開始處理 video_capture = cv2.VideoCapture(0) while True: ret, frame = video_capture.read() if ret: # 轉換 BGR(opencv使用) 爲 RGB(face_recognition使用) rgb_img = frame[:, :, ::-1] # 識別圖片中的臉部 face_locations = face_recognition.face_locations(rgb_img) # 遍歷人臉,進行識別 for (top, right, bottom, left) in face_locations: # 打上馬賽克 do_mosaic(frame, top, right, bottom, left, 8) # 畫框 cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2) cv2.imshow("video", frame) if cv2.waitKey(1) == ord("q"): break video_capture.release() cv2.destroyAllWindows()
7. 人臉追蹤,磨皮美顏
- 雙邊濾波-磨皮美顏
# 方法-圖中某個區域磨皮美顏 def do_beautify(img, top, right, bottom, left): # 雙邊濾波-磨皮美顏 beautify_img = cv2.bilateralFilter(img[top: bottom, left:right], 10, 20, 20) # 修改原圖 height, width, channels = beautify_img.shape for i in range(0, height): for j in range(0, width): img[top + i, left + j] = beautify_img[i, j]
- 爲人臉進行磨皮
# 開始處理 video_caputre = cv2.VideoCapture(0) while True: ret, frame = video_caputre.read() if ret: # 轉換 BGR(opencv使用) 爲 RGB(face_recognition使用) rgb_img = frame[:, :, ::-1] # 識別圖片中的臉部 face_locations = face_recognition.face_locations(rgb_img) # 遍歷人臉,進行識別 for (top, right, bottom, left) in face_locations: # 雙邊濾波-磨皮美顏 do_beautify(frame, top, right, bottom, left) # 畫框 cv2.rectangle(frame, (left, top), (right, bottom), (0, 255, 0), 2) cv2.imshow("video", frame) if cv2.waitKey(1) == ord("q"): break video_capture.release() cv2.destroyAllWindows()