2022年3月17日 星期四

[AI, Python] 它認得出我:Python CVZone + Face Recognition 函式庫

它認得出我:

Python CVZone [1] + Face Recognition [2] 函式庫

Line:ted2016.kpvs
Email:Lct4246@gmail.com
FBhttp://gg.gg/TedLeeFB/
Bloghttp://gg.gg/TedLeeBlog/

Mar. 17, 2022
88x31.png [3]
 


筆者拙著《Python玩AI,你也可以 – 從CVZone入門吧!(https://reurl.cc/X4MRbg)》與《讓我們Py在一起:手勢控制PowerPoint放映切換(https://reurl.cc/Goy57A)》兩篇文章介紹了以 OpenCV 影像處理(image processing)為基礎的深度學習(Deep Learning)上層框架 CVZone(Computer Vision Zone)之若干示例,這些內容是十分適合懂一點 Python 語法的中學生入門體驗 AI 的相關應用。
本文再跟隨陳會安老師先前分享幾十行 Python 程式碼玩人臉辨識(facial recognition)的精彩範例程式(https://reurl.cc/Mb53kW),邀請讀者們一起來玩玩看電腦也能認得出主人的刷臉神技吧!

先玩再說

筆者非常強調「編程直覺(programming intuition)。也就是說,在尚未開始研究別人寫的程式之前,讓它先可以動起來玩對於編程的抽象邏輯思維理解是很重要的第一步!
請讀者先接好攝影機,再下載我們已經在會安老師分享的 fChart 工具箱(toolkit)[4] 中裝好 人臉辨識  函式庫(library) face_recognition [5] 的英文版工具箱壓縮檔「fChartThonny6_cvzone_face_recognition_en.zip(https://reurl.cc/rQG2jy)」。
將它解到 c:\ 根目錄下 [6]  後,在檔案總管中切換路徑(path)C:\fChartThonny6_cvzone_face_recognition_en\WinPython」即可找到 Thonny IDE 的執行檔thonny.vbs」,如圖 1 所示。雙撃開啟的畫面如圖 2 所示。其中,檔案管理的樹狀顯示面板可以從「View ® Files」做切換(如圖 3 所示)。

圖 1:thonny.vbs」所在路徑

圖 2:雙撃thonny.vbs」執行 Thonny IDE

圖 3:「檔案(Files)」樹狀管理面板

接著,請下載我們已加註好的範例程式碼(它認得出我_03192022.zip,https://reurl.cc/9ONYrX),將之解壓縮(例如:d:\)後就能如圖 2 在 Thonny IDE 的左側面板(panel)中做專案管理(project management)
最後,雙撃開啟「findFaces_webcam_TedLee_03172022.py」這隻 Python 程式,再按下後即可執行它(圖 4)。

 
圖 4:原始檔「findFaces_webcam_TedLee_03172022.py」之執行畫面

Python 字典(dictionary)

Python 提供了字典的抽象資料結構(data structure),它以成對的 (鍵 key: 值 value) 格式儲存。顧名思義,在實作上,給定一特定的鍵,則能取得其對應的值,正好類比了資料庫(database)建立(create)查詢(query)功能。
緊接著,我們先從「encodingFaces_TedLee_03172022.py」這隻程式中抽出一程式片斷 Dictionary.py 來舉例說明這個結構的簡單、易用之處。
如表 1,我們要建立一個含有人名及其年齡的資料串 known_face_list:

表 1:Python 提供的字典資料型態

然後,我們使用一個 for 迴圈把這個塞滿資料的字典內含一一倒出:Dictionary.py


known_face_list = [
    {
        "name": "Barack Obama",
        "age": 60,
    },
    {
        "name": "Joe Biden",
        "age": 79,     
    },
    {
        "name": "郭富城",
        "age": 56,  
    }
]

for data in known_face_list:  
    print(data["name"], end='')
    print(', ' + str(data["age"]))


程式的執行結果如下:

Barack Obama, 60
Joe Biden, 79
郭富城, 56

攝影機控制

在「findFaces_webcam_TedLee_03172022.py」中以OpenCV 不斷地從攝影機中取得輸入影像的流程如圖 5:

圖 5:控制攝影機不斷取得影像的流程

截取後的程式片斷「控camera.py」如下:CameraControl.py

import cv2
cap = cv2.VideoCapture(0) #開啟攝影機 while True: ret, frame = cap.read() #讀影像 rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) cv2.imshow('Video', frame) #顯示影像視窗 if cv2.waitKey(1) & 0xFF == ord('q'): #按 q 関閉視窗 break #釋放資源 cap.release() cv2.destroyAllWindows()


「控camera.py」的執行結果:

圖 6:「控camera.py」執行畫面

OpenCV 顯示中文字

會安老師原先分享的版本如果人像白名單裡有中文人名的話則會以羅馬拼音來顯示(圖 7),這是因為 putText() 方法缺乏中文字型而只能處理英文字。我們參考了這篇 https://reurl.cc/Dd2Ame,並使用了 Windows 內建的微軟正黑體字型檔(msjh.ttf)來顯示中文人名。

圖 7:會安老師版程式只能以羅馬拼音顯示中文人名

我們修改後的測試程式如下(執行結果如圖 8):ShowChineseWords.py

import numpy as np
import cv2
from PIL import ImageFont, ImageDraw, Image

img = np.zeros((450, 450, 3), np.uint8)

# 將背景設定為大紅色
img[:] = (0, 0, 255)

# 文字
text = '招財\n進寶'

# 指定 TTF 字體檔
fontPath = "C:\\Windows\\Fonts\\msjh.ttc"

# 載入字體
font = ImageFont.truetype(fontPath, 162)

# 將 NumPy 陣列轉為 PIL 影像
imgPil = Image.fromarray(img)

# 在圖片上加入文字
draw = ImageDraw.Draw(imgPil)
draw.text((30, 30),  text, font = font, fill = (0, 0, 0))

# 將 PIL 影像轉回 NumPy 陣列
img = np.array(imgPil)

cv2.imshow('My Image', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

圖 8:顯示中文字

人臉辨識

本範例將Biden、Obama和郭富城三張白名單人臉經由「encodingFaces_TedLee_03172022.py」編碼(encode)後產生「faces_encoding.dat」二進位檔(binary file)再餵給「findFaces_webcam_TedLee_03172022.py」去辨識。程式的執行流程如圖 9 所示。

圖 9:人臉辨識流程。

完整的程式碼如下(紅字的程式碼是做人臉識別處理,藍色的是顯示辨識到的中文人名):findFaces_webcam_TedLee_03172022.py

import face_recognition #https://github.com/ageitgey/face_recognition/blob/master/face_recognition/api.py
import cv2 #####
import numpy as np #argmin()
import pickle  #object serialization, API:
from PIL import ImageFont, ImageDraw, Image #顯示中文字

with open("faces_encoding.dat", "rb") as f:
    known_face_list = pickle.load(f)
    
known_face_encodings = [data["face_encoding"] for data in known_face_list]

cap = cv2.VideoCapture(0) #####開啟攝影機
while True: #####
    ret, frame = cap.read() #####讀影像
    rgb_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)  #####
    face_locations = face_recognition.face_locations(rgb_frame)
    face_encodings = face_recognition.face_encodings(rgb_frame, face_locations)
    for (top, right, bottom, left), face_encoding in zip(face_locations, face_encodings):
        face_distances = face_recognition.face_distance(known_face_encodings, face_encoding)
        best_match_index = np.argmin(face_distances)
#這是誰?
        if face_distances[best_match_index] < 0.6:
            name = known_face_list[best_match_index]["name"]
        else:
            name = "Unknown"
        
        #處理中文名顯示
        fontPath = "C:\\Windows\\Fonts\\msjh.ttc"
        font = ImageFont.truetype(fontPath, 50)
        imgPil = Image.fromarray(frame)
        draw = ImageDraw.Draw(imgPil)
        draw.text((10, 10), name, font = font, fill = (0, 255, 0)) #BGR
        frame = np.array(imgPil)       
        
        cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)  #####畫出 bounding box
        cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)  #####填滿姓名標示框
    cv2.imshow('Video', frame)  #####顯示影像視窗
    if cv2.waitKey(1) & 0xFF == ord('q'):  #####按 q 關閉視窗
        break  #####

#釋放資源
cap.release()  #####
cv2.destroyAllWindows()  #####


程式的執行果如圖 10,辨識結果的測試影片請參考 https://reurl.cc/oeM733。其中,本文範例程式的整合架構如圖 11 所示。

圖 10:人臉辨識結果。

圖 11:程式架構。

Maker AI+

經過了以上的解析,我們已有能力可以處理人臉識別的技術了。緊接著思考:它可以再如何和 maker 的技能相結合呢?我們以 72Action 這個曼陀羅(Mandal)創意思考 app 一起來腦力激盪:Maker AI+  ® 防走失 ® 自動拍照 ® 帳密提示 ® 刷臉開門 ® 情緒偵測 ® 認親 ® 留言、傳情 ® 借錢、結帳…,然後再從中挑一個有興趣的子主題一門深入吧!
如果讀者們任何好的想法或作品,也請不吝到我們的臉書社群 https://reurl.cc/g0ADAz 上來分享。

 
圖 11:Maker + AI 的曼陀羅發想。

後記:在 fChart 中安裝 face_recognition 函式庫 

會安老師在 https://reurl.cc/qORLW3 一文中已指明如何在他分享已裝妥 CVZone 的 fChart (https://reurl.cc/12V15X)中以「pip install face-recognition」命令即可安裝本文援用的 face_recognition 函式庫。開啟檔案總管,找到 c:\ 下的「fChartThonny6_cvzone_face_recognition_en」資料夾,雙撃 startfChartMenu.exe 後,再點撃工作列右側的 圖示後,選擇「Python Command Prompt (CLI)」即可下達安裝指令。完整的操作畫面如圖 12 所示。

圖 12:在 fChart 的 CLI 中安裝face-recognition 函式庫。