| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161 |
- from app.utils.scheme import ImageType, CardImageResponse
- from app.core.logger import get_logger
- from typing import List, Dict, Any, Optional
- logger = get_logger(__name__)
- def calculate_scores_from_images(images: List[CardImageResponse]) -> Dict[str, Any]:
- """
- 根据图片计算分数(兼容 14 图与历史 8 图)。
- - 必要条件:front_ring + back_ring 存在
- - face 分数来源:同面 stripe(1~4) / coaxial / fusion,按可用图累加
- - 不再依赖 coaxial 必须存在
- """
- scores = {
- "detection_score": None,
- "modified_score": None,
- "detection_score_detail": {
- "detection_center_score": None,
- "detection_corner_score": None,
- "detection_edge_score": None,
- "detection_face_score": None
- },
- "modified_score_detail": {
- "modified_center_score": None,
- "modified_corner_score": None,
- "modified_edge_score": None,
- "modified_face_score": None
- },
- "is_edited": False,
- }
- def _as_float(value: Any) -> float:
- try:
- return float(value or 0)
- except (TypeError, ValueError):
- return 0.0
- def _get_reducts(src: Dict[str, Any], side: str) -> Dict[str, float]:
- defect_result = src.get("result", {}).get("defect_result", {})
- center_result = src.get("result", {}).get("center_result", {})
- return {
- "total": _as_float(src.get("result", {}).get("_used_compute_deduct_score", 0)),
- "center": _as_float(center_result.get("deduct_score", 0)),
- "corner": _as_float(defect_result.get(f"{side}_corner_deduct_score", 0)),
- "edge": _as_float(defect_result.get(f"{side}_edge_deduct_score", 0)),
- "face": _as_float(defect_result.get(f"{side}_face_deduct_score", 0)),
- }
- front_ring: Optional[CardImageResponse] = None
- back_ring: Optional[CardImageResponse] = None
- front_face_imgs: List[CardImageResponse] = []
- back_face_imgs: List[CardImageResponse] = []
- for img in images:
- image_type = img.image_type
- if image_type == ImageType.front_ring:
- front_ring = img
- elif image_type == ImageType.back_ring:
- back_ring = img
- if image_type in [
- ImageType.front_stripe1, ImageType.front_stripe2,
- ImageType.front_stripe3, ImageType.front_stripe4,
- ImageType.front_coaxial, ImageType.front_fusion,
- ]:
- front_face_imgs.append(img)
- elif image_type in [
- ImageType.back_stripe1, ImageType.back_stripe2,
- ImageType.back_stripe3, ImageType.back_stripe4,
- ImageType.back_coaxial, ImageType.back_fusion,
- ]:
- back_face_imgs.append(img)
- # ring 是当前模型计算中心/角/边的必要数据
- if not front_ring or not back_ring:
- return scores
- try:
- # ---------- detection_score ----------
- detection_score = 10.0
- detection_center_score = 10.0
- detection_corner_score = 10.0
- detection_edge_score = 10.0
- detection_face_score = 10.0
- for ring_img, side in ((front_ring, "front"), (back_ring, "back")):
- try:
- reducts = _get_reducts(ring_img.detection_json or {}, side)
- detection_score += reducts["total"]
- detection_center_score += reducts["center"]
- detection_corner_score += reducts["corner"]
- detection_edge_score += reducts["edge"]
- detection_face_score += reducts["face"]
- except Exception as e:
- logger.warning(f"解析 detection_json 分数失败 (image_id={ring_img.id}): {e}")
- # 同面 face 辅助图(stripe/coaxial/fusion)叠加 face 与 total
- for side, face_imgs in (("front", front_face_imgs), ("back", back_face_imgs)):
- for img in face_imgs:
- try:
- reducts = _get_reducts(img.detection_json or {}, side)
- detection_score += reducts["total"]
- detection_face_score += reducts["face"]
- except Exception as e:
- logger.warning(f"解析 detection_json 分数失败 (image_id={img.id}): {e}")
- scores["detection_score"] = detection_score
- scores["detection_score_detail"] = {
- "detection_center_score": detection_center_score,
- "detection_corner_score": detection_corner_score,
- "detection_edge_score": detection_edge_score,
- "detection_face_score": detection_face_score,
- }
- # ---------- modified_score ----------
- modified_score = 10.0
- modified_center_score = 10.0
- modified_corner_score = 10.0
- modified_edge_score = 10.0
- modified_face_score = 10.0
- all_score_images = [front_ring, back_ring] + front_face_imgs + back_face_imgs
- is_edited = any(img.modified_json is not None for img in all_score_images if img is not None)
- scores["is_edited"] = is_edited
- if is_edited:
- for ring_img, side in ((front_ring, "front"), (back_ring, "back")):
- src = ring_img.modified_json if ring_img.modified_json is not None else ring_img.detection_json
- try:
- reducts = _get_reducts(src or {}, side)
- modified_score += reducts["total"]
- modified_center_score += reducts["center"]
- modified_corner_score += reducts["corner"]
- modified_edge_score += reducts["edge"]
- modified_face_score += reducts["face"]
- except Exception as e:
- logger.warning(f"解析 modified_json 分数失败 (image_id={ring_img.id}): {e}")
- for side, face_imgs in (("front", front_face_imgs), ("back", back_face_imgs)):
- for img in face_imgs:
- src = img.modified_json if img.modified_json is not None else img.detection_json
- try:
- reducts = _get_reducts(src or {}, side)
- modified_score += reducts["total"]
- modified_face_score += reducts["face"]
- except Exception as e:
- logger.warning(f"解析 modified_json 分数失败 (image_id={img.id}): {e}")
- scores["modified_score"] = modified_score
- scores["modified_score_detail"] = {
- "modified_center_score": modified_center_score,
- "modified_corner_score": modified_corner_score,
- "modified_edge_score": modified_edge_score,
- "modified_face_score": modified_face_score,
- }
- except Exception as e:
- logger.error(f"计算分数过程异常: {e}")
- return scores
|