| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- 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:
- # 解包返回值,获取转正后的外框数据
- img_bgr, transformed_outer_json = self.rectify_center_service.rectify_and_center(img_bgr)
- if img_bgr is None:
- raise ValueError("图像转正处理失败")
- imageHeight, imageWidth = img_bgr.shape[:2]
- logger.info("开始进行卡片分数推理, 使用变换后的外框")
- # 定义通用参数,传入 pre_calculated_outer_result
- defect_kwargs = {
- "img_bgr": img_bgr.copy(),
- "pre_calculated_outer_result": transformed_outer_json
- }
- if score_type == 'front_ring' or score_type == 'front_coaxial':
- center_data = self.defect_service.defect_inference("pokemon_front_card_center", **defect_kwargs)
- else:
- center_data = self.defect_service.defect_inference("pokemon_back_card_center", **defect_kwargs)
- if is_reflect_card:
- if score_type == 'front_ring':
- defect_data = self.defect_service.defect_inference('pokemon_front_face_reflect_ring_light_defect',
- **defect_kwargs)
- elif score_type == 'front_coaxial':
- defect_data = self.defect_service.defect_inference('pokemon_front_face_reflect_coaxial_light_defect',
- **defect_kwargs)
- elif score_type == 'back_ring':
- defect_data = self.defect_service.defect_inference('pokemon_back_face_ring_light_defect',
- **defect_kwargs)
- elif score_type == 'back_coaxial':
- defect_data = self.defect_service.defect_inference('pokemon_back_face_coaxial_light_defect',
- **defect_kwargs)
- else:
- return {}
- else:
- if score_type == 'front_ring':
- defect_data = self.defect_service.defect_inference('pokemon_front_face_no_reflect_ring_light_defect',
- **defect_kwargs)
- elif score_type == 'front_coaxial':
- defect_data = self.defect_service.defect_inference('pokemon_front_face_no_reflect_coaxial_light_defect',
- **defect_kwargs)
- elif score_type == 'back_ring':
- defect_data = self.defect_service.defect_inference('pokemon_back_face_ring_light_defect',
- **defect_kwargs)
- elif score_type == 'back_coaxial':
- defect_data = self.defect_service.defect_inference('pokemon_back_face_coaxial_light_defect',
- **defect_kwargs)
- else:
- return {}
- logger.info("模型推理结束, 开始计算分数")
- if score_type == 'front_ring' or score_type == 'front_coaxial':
- card_aspect = "front"
- else:
- card_aspect = "back"
- if score_type == 'front_ring' or score_type == 'back_ring':
- card_light_type = "ring"
- else:
- card_light_type = "coaxial"
- if card_light_type == 'ring':
- center_score_data = self.card_scorer.calculate_centering_score(card_aspect, center_data, True)
- # 计算角, 边, 面的分数, 会把分数写入json, 然后传入刚写好的, 继续写边的分数
- defect_data = self.card_scorer.calculate_defect_score('corner', card_aspect, card_light_type,
- defect_data, True)
- defect_data = self.card_scorer.calculate_defect_score('edge', card_aspect, card_light_type,
- defect_data, True)
- defect_score_data = self.card_scorer.calculate_defect_score('face', card_aspect, card_light_type,
- defect_data, True)
- elif card_light_type == 'coaxial':
- # 居中
- center_score_data = {}
- # 同轴光照片只计算面缺陷
- defect_score_data = self.card_scorer.calculate_defect_score('face', card_aspect, card_light_type,
- defect_data, True)
- else:
- return {}
- result_json = self.card_scorer.formate_one_card_result(center_score_data, defect_score_data,
- card_light_type=card_light_type,
- card_aspect=card_aspect,
- imageHeight=imageHeight,
- imageWidth=imageWidth)
- 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']
- imageHeight = json_data["result"].get('imageHeight', 0)
- imageWidth = json_data["result"].get('imageWidth', 0)
- # 正反面类型分类
- if score_type == 'front_ring' or score_type == 'front_coaxial':
- card_aspect = "front"
- else:
- card_aspect = "back"
- if score_type == 'front_ring' or score_type == 'back_ring':
- card_light_type = "ring"
- else:
- card_light_type = "coaxial"
- logger.info("开始进行缺陷信息重计算")
- defect_data = self.defect_service.re_inference_from_json(card_light_type=card_light_type,
- center_json=center_json_data,
- defect_json=defect_json_data)
- logger.info("开始重新计算分数")
- if card_light_type == 'ring':
- logger.info("开始进行居中信息重计算")
- center_data = self.defect_service.re_inference_from_json(card_light_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, 然后传入刚写好的, 继续写边的分数
- logger.info("开始重新计算:边角面")
- defect_data = self.card_scorer.calculate_defect_score('corner', card_aspect, card_light_type,
- defect_data, True)
- defect_data = self.card_scorer.calculate_defect_score('edge', card_aspect, card_light_type,
- defect_data, True)
- defect_score_data = self.card_scorer.calculate_defect_score('face', card_aspect, card_light_type,
- defect_data, True)
- elif card_light_type == 'coaxial':
- # 居中
- center_score_data = {}
- # 同轴光照片只计算面缺陷
- logger.info("开始重新计算:面")
- defect_score_data = self.card_scorer.calculate_defect_score('face', card_aspect, card_light_type,
- defect_data, True)
- else:
- return {}
- result_json = self.card_scorer.formate_one_card_result(center_score_data, defect_score_data,
- card_light_type=card_light_type,
- card_aspect=card_aspect,
- imageHeight=imageHeight,
- imageWidth=imageWidth)
- 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
|