基於Python實現人臉識別和焦點人物檢測功能
寫在前面的話
基於dlib庫的模型,實現人臉識別和焦點人物的檢測。最後呈現的效果為焦點人物的識別框顏色與其他人物框不一樣。
準備工作
需要安裝好python環境,安裝好dlib、opencv-python庫等,具體可以看報錯信息(可以使用PyCharm來運行和編輯py文件),然後把需要的庫補全,文章最後會有完整代碼,但是需要與shape_predictor_68_face_landmarks.dat模型文件同處一個路徑下,然後啟用。(百度可以下載到)
設計過程
- 因為是在自己電腦完成的必做題設計,所以前期還經歷瞭相應的Python安裝與環境配置,相應的資源庫安裝,例如dlib、opencv-python等等。
- 然後運行綜合瞭(68個人臉特征點檢測模型完成靜止圖像的人臉檢測與標註)和(完成實時攝制視頻的人臉檢測與定位)的參考文件opencv_webcam_face_detection.py,發現可以實現實時視頻的人臉檢測。
- 對參考文件的代碼進行分析,理解每一句代碼的意思。對比查找設計需要的功能模塊,實現1280×720視頻輸出,實現類win10相機的焦點人物識別。
- 上網查找並學習相應資料,參考win10相機的算法,創建自己的基於距離與面積的焦點人物算法,根據自己的需要對源代碼進行添加及修改。
- 最後對代碼進行測試,且不斷修改成最適合的版本。
Python程序
流程圖
焦點人物算法
內在邏輯:模仿win10相機,當有多於1個人時,優先選擇最居中的為焦點人物,但若在其他地方的人臉面積大於4倍中心的人臉面積,則選擇其他地方的作為焦點人物。
實際代碼
import dlib import cv2 import math # 攝像頭參數設置 cam = cv2.VideoCapture(0) # 參數0,調用計算機的攝像頭 cam.set(3, 1280) # 參數3,設定寬度分辨為1280 cam.set(4, 720) # 參數4,設定高度分辨為720 # 設定人臉框的邊框顏色及寬度,便於分辨焦點人物 color_focus = (255, 0, 255) # 設定焦點人臉框的顏色,紫紅色 color_other = (255, 255, 255) # 設定其餘人臉框的顏色,白色 lineWidth_focus = 2 # 設定焦點人臉框的寬度 lineWidth_other = 1 # 設定其他人臉框的寬度 # 設定計算的一些參數 w = cam.get(3) / 2 # 設定屏幕中心的橫坐標X h = cam.get(4) / 2 # 設定屏幕中心的縱坐標Y d_center = 10000 # 預設人臉框到屏幕中心的距離 index_center = 0 # 預設距離優先時的人臉框序號 index_area = 0 # 預設面積優先時的人臉框序號 area_center = -1 # 預設距離中心最近人臉框的面積 area = -1 # # 預設人臉框面積最大時的面積 detector = dlib.get_frontal_face_detector() # 加載這個庫自帶的人臉檢測器 predictor_path = "shape_predictor_68_face_landmarks.dat" # 設置人臉預測模型的路徑位置 predictor = dlib.shape_predictor(predictor_path) # 人臉預測實例化 while True: # 當獲取到視頻輸入時 ret_val, img = cam.read() # 讀取視頻每一幀,顏色格式為BGR格式, rgb_image = cv2.cvtColor(img, cv2.COLOR_BGR2RGB) # 顏色BGR格式轉為RGB格式 faces = detector(rgb_image) # 返回RGB格式人臉捕捉框 # 邏輯算法:當有多於1個人時,優先選擇最居中的為焦點人物,但若其他地方的人臉面積大於4倍中心的人臉面積,則選擇該為焦點人物。 # 這個for循環先求出距離屏幕中心最近時的人臉框的序號和距離優先面積 for i, det in enumerate(faces): # 遍歷所有人臉框,i是人臉框序號,det是每個人臉框 d = math.sqrt((w-(det.left()+(det.right()-det.left())/2))**2+(h-(det.top()+(det.bottom()-det.top())/2))**2) # 計算該人臉框到屏幕中心的距離 if d < d_center: # 對比剛計算出的距離與設定的最近距離,達成選擇更小 index_center = i # 更新距離最近時的人臉框序號 d_center = d # 更新最近距離 area_center = abs((det.right() - det.left()) * (det.bottom() - det.top())) # 算出該人臉框的面積(距離更近優先) # 這個for循環求出面積最大的人臉框的序號和面積優先面積 for i, det in enumerate(faces): # 遍歷所有人臉框,i是人臉框序號,det是每個人臉框 if abs((det.right() - det.left()) * (det.bottom() - det.top())) > area: # 對比該人臉面積與設定的最大面積,實現選擇更大 index_area = i # 更新面積更大時的人臉框序號 area = abs((det.right() - det.left()) * (det.bottom() - det.top())) # 算出該人臉框的面積(面積更大優先) if area > 5*area_center: # 判斷依據,若面積優先面積大於距離優先面積的5倍,就實現面積優先選擇焦點人物,否則就距離優先。 index_center = index_area # 面積優先時,使用面積最大的人臉框序號 for i, det in enumerate(faces): # 遍歷所有人臉框 if i == index_center: # 確定焦點人臉框的序號 print(d_center, i) # 輸出焦點人物的距離中心位置,方便調試 cv2.rectangle(img, (det.left(), det.top()), (det.right(), det.bottom()), color_focus, lineWidth_focus) # 繪出焦點人臉框 shape = predictor(img, det) # 從預測模型處,得到68個人物特征點 for p in shape.parts(): # 遍歷68個人物特征點 cv2.circle(img, (p.x, p.y), 2, (124, 252, 0), -1) # 設定焦點人物的68個點的形狀顏色,茶綠色、實心 else: cv2.rectangle(img, (det.left(), det.top()), (det.right(), det.bottom()), color_other, lineWidth_other) # 繪出其他人臉框 shape = predictor(img, det) # 從預測模型處,得到68個人物特征點 for p in shape.parts(): # 遍歷68個人物特征點 cv2.circle(img, (p.x, p.y), 2, (255, 255, 255), -1) # 設定其他人物的68個點的形狀顏色,白色、實心 cv2.imshow('my webcam', img) # 輸出繪好框後的幀動畫 if cv2.waitKey(1) == 27: # 設置一個滯留時間,等待用戶觸發事件,若用戶按下 ESC(ASCII碼為27),則執行 if 體 break # (if主體)退出 cv2.destroyAllWindows() # 銷毀所有輸出圖像窗
運行情況
為瞭容易分辨焦點人物與其他人物,首先將焦點人物框的寬度設為2,顏色設為紫紅色,68個識別點設為茶綠色;其他人物框的寬度設為1,顏色設為白色,68個識別點設為白色。
然後進行多次測試,通過整理測試結果,發現算法沒有錯誤,焦點人物按照距離和面積兩個因素來決定。成功運行圖如下:
不展示圖瞭,但是主人物為紫紅框,其他人物為白色圈。與預期一致。
到此這篇關於基於Python的人臉識別和焦點人物檢測的文章就介紹到這瞭,更多相關Python人臉識別和焦點人物檢測內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 樹莓派上利用python+opencv+dlib實現嘴唇檢測的實現
- 超詳細註釋之OpenCV dlib實現人臉采集
- 人臉檢測實戰終極之OpenCV+Python實現人臉對齊
- 教你如何用Python實現人臉識別(含源代碼)
- 基於Opencv制作的美顏相機帶你領略美顏特效的效果