import cv2 from app.core.config import settings from app.core.logger import get_logger from app.services.defect_service import DefectInferenceService from app.services.card_rectify_and_center import CardRectifyAndCenter from app.utils.score_inference.CardScorer import CardScorer import numpy as np import json logger = get_logger(__name__) class ScoreService: def __init__(self): self.scoring_config_path = settings.SCORE_CONFIG_PATH self.card_scorer = CardScorer(config_path=self.scoring_config_path) self.defect_service = DefectInferenceService() self.rectify_center_service = CardRectifyAndCenter() def score_inference(self, score_type: str, is_reflect_card: bool, img_bgr: np.ndarray) -> dict: logger.info("开始进行卡片居中和转正") img_bgr = self.rectify_center_service.rectify_and_center(img_bgr) logger.info("开始进行卡片分数推理") if score_type == 'front_corner_edge' or score_type == 'front_face': center_data = self.defect_service.defect_inference("pokemon_front_card_center", img_bgr.copy()) else: center_data = self.defect_service.defect_inference("pokemon_back_card_center", img_bgr.copy()) if is_reflect_card: if score_type == 'front_corner_edge': defect_data = self.defect_service.defect_inference('pokemon_front_corner_reflect_defect', img_bgr.copy()) elif score_type == 'front_face': defect_data = self.defect_service.defect_inference('pokemon_front_face_reflect_defect', img_bgr.copy()) elif score_type == 'back_corner_edge': defect_data = self.defect_service.defect_inference('pokemon_back_corner_defect', img_bgr.copy()) elif score_type == 'back_face': defect_data = self.defect_service.defect_inference('pokemon_back_face_defect', img_bgr.copy()) else: return {} else: if score_type == 'front_corner_edge': defect_data = self.defect_service.defect_inference('pokemon_front_corner_no_reflect_defect', img_bgr.copy()) elif score_type == 'front_face': defect_data = self.defect_service.defect_inference('pokemon_front_face_no_reflect_defect', img_bgr.copy()) elif score_type == 'back_corner_edge': defect_data = self.defect_service.defect_inference('pokemon_back_corner_defect', img_bgr.copy()) elif score_type == 'back_face': defect_data = self.defect_service.defect_inference('pokemon_back_face_defect', img_bgr.copy()) else: return {} logger.info("模型推理结束, 开始计算分数") if score_type == 'front_corner_edge' or score_type == 'front_face': card_aspect = "front" else: card_aspect = "back" if score_type == 'front_corner_edge' or score_type == 'back_corner_edge': card_defect_type = "corner_edge" else: card_defect_type = "face" if card_defect_type == 'corner_edge': center_score_data = self.card_scorer.calculate_centering_score(card_aspect, center_data, True) # 先计算角的分数, 会把分数写入json, 然后传入刚写好的, 继续写边的分数 corner_score_data = self.card_scorer.calculate_defect_score('corner', card_aspect, defect_data, True) defect_score_data = self.card_scorer.calculate_defect_score('edge', card_aspect, corner_score_data, True) elif card_defect_type == 'face': center_score_data = {} defect_score_data = self.card_scorer.calculate_defect_score('face', card_aspect, defect_data, True) else: return {} result_json = self.card_scorer.formate_one_card_result(center_score_data, defect_score_data, card_defect_type=card_defect_type, card_aspect=card_aspect) temp_score_json_path = settings.TEMP_WORK_DIR / f'{score_type}_score.json' with open(temp_score_json_path, 'w', encoding='utf-8') as f: json.dump(result_json, f, ensure_ascii=False, indent=2) logger.info("分数推理完成 ") return result_json def recalculate_defect_score(self, score_type: str, json_data: dict): center_json_data = json_data["result"]['center_result'] defect_json_data = json_data["result"]['defect_result'] # 边角和面 类型分类 if score_type == 'front_corner_edge' or score_type == 'back_corner_edge': inference_type = "corner_edge" else: inference_type = "face" # 正反面类型分类 if score_type == 'front_corner_edge' or score_type == 'front_face': card_aspect = "front" else: card_aspect = "back" logger.info("开始进行缺陷信息重计算") defect_data = self.defect_service.re_inference_from_json(inference_type=inference_type, center_json=center_json_data, defect_json=defect_json_data) logger.info("开始重新计算分数") if inference_type == 'corner_edge': logger.info("开始进行居中信息重计算") center_data = self.defect_service.re_inference_from_json(inference_type="center", center_json=center_json_data, defect_json=defect_json_data) center_score_data = self.card_scorer.calculate_centering_score(card_aspect, center_data, True) # 先计算角的分数, 会把分数写入json, 然后传入刚写好的, 继续写边的分数 corner_score_data = self.card_scorer.calculate_defect_score('corner', card_aspect, defect_data, True) defect_score_data = self.card_scorer.calculate_defect_score('edge', card_aspect, corner_score_data, True) elif inference_type == 'face': # 面类型不计算居中 center_score_data = {} defect_score_data = self.card_scorer.calculate_defect_score('face', card_aspect, defect_data, True) else: return {} result_json = self.card_scorer.formate_one_card_result(center_score_data, defect_score_data, card_defect_type=inference_type, card_aspect=card_aspect) temp_score_json_path = settings.TEMP_WORK_DIR / f're_{score_type}_score.json' with open(temp_score_json_path, 'w', encoding='utf-8') as f: json.dump(result_json, f, ensure_ascii=False, indent=2) logger.info("分数推理完成 ") return result_json