opencv + face_recognition —— 人臉識別案例

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()

face_02

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()
    

face_03

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()
    

face_06

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()
    

face_04

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()
    

face_05

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