defect_service.py 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. import cv2
  2. import numpy as np
  3. from ..core.model_loader import get_predictor
  4. from app.utils.defect_inference.CardDefectAggregator import CardDefectAggregator
  5. from app.utils.defect_inference.arean_anylize_draw import DefectProcessor, DrawingParams
  6. from app.utils.defect_inference.AnalyzeCenter import analyze_centering_rotated, formate_center_data
  7. from app.utils.defect_inference.DrawCenterInfo import draw_boxes_and_center_info
  8. from app.utils.defect_inference.ClassifyEdgeCorner import ClassifyEdgeCorner
  9. from app.utils.json_data_formate import formate_face_data, formate_add_edit_type
  10. from app.core.config import settings
  11. from app.core.logger import get_logger
  12. import json
  13. logger = get_logger(__name__)
  14. class DefectInferenceService:
  15. def defect_inference(self, inference_type: str, img_bgr: np.ndarray,
  16. is_draw_image=True) -> dict:
  17. """
  18. 执行卡片识别推理。
  19. Args:
  20. inference_type: 模型类型 (e.g., 'outer_box').
  21. img_bgr: 图像。
  22. Returns:
  23. 一个包含推理结果的字典。
  24. """
  25. # 面
  26. if (inference_type == "pokemon_front_face_no_reflect_defect"
  27. or inference_type == "pokemon_front_face_reflect_defect"
  28. or inference_type == "pokemon_back_face_defect"):
  29. # 1. 获取对应的预测器实例
  30. predictor = get_predictor(inference_type)
  31. # 3. 调用我们新加的 predict_from_image 方法进行推理
  32. # result = predictor.predict_from_image(img_bgr)
  33. # 3. 实例化我们聚合器,传入预测器
  34. aggregator = CardDefectAggregator(
  35. predictor=predictor,
  36. tile_size=512,
  37. overlap_ratio=0.1, # 10% 重叠
  38. )
  39. json_data = aggregator.process_image(
  40. image=img_bgr,
  41. mode='face'
  42. )
  43. # merge_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-merge.json'
  44. # with open(merge_json_path, 'w', encoding='utf-8') as f:
  45. # json.dump(json_data, f, ensure_ascii=False, indent=4)
  46. # logger.info(f"合并结束")
  47. processor = DefectProcessor(pixel_resolution=settings.PIXEL_RESOLUTION)
  48. area_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-face_result.json'
  49. if is_draw_image:
  50. drawing_params_with_rect = DrawingParams(draw_min_rect=True)
  51. drawn_image, area_json = processor.analyze_and_draw(img_bgr, json_data,
  52. drawing_params_with_rect)
  53. temp_img_path = settings.TEMP_WORK_DIR / f'{inference_type}-face_result.jpg'
  54. cv2.imwrite(temp_img_path, drawn_image)
  55. else:
  56. area_json = processor.analyze_from_json(json_data)
  57. face_json_result = formate_face_data(area_json)
  58. face_json_result = formate_add_edit_type(face_json_result)
  59. with open(area_json_path, 'w', encoding='utf-8') as f:
  60. json.dump(face_json_result, f, ensure_ascii=False, indent=2)
  61. logger.info("面的面积计算结束")
  62. return face_json_result
  63. # 边角
  64. elif (inference_type == "pokemon_front_corner_no_reflect_defect"
  65. or inference_type == "pokemon_front_corner_reflect_defect"
  66. or inference_type == "pokemon_back_corner_defect"):
  67. predictor = get_predictor(inference_type)
  68. aggregator = CardDefectAggregator(
  69. predictor=predictor,
  70. tile_size=512,
  71. overlap_ratio=0.1, # 10% 重叠
  72. )
  73. json_data = aggregator.process_image(
  74. image=img_bgr,
  75. mode='edge'
  76. )
  77. # merge_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-merge.json'
  78. # with open(merge_json_path, 'w', encoding='utf-8') as f:
  79. # json.dump(json_data, f, ensure_ascii=False, indent=4)
  80. # logger.info(f"合并结束")
  81. processor = DefectProcessor(pixel_resolution=settings.PIXEL_RESOLUTION)
  82. area_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-corner_result.json'
  83. if is_draw_image:
  84. drawing_params_with_rect = DrawingParams(draw_min_rect=True)
  85. drawn_image, area_json = processor.analyze_and_draw(img_bgr, json_data,
  86. drawing_params_with_rect)
  87. temp_img_path = settings.TEMP_WORK_DIR / f'{inference_type}-corner_result.jpg'
  88. cv2.imwrite(temp_img_path, drawn_image)
  89. else:
  90. area_json: dict = processor.analyze_from_json(json_data)
  91. logger.info("边角缺陷面积计算结束")
  92. # 推理外框
  93. predictor_outer = get_predictor("outer_box")
  94. outer_result = predictor_outer.predict_from_image(img_bgr)
  95. classifier = ClassifyEdgeCorner(settings.PIXEL_RESOLUTION, settings.CORNER_SIZE_MM)
  96. edge_corner_data = classifier.classify_defects_location(area_json, outer_result)
  97. edge_corner_data = formate_add_edit_type(edge_corner_data)
  98. with open(area_json_path, 'w', encoding='utf-8') as f:
  99. json.dump(edge_corner_data, f, ensure_ascii=False, indent=2)
  100. logger.info("边角面积计算结束")
  101. return edge_corner_data
  102. elif inference_type == "pokemon_front_card_center" \
  103. or inference_type == "pokemon_back_card_center":
  104. predictor_inner = get_predictor(settings.DEFECT_TYPE[inference_type]['inner_box'])
  105. predictor_outer = get_predictor(settings.DEFECT_TYPE[inference_type]['outer_box'])
  106. inner_result = predictor_inner.predict_from_image(img_bgr)
  107. outer_result = predictor_outer.predict_from_image(img_bgr)
  108. # temp_inner_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-inner_result.json'
  109. # temp_outer_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-outer_result.json'
  110. # with open(temp_inner_json_path, 'w', encoding='utf-8') as f:
  111. # json.dump(inner_result, f, ensure_ascii=False, indent=4)
  112. # with open(temp_outer_json_path, 'w', encoding='utf-8') as f:
  113. # json.dump(outer_result, f, ensure_ascii=False, indent=4)
  114. inner_points = inner_result['shapes'][0]['points']
  115. outer_points = outer_result['shapes'][0]['points']
  116. center_result, inner_rect_box, outer_rect_box = analyze_centering_rotated(inner_points, outer_points)
  117. logger.info(f"inner_rect_box: {type(inner_rect_box)}, {inner_rect_box}")
  118. logger.info(f"outer_rect_box: , {outer_rect_box}")
  119. logger.info("格式化居中数据")
  120. center_result = formate_center_data(center_result,
  121. inner_result, outer_result,
  122. inner_rect_box, outer_rect_box)
  123. draw_img = draw_boxes_and_center_info(img_bgr, center_result)
  124. temp_center_img_path = settings.TEMP_WORK_DIR / f'{inference_type}-center_result.jpg'
  125. cv2.imwrite(temp_center_img_path, draw_img)
  126. temp_center_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-center_result.json'
  127. with open(temp_center_json_path, 'w', encoding='utf-8') as f:
  128. json.dump(center_result, f, ensure_ascii=False, indent=2)
  129. return center_result
  130. else:
  131. return {}
  132. # 创建一个单例服务
  133. # defect_service = DefectInferenceService()