|
@@ -38,13 +38,15 @@ class DefectInferenceService:
|
|
|
return json_data
|
|
return json_data
|
|
|
|
|
|
|
|
def defect_inference(self, inference_type: str, img_bgr: np.ndarray,
|
|
def defect_inference(self, inference_type: str, img_bgr: np.ndarray,
|
|
|
- is_draw_image=True) -> dict:
|
|
|
|
|
|
|
+ is_draw_image=True,
|
|
|
|
|
+ pre_calculated_outer_result: dict = None) -> dict:
|
|
|
"""
|
|
"""
|
|
|
执行卡片识别推理。
|
|
执行卡片识别推理。
|
|
|
|
|
|
|
|
Args:
|
|
Args:
|
|
|
inference_type: 模型类型 (e.g., 'outer_box').
|
|
inference_type: 模型类型 (e.g., 'outer_box').
|
|
|
img_bgr: 图像。
|
|
img_bgr: 图像。
|
|
|
|
|
+ pre_calculated_outer_result: 如果提供了转正后的外框数据,则不再重新推理外框
|
|
|
|
|
|
|
|
Returns:
|
|
Returns:
|
|
|
一个包含推理结果的字典。
|
|
一个包含推理结果的字典。
|
|
@@ -52,6 +54,20 @@ class DefectInferenceService:
|
|
|
simplifyPoints = SimplifyPoints()
|
|
simplifyPoints = SimplifyPoints()
|
|
|
outside_filter = FilterOutsideDefects(expansion_pixel=30)
|
|
outside_filter = FilterOutsideDefects(expansion_pixel=30)
|
|
|
|
|
|
|
|
|
|
+ # 辅助函数:获取外框结果(优先使用传入的,否则现场推理)
|
|
|
|
|
+ def get_outer_result(tag=""):
|
|
|
|
|
+ if pre_calculated_outer_result:
|
|
|
|
|
+ logger.info(f"[{tag}] 使用预计算的转正外框数据")
|
|
|
|
|
+ return pre_calculated_outer_result
|
|
|
|
|
+ else:
|
|
|
|
|
+ logger.info(f"[{tag}] 未提供外框数据,开始推理外框...")
|
|
|
|
|
+ p_outer = get_predictor("outer_box")
|
|
|
|
|
+ res = p_outer.predict_from_image(img_bgr)
|
|
|
|
|
+ # 如果是现场推理的,需要过滤一下
|
|
|
|
|
+ if inference_type in ["pokemon_front_card_center", "pokemon_back_card_center"]:
|
|
|
|
|
+ res = self._filter_max_prob_shape(res, tag=f"{tag}-过滤")
|
|
|
|
|
+ return res
|
|
|
|
|
+
|
|
|
# 面
|
|
# 面
|
|
|
if (inference_type == "pokemon_back_face_coaxial_light_defect"
|
|
if (inference_type == "pokemon_back_face_coaxial_light_defect"
|
|
|
or inference_type == "pokemon_front_face_reflect_coaxial_light_defect"
|
|
or inference_type == "pokemon_front_face_reflect_coaxial_light_defect"
|
|
@@ -77,18 +93,14 @@ class DefectInferenceService:
|
|
|
# 简化点数
|
|
# 简化点数
|
|
|
logger.info("开始简化点数")
|
|
logger.info("开始简化点数")
|
|
|
for shapes in json_data["shapes"]:
|
|
for shapes in json_data["shapes"]:
|
|
|
- points = shapes["points"]
|
|
|
|
|
|
|
+ shapes["points"] = simplifyPoints.simplify_points(shapes["points"])
|
|
|
# num1 = len(points)
|
|
# num1 = len(points)
|
|
|
- simplify_points = simplifyPoints.simplify_points(points)
|
|
|
|
|
- shapes["points"] = simplify_points
|
|
|
|
|
- # new_num1 = len(simplify_points)
|
|
|
|
|
# logger.info(f"num: {num1}, new_num1: {new_num1}")
|
|
# logger.info(f"num: {num1}, new_num1: {new_num1}")
|
|
|
|
|
|
|
|
logger.info("开始执行外框过滤...")
|
|
logger.info("开始执行外框过滤...")
|
|
|
try:
|
|
try:
|
|
|
- # 1. 因为面原本没有外框推理,这里需要专门加载并推理一次
|
|
|
|
|
- predictor_outer = get_predictor("outer_box")
|
|
|
|
|
- outer_result = predictor_outer.predict_from_image(img_bgr)
|
|
|
|
|
|
|
+ # 获取外框
|
|
|
|
|
+ outer_result = get_outer_result(tag="面流程")
|
|
|
|
|
|
|
|
# 2. 执行过滤
|
|
# 2. 执行过滤
|
|
|
json_data = outside_filter.execute(json_data, outer_result)
|
|
json_data = outside_filter.execute(json_data, outer_result)
|
|
@@ -120,7 +132,7 @@ class DefectInferenceService:
|
|
|
|
|
|
|
|
return face_json_result
|
|
return face_json_result
|
|
|
|
|
|
|
|
- # 存在边角判断的情况
|
|
|
|
|
|
|
+ # 边角
|
|
|
elif (inference_type == "pokemon_back_face_ring_light_defect"
|
|
elif (inference_type == "pokemon_back_face_ring_light_defect"
|
|
|
or inference_type == "pokemon_front_face_reflect_ring_light_defect"
|
|
or inference_type == "pokemon_front_face_reflect_ring_light_defect"
|
|
|
or inference_type == "pokemon_front_face_no_reflect_ring_light_defect"):
|
|
or inference_type == "pokemon_front_face_no_reflect_ring_light_defect"):
|
|
@@ -140,13 +152,7 @@ class DefectInferenceService:
|
|
|
# 简化点数
|
|
# 简化点数
|
|
|
logger.info("开始进行点数简化")
|
|
logger.info("开始进行点数简化")
|
|
|
for shapes in json_data["shapes"]:
|
|
for shapes in json_data["shapes"]:
|
|
|
- points = shapes["points"]
|
|
|
|
|
- num1 = len(points)
|
|
|
|
|
- simplify_points = simplifyPoints.simplify_points(points)
|
|
|
|
|
- shapes["points"] = simplify_points
|
|
|
|
|
- new_num1 = len(simplify_points)
|
|
|
|
|
- # logger.info(f"num: {num1}, new_num1: {new_num1}")
|
|
|
|
|
- logger.info("点数简化结束")
|
|
|
|
|
|
|
+ shapes["points"] = simplifyPoints.simplify_points(shapes["points"])
|
|
|
|
|
|
|
|
# merge_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-merge.json'
|
|
# merge_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-merge.json'
|
|
|
# with open(merge_json_path, 'w', encoding='utf-8') as f:
|
|
# with open(merge_json_path, 'w', encoding='utf-8') as f:
|
|
@@ -155,11 +161,11 @@ class DefectInferenceService:
|
|
|
|
|
|
|
|
logger.info("开始执行外框过滤...")
|
|
logger.info("开始执行外框过滤...")
|
|
|
# 外框推理
|
|
# 外框推理
|
|
|
- predictor_outer = get_predictor("outer_box")
|
|
|
|
|
- outer_result = predictor_outer.predict_from_image(img_bgr)
|
|
|
|
|
|
|
+ outer_result = get_outer_result(tag="Corner流程")
|
|
|
|
|
|
|
|
# 过滤外框,只留一个
|
|
# 过滤外框,只留一个
|
|
|
- outer_result = self._filter_max_prob_shape(outer_result, tag="Corner流程-外框")
|
|
|
|
|
|
|
+ if not pre_calculated_outer_result:
|
|
|
|
|
+ outer_result = self._filter_max_prob_shape(outer_result, tag="Corner流程-外框")
|
|
|
|
|
|
|
|
# 2. 执行过滤, 去掉外框外的缺陷
|
|
# 2. 执行过滤, 去掉外框外的缺陷
|
|
|
json_data = outside_filter.execute(json_data, outer_result)
|
|
json_data = outside_filter.execute(json_data, outer_result)
|
|
@@ -188,25 +194,21 @@ class DefectInferenceService:
|
|
|
|
|
|
|
|
return edge_corner_data
|
|
return edge_corner_data
|
|
|
|
|
|
|
|
|
|
+ # 居中
|
|
|
elif inference_type == "pokemon_front_card_center" \
|
|
elif inference_type == "pokemon_front_card_center" \
|
|
|
or inference_type == "pokemon_back_card_center":
|
|
or inference_type == "pokemon_back_card_center":
|
|
|
|
|
|
|
|
predictor_inner = get_predictor(settings.DEFECT_TYPE[inference_type]['inner_box'])
|
|
predictor_inner = get_predictor(settings.DEFECT_TYPE[inference_type]['inner_box'])
|
|
|
- predictor_outer = get_predictor(settings.DEFECT_TYPE[inference_type]['outer_box'])
|
|
|
|
|
|
|
+ # predictor_outer = get_predictor(settings.DEFECT_TYPE[inference_type]['outer_box'])
|
|
|
|
|
|
|
|
inner_result = predictor_inner.predict_from_image(img_bgr)
|
|
inner_result = predictor_inner.predict_from_image(img_bgr)
|
|
|
- outer_result = predictor_outer.predict_from_image(img_bgr)
|
|
|
|
|
|
|
+ outer_result = get_outer_result(tag="Center流程")
|
|
|
|
|
|
|
|
# 过滤内框和外框,只留最大置信度的框
|
|
# 过滤内框和外框,只留最大置信度的框
|
|
|
inner_result = self._filter_max_prob_shape(inner_result, tag="Center流程-内框")
|
|
inner_result = self._filter_max_prob_shape(inner_result, tag="Center流程-内框")
|
|
|
- outer_result = self._filter_max_prob_shape(outer_result, tag="Center流程-外框")
|
|
|
|
|
-
|
|
|
|
|
- # temp_inner_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-inner_result.json'
|
|
|
|
|
- # temp_outer_json_path = settings.TEMP_WORK_DIR / f'{inference_type}-outer_result.json'
|
|
|
|
|
- # with open(temp_inner_json_path, 'w', encoding='utf-8') as f:
|
|
|
|
|
- # json.dump(inner_result, f, ensure_ascii=False, indent=4)
|
|
|
|
|
- # with open(temp_outer_json_path, 'w', encoding='utf-8') as f:
|
|
|
|
|
- # json.dump(outer_result, f, ensure_ascii=False, indent=4)
|
|
|
|
|
|
|
+ # 如果是传入的预计算结果,它已经过滤过了;如果是现算的,需要过滤
|
|
|
|
|
+ if not pre_calculated_outer_result:
|
|
|
|
|
+ outer_result = self._filter_max_prob_shape(outer_result, tag="Center流程-外框")
|
|
|
|
|
|
|
|
inner_points = inner_result['shapes'][0]['points']
|
|
inner_points = inner_result['shapes'][0]['points']
|
|
|
outer_points = outer_result['shapes'][0]['points']
|
|
outer_points = outer_result['shapes'][0]['points']
|