首頁  >  文章  >  科技週邊  >  人臉辨識還能這麼玩

人臉辨識還能這麼玩

PHPz
PHPz轉載
2023-05-11 12:34:051007瀏覽

今天我們來擴充一下,用人臉玩飛機大戰。雖然想法跟手勢辨識類似,但代碼量比手勢辨識版稍多。

使用的人臉演算法是毫秒的,幀率能到 30,用電腦CPU運作也很流暢。

下面我分享下專案實作過程,文末取得專案完整的原始碼。

準備飛機大戰程序

Github上找到一個Python版本的飛機大戰程序,安裝Pygame即可運作。

人臉辨識還能這麼玩

用鍵盤的A、D、W、S鍵用來控制飛機的移動方向,分別對應左、右、上、下。

所以,接下來我們要做的是辨識人臉,並對人臉姿態進行估計,將估計後的結果映射到左、右、上、下,從而控制飛機的運行。

人臉辨識

這裡,我們用opencv讀取攝影機中的視訊串流。

將視訊串流中的每個畫面送入mediapipe中的人臉辨識模型,進行辨識。

人臉辨識還能這麼玩

圖片mediapipe 不只辨識人臉,還能標示出人臉 6 點左眼、右眼、左耳、右耳、鼻子、嘴巴。

核心程式碼:

with self.mp_face_detection.FaceDetection(
model_selection=0, min_detection_confidence=0.9) as face_detection:
while cap.isOpened():
success, image = cap.read()
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
results = face_detection.process(image)
image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)
if results.detections:
for detection in results.detections:
# 获取人脸框坐标
face_box = detection.location_data.relative_bounding_box
face_w, face_h = int(face_box.width * frame_w), int(face_box.height * frame_h)
face_l = int(face_box.xmin * frame_w) + face_w
face_t = int(face_box.ymin * frame_h)
face_r, face_b = face_l - face_w, face_t + face_h
# 显示人脸框
cv2.rectangle(image, (face_l, face_t), (face_r, face_b), (0, 255, 255), 2)
self.draw_zh_img(image, self.face_box_name_img, (face_r + face_l) // 2, face_t - 5)

pose_direct, pose_key_points = self.pose_estimate(detection)
# 显示人脸 6 个关键点
for point_name in FaceKeyPoint:
mp_point = self.mp_face_detection.get_key_point(detection, point_name)

point_x = int(mp_point.x * frame_w)
point_y = int(mp_point.y * frame_h)

point_color = (0, 255, 0) if point_name in pose_key_points else (255, 0, 255)
cv2.circle(image, (point_x, point_y), 4, point_color, -1)
# 显示关键点中文名称
point_name_img = self.face_key_point_name_img[point_name]
self.draw_zh_img(image, point_name_img, point_x, point_y-5)

這裡有個小知識點需要大家注意。

程式碼中用draw_zh_img來顯示中文,由於opencv不支援直接顯示中文。因此,我用PIL模組中Image方法提前繪製中文圖片,並轉為opencv格式。

人臉辨識還能這麼玩

在需要的時候,直接與視訊串流合併,效率高,不掉幀。

人臉姿態估計

之前手勢識別,我們用相鄰幀來判斷手勢的移動。人臉姿態估計只用當前幀就可以,相對容易一些。

我們透過人臉6 個關鍵點的座標距離,就可以判斷出人臉的姿態

人臉辨識還能這麼玩

這裡,左耳和鼻子的水平距離很近,因此,我們可以估計臉向左轉,從而可以用隻飛機向左移動。

同樣的,用其他關鍵點,我們可以估計出人臉向右轉、向上(抬頭)和向下(低頭)

核心代碼:

# 左耳与鼻子水平距离,判断面部左转
left_ear_to_nose_dist = left_ear.x - nose_pos.x 
# 右耳与鼻子水平距离,判断面部右转
nose_to_right_ear_dist = nose_pos.x - right_ear.x

# 鼻子与左眼垂直距离,判断面部向上
nose_to_left_eye_dist = nose_pos.y - left_eye.y
# 左耳与左眼垂直距离,判断面部向下
left_ear_to_left_eye_dist = left_ear.y - left_eye.y

if left_ear_to_nose_dist < 0.07:
# print('左转')
self.key_board.press_key('A')
time.sleep(0.07)
self.key_board.release_key('A')

return 'A', [FaceKeyPoint.NOSE_TIP, FaceKeyPoint.LEFT_EAR_TRAGION]
if nose_to_right_ear_dist < 0.07:
# print('右转')
self.key_board.press_key('D')
time.sleep(0.07)
self.key_board.release_key('D')
return 'D', [FaceKeyPoint.NOSE_TIP, FaceKeyPoint.RIGHT_EAR_TRAGION]

姿態控制飛機移動

辨識出人臉姿態,我們就可以用程式控制鍵盤,從而控制飛機移動。

這裡我用PyKeyboard模組控制鍵盤按鍵。

self.key_board = PyKeyboard()
# print('左转')
self.key_board.press_key('A')
time.sleep(0.07)
self.key_board.release_key('A')

press_key和release_key函數分別是按鍵和釋放按鍵。

它們之間,呼叫了time.sleep(0.07)控制按鍵的時長,按鍵時間長,則飛機移動距離就長,反之,按鍵時間短,則飛機移動距離就短,大家可以根據自己的需求來調節。

以上是人臉辨識還能這麼玩的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:51cto.com。如有侵權,請聯絡admin@php.cn刪除