Chinese_Chess_Recognition / core /chessboard_detector.py
yolo12138's picture
publish v1
37170d6
raw
history blame
4.83 kB
import time
import numpy as np
import cv2
from typing import List, Tuple, Union
from pandas import DataFrame
from .runonnx.rtmdet import RTMDET_ONNX
from .runonnx.rtmpose import RTMPOSE_ONNX
from .runonnx.full_classifier import FULL_CLASSIFIER_ONNX
from core.helper_34 import extract_chessboard
class ChessboardDetector:
def __init__(self,
det_model_path: str,
pose_model_path: str,
full_classifier_model_path: str = None
):
self.det = RTMDET_ONNX(
model_path=det_model_path,
)
self.pose = RTMPOSE_ONNX(
model_path=pose_model_path,
)
if full_classifier_model_path is not None:
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_detect_and_keypoints(self, image_bgr: Union[np.ndarray, None] = None) -> Tuple[List[int], float, List[List[int]], List[float]]:
xyxy, conf = self.det.pred(image_bgr)
# 预测关键点, 绘制关键点
keypoints, scores = self.pose.pred(image=image_bgr, bbox=xyxy)
return xyxy, conf, 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, None
image_rgb = image_rgb.copy()
original_image = image_rgb.copy()
image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
xyxy, conf, keypoints, scores = self.pred_detect_and_keypoints(image_bgr)
# 绘制棋盘框架
draw_image = self.det.draw_pred(image_rgb, xyxy, conf)
# 绘制关键点
draw_image = self.pose.draw_pred(img=draw_image, keypoints=keypoints, scores=scores)
# 融合 self.pose.bone_names 与 keypoints, 再转换成 DataFrame
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, [xyxy], keypoint_df
# 拉伸棋盘 detect board, 然后预测
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
# 检测棋盘 detect board
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()
start_time = time.time()
image_bgr = cv2.cvtColor(image_rgb, cv2.COLOR_RGB2BGR)
xyxy, conf, keypoints, scores = self.pred_detect_and_keypoints(image_bgr)
# 绘制棋盘框架
draw_image = self.det.draw_pred(image_rgb, xyxy, conf)
"""
绘制 原图关键点
"""
original_image_with_keypoints = self.pose.draw_pred(img=draw_image, keypoints=keypoints, scores=scores)
transformed_image, cells_labels, scores = self.extract_chessboard_and_classifier_layout(image_rgb=image_rgb_for_extract, keypoints=keypoints)
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