1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| def is_facing(self, image, detection_results, idx=0): """ 使用检测结果判断是否为正脸人像 :param image cv2得到的帧数据 :param detection_results YOLOv8x-pose检测到的结果 :param idx 检测结果索引 :return bool """ x1, y1, x2, y2 = detection_results.boxes.xyxy[idx] image = image[int(y1):int(y2), int(x1):int(x2)]
res = detection_results
if not hasattr(res, 'keypoints') or not res.keypoints: return False points = res.keypoints.xy[idx] logging.info(f'[{self.video.stem}] Key Points: {points.tolist()}') if len(points) < 1: return False left_eye = points[1] right_eye = points[2] nose = points[0] self.result.update({ 'keypoints': points.tolist() }) if any(sum(point) == 0 for point in [left_eye, right_eye, nose]): return False mid_point = ((left_eye[0] + right_eye[0]) / 2, (left_eye[1] + right_eye[1]) / 2) eye_distance = math.sqrt((right_eye[0] - left_eye[0]) ** 2 + (right_eye[1] - left_eye[1]) ** 2) horizontal_offset = float(abs(nose[0] - mid_point[0]))
vertical_distance = float(abs(nose[1] - mid_point[1]))
is_symmetrical = horizontal_offset < 0.5 * eye_distance self.result.update({ 'horizontal_offset': float(horizontal_offset), 'eye_distance': float(eye_distance), 'symmetrical': float(horizontal_offset / eye_distance), 'is_symmetrical': bool(is_symmetrical) }) if eye_distance / image.shape[1] < 0.12: return False if self.debug: self._save_debug_image(image, 'symmetrical', f'{round(horizontal_offset / eye_distance, 2)}-{self.video.parent.name}_{self.video.stem}.png') if not is_symmetrical: logging.info(f'[{self.video.stem}] 鼻子不在中间范围.{horizontal_offset} < 0.2 * {eye_distance}') return False
reasonable_vertical_distance = 0.2 <= vertical_distance / eye_distance <= 1.5 self.result.update({ 'vertical_distance': float(vertical_distance), 'reasonable_vertical_distance': float(vertical_distance / eye_distance), 'is_reasonable_vertical_distance': bool(reasonable_vertical_distance) }) if self.debug: self._save_debug_image(image, 'reasonable', f'{round(vertical_distance / eye_distance, 2)}-{self.video.parent.name}_{self.video.stem}.png')
if np.sum(points[5:11].tolist()) == 0: logging.info(f'[{self.video.stem}] 没有上半身') return False return True
|