|
|
| import time |
| import numpy as np |
| import cv2 |
| from typing import List, Tuple, Union |
| from pandas import DataFrame |
| from .runonnx.rtmpose import RTMPOSE_ONNX |
| from .runonnx.full_classifier import FULL_CLASSIFIER_ONNX |
|
|
| from core.helper_4_kpt import extract_chessboard |
|
|
| class ChessboardDetector: |
| def __init__(self, |
| pose_model_path: str, |
| full_classifier_model_path: str = None |
| ): |
|
|
| self.pose = RTMPOSE_ONNX( |
| model_path=pose_model_path, |
| ) |
|
|
| self.full_classifier = FULL_CLASSIFIER_ONNX( |
| model_path=full_classifier_model_path, |
| ) |
|
|
| self.board_positions = [] |
| self.current_image = None |
| self.current_filename = None |
| |
|
|
| |
| def pred_keypoints(self, image_bgr: Union[np.ndarray, None] = None) -> Tuple[List[List[int]], List[float]]: |
|
|
| |
|
|
| width, height = image_bgr.shape[:2] |
| bbox = [0, 0, width, height] |
|
|
| keypoints, scores = self.pose.pred(image=image_bgr, bbox=bbox) |
|
|
| return keypoints, scores |
| |
|
|
| def draw_pred_with_keypoints(self, image_rgb: Union[np.ndarray, None] = None) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: |
| if image_rgb is None: |
| return None, None, None |
| |
| image_rgb = image_rgb.copy() |
|
|
| original_image = image_rgb.copy() |
|
|
| image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR) |
|
|
| keypoints, scores = self.pred_keypoints(image_bgr) |
|
|
| |
| draw_image = self.pose.draw_pred(img=image_rgb, keypoints=keypoints, scores=scores) |
|
|
| |
| keypoint_list = [] |
| for bone_name, keypoint in zip(self.pose.bone_names, keypoints): |
| keypoint_list.append({"name": bone_name, "x": keypoint[0], "y": keypoint[1]}) |
|
|
| keypoint_df = DataFrame(keypoint_list) |
|
|
| return draw_image, original_image, keypoint_df |
|
|
| |
| def extract_chessboard_and_classifier_layout(self, |
| image_rgb: Union[np.ndarray, None] = None, |
| keypoints: Union[np.ndarray, None] = None |
| ) -> Tuple[np.ndarray, List[List[str]], List[List[float]]]: |
| |
| |
| transformed_image, _transformed_keypoints, _corner_points = extract_chessboard(img=image_rgb, keypoints=keypoints) |
|
|
| transformed_image_copy = transformed_image.copy() |
| |
| |
| _, _, scores, pred_result = self.full_classifier.pred(transformed_image_copy, is_rgb=True) |
|
|
|
|
| return transformed_image, pred_result, scores |
|
|
|
|
| |
| def pred_detect_board_and_classifier(self, |
| image_rgb: Union[np.ndarray, None] = None, |
| ) -> Tuple[np.ndarray, np.ndarray, str, List[List[float]], str]: |
|
|
| """ |
| @param image_rgb: 输入的 RGB 图像 |
| @return: |
| - transformed_image_layout # 拉伸棋盘 |
| - original_image_with_keypoints # 原图关键点 |
| - layout_pred_info # 每个位置的 棋子类别 |
| - scores # 每个位置的 置信度 |
| - time_info # 推理用时 |
| """ |
|
|
| if image_rgb is None: |
| return None, None, [], [], "" |
| |
| image_rgb_for_extract = image_rgb.copy() |
| image_rgb_for_draw = image_rgb.copy() |
| |
| start_time = time.time() |
|
|
| try: |
| image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR) |
|
|
| keypoints, scores = self.pred_keypoints(image_bgr) |
|
|
| """ |
| 绘制 原图关键点 |
| """ |
| original_image_with_keypoints = self.pose.draw_pred(img=image_rgb_for_draw, keypoints=keypoints, scores=scores) |
|
|
| transformed_image, cells_labels, scores = self.extract_chessboard_and_classifier_layout(image_rgb=image_rgb_for_extract, keypoints=keypoints) |
| except Exception as e: |
| print("检测棋盘失败", e) |
| return None, None, None, None, "" |
|
|
|
|
| use_time = time.time() - start_time |
|
|
| time_info = f"推理用时: {use_time:.2f}s" |
|
|
| return original_image_with_keypoints, transformed_image, cells_labels, scores, time_info |
| |