基于PaddleHub的人脸检测:AI人脸打飞机(第2版)
第 1 版链接如下:
第 2 版的改进:
- 大幅增加流畅度
- 采用新的动作侦测算法,代码缩减 100 行 +
- 修改游戏背景
- 修正音乐 bug
- 修改部分飞机参数
效果视频请看 B 站,链接如下:
基于PaddleHub的人脸检测:AI人脸打飞机(第2版)附代码
所有代码和素材文件请见 GitHub:
github: planegame_head_control
关于头部角度的算法:
原来使用的是欧拉角的算法,来进行头部的角度计算
但是分析了一下以这个项目的需求来看,不需要精度太高的角度计算,所有其实可以采用简化的算法来代替复杂的欧拉角计算
头部角度检测部分的代码片段如下
class HeadPostEstimation():
"""
头部姿态识别
"""
def __init__(self, face_detector=None):
self.module = hub.Module(name="face_landmark_localization", face_detector_module=face_detector)
def get_face_landmark(self, image):
"""
预测人脸的68个关键点坐标
images(ndarray): 单张图片的像素数据
"""
try:
# 选择GPU运行,use_gpu=True,并且在运行整个教程代码之前设置CUDA_VISIBLE_DEVICES环境变量
res = self.module.keypoint_detection(images=[image], use_gpu=True)
return True, res[0]['data'][0]
except Exception as e:
logger.error("Get face landmark localization failed! Exception: %s " % e)
return False, None
def get_lips_distance(self, face_landmark):
"""
从face_landmark_localization的检测结果中查看上下嘴唇的距离
"""
lips_points = np.array([
face_landmark[52], face_landmark[58]
], dtype='float')
head_points = np.array([
face_landmark[25], face_landmark[8]
], dtype='float')
lips_distance = np.sum(np.square(lips_points[0] - lips_points[1]))
head_distance = np.sum(np.square(head_points[0] - head_points[1]))
relative_distance = lips_distance / head_distance
return relative_distance
def get_nose_distance(self,face_landmark):
"""
从face_landmark_localization的检测结果中获得鼻子的位置,以此判断头部运动
"""
nose_point = np.array([
face_landmark[31]
], dtype='float')
cheek_points = np.array([
face_landmark[3], face_landmark[15]
], dtype='float')
left_distance = np.sum(np.square(nose_point[0] - cheek_points[0]))
right_distance = np.sum(np.square(nose_point[0] - cheek_points[1]))
nose_position_h = left_distance/(left_distance+right_distance)
nose_position_v = nose_point[0][1]-cheek_points[0][1] # 获得鼻子和脸颊定位点的高度相对值,以此作为抬头/低头的判断
return nose_position_h, nose_position_v
def classify_pose(self, video):
"""
video 表示不断产生图片的生成器
"""
for index, img in enumerate(video(), start=1):
self.img_size = img.shape
success, face_landmark = self.get_face_landmark(img)
if not success:
logger.info("Get face landmark localization failed! Please check your image!")
continue
if not success:
logger.info("Get rotation and translation vectors failed!")
continue
# 计算嘴唇距离
lips_distance = self.get_lips_distance(face_landmark)
# 计算鼻子左右位置
nose_position_h, nose_position_v = self.get_nose_distance(face_landmark)
# 转换成摄像头可显示的格式
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 本地显示预测视频框,AIStudio项目不支持显示视频框
#cv2.imshow('Pose Estimation', img_rgb)
return nose_position_h, nose_position_v, lips_distance