Skip to content

Commit dad00c1

Browse files
committed
update pre-check function
1 parent ba5037c commit dad00c1

2 files changed

Lines changed: 80 additions & 55 deletions

File tree

evaluation_function/evaluation.py

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -36,16 +36,14 @@
3636
"fail": "Some parts could not be detected clearly. Please separate the parts and retake the photo.",
3737
},
3838
"precheck": {
39-
"pass": "Good. The detected setup is consistent. You can proceed.",
40-
"count_rule_fail": (
41-
"The detected numbers of gears and gear-contact regions are not consistent. "
42-
"Please make sure all gears and contact regions are clearly visible, then retake the photo."
39+
"report": (
40+
"Photo quality reference values:\n"
41+
"- brightness: {brightness_mean}\n"
42+
"- contrast: {contrast_std}\n"
43+
"- sharpness: {sharpness_score}\n"
44+
"- lighting uniformity: {illumination_nonuniformity}\n"
45+
"These values are provided as reference only and do not determine whether the assembly is correct."
4346
),
44-
"big_small_inconsistent": (
45-
"The detected numbers of big gears and small gears are not consistent. "
46-
"Please make sure all gears are clearly visible, then retake the photo."
47-
),
48-
"fail": "Please retake the photo. The detected setup is not consistent enough for reliable checking.",
4947
},
5048
"single_stage": {
5149
"pass": (
@@ -125,9 +123,17 @@
125123
"- driving gear: {driving_gear}\n"
126124
"- small gear: {smallgear}\n"
127125
"- big gear: {biggear}\n"
128-
"The detected gears and contact regions are not consistent enough for reliable checking. "
129-
"Please make sure only the intended gears are visible, that meshing areas can be seen clearly, "
130-
"and then retake the photo."
126+
"The system cannot reliably evaluate the gear meshing due to unclear or inconsistent detection results. "
127+
"Please ensure that only the required gears are visible in the image, and that the gear meshing areas "
128+
"are clearly shown before retaking the photo."
129+
),
130+
"big_small_inconsistent": (
131+
"Detected gears:\n"
132+
"- driving gear: {driving_gear}\n"
133+
"- small gear: {smallgear}\n"
134+
"- big gear: {biggear}\n"
135+
"The detected numbers of big gears and small gears are not consistent. "
136+
"Please check the gear setup and retake the photo."
131137
),
132138
"mismatch_fail": (
133139
"Detected gears:\n"
@@ -299,6 +305,7 @@ def keep(e: Dict[str, Any]) -> bool:
299305
"E_NO_GEARS",
300306
"E_MESH_MISMATCH",
301307
"E_GEAR_CONTACT_INCONSISTENT",
308+
"E_GEAR_BIG_SMALL_INCONSISTENT",
302309
}
303310

304311
if task == "mesh_ratio":
@@ -513,25 +520,20 @@ def _build_student_message(
513520
task_has_error = _has_selected_pipeline_error(selected_errors)
514521

515522
if task == "precheck":
516-
codes = {
517-
str(e.get("code", "")).upper()
518-
for e in selected_errors
519-
if isinstance(e, dict)
520-
}
521-
522-
if "E_NO_GEARS" in codes:
523-
return False, MESSAGE_POLICY["precheck"]["fail"]
524-
525-
if "E_PRECHECK_BIG_SMALL_INCONSISTENT" in codes:
526-
return False, MESSAGE_POLICY["precheck"]["big_small_inconsistent"]
527-
528-
if "E_PRECHECK_COUNT_RULE_FAIL" in codes:
529-
return False, MESSAGE_POLICY["precheck"]["count_rule_fail"]
530-
531-
if task_has_error:
532-
return False, MESSAGE_POLICY["precheck"]["fail"]
533-
534-
return True, MESSAGE_POLICY["precheck"]["pass"]
523+
quality = out.get("quality", {}) if isinstance(out.get("quality"), dict) else {}
524+
525+
def qfmt(key: str) -> str:
526+
try:
527+
return f"{float(quality.get(key, 0.0)):.2f}"
528+
except Exception:
529+
return str(quality.get(key, "N/A"))
530+
531+
return True, MESSAGE_POLICY["precheck"]["report"].format(
532+
brightness_mean=qfmt("brightness_mean"),
533+
contrast_std=qfmt("contrast_std"),
534+
sharpness_score=qfmt("sharpness_score"),
535+
illumination_nonuniformity=qfmt("illumination_nonuniformity"),
536+
)
535537

536538
if task == "single_stage":
537539
codes = {
@@ -721,6 +723,13 @@ def _build_student_message(
721723
biggear=biggear,
722724
)
723725

726+
if "E_GEAR_BIG_SMALL_INCONSISTENT" in codes:
727+
return False, MESSAGE_POLICY["gear_inventory"]["big_small_inconsistent"].format(
728+
driving_gear=driving_gear,
729+
smallgear=smallgear,
730+
biggear=biggear,
731+
)
732+
724733
if "E_GEAR_CONTACT_INCONSISTENT" in codes:
725734
return False, MESSAGE_POLICY["gear_inventory"]["contact_consistency_fail"].format(
726735
driving_gear=driving_gear,

evaluation_function/yolo_pipeline.py

Lines changed: 40 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -711,25 +711,33 @@ def get_spacer_counts(spacers: List[Dict[str, Any]]) -> Dict[str, int]:
711711
# =========================
712712
# Precheck helpers
713713
# =========================
714-
def evaluate_precheck_consistency(
715-
gears: List[Dict[str, Any]],
716-
mesh_boxes: List[Tuple[float, float, float, float]],
717-
mismesh_boxes: List[Tuple[float, float, float, float]],
718-
) -> Tuple[List[Dict[str, str]], Dict[str, int]]:
719-
errs: List[Dict[str, str]] = []
720-
721-
counts = get_gear_counts(gears)
722-
723-
if counts["biggear"] != counts["smallgear"]:
724-
errs.append({
725-
"code": "E_PRECHECK_BIG_SMALL_INCONSISTENT",
726-
"message": (
727-
f"Precheck failed: biggear={counts['biggear']} and smallgear={counts['smallgear']} "
728-
f"are not consistent."
729-
),
730-
})
714+
def compute_image_quality_metrics(img_bgr: np.ndarray) -> Dict[str, float]:
715+
gray = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2GRAY)
716+
717+
brightness_mean = float(np.mean(gray))
718+
contrast_std = float(np.std(gray))
719+
sharpness_score = float(cv2.Laplacian(gray, cv2.CV_64F).var())
720+
721+
h, w = gray.shape
722+
block_means: List[float] = []
723+
for r in range(4):
724+
for c in range(4):
725+
y0 = int(r * h / 4)
726+
y1 = int((r + 1) * h / 4)
727+
x0 = int(c * w / 4)
728+
x1 = int((c + 1) * w / 4)
729+
patch = gray[y0:y1, x0:x1]
730+
if patch.size > 0:
731+
block_means.append(float(np.mean(patch)))
732+
733+
illumination_nonuniformity = float(np.std(block_means)) if block_means else 0.0
731734

732-
return errs, counts
735+
return {
736+
"brightness_mean": brightness_mean,
737+
"contrast_std": contrast_std,
738+
"sharpness_score": sharpness_score,
739+
"illumination_nonuniformity": illumination_nonuniformity,
740+
}
733741

734742

735743
# =========================
@@ -839,6 +847,15 @@ def evaluate_gear_inventory_step(
839847
})
840848
return errs, counts
841849

850+
if counts["biggear"] != counts["smallgear"]:
851+
errs.append({
852+
"code": "E_GEAR_BIG_SMALL_INCONSISTENT",
853+
"message": (
854+
f"Gear inventory check failed: biggear={counts['biggear']} and "
855+
f"smallgear={counts['smallgear']} are not consistent."
856+
),
857+
})
858+
842859
total_contact = len(mesh_boxes) + len(mismesh_boxes)
843860
gear_count = len(gears)
844861
expected_contact, ok = expected_contact_boxes_from_gear_count(gear_count)
@@ -2095,11 +2112,9 @@ def _need_shafts() -> bool:
20952112

20962113
# --- task: precheck ---
20972114
if task == TASK_PRECHECK:
2098-
errors, counts = evaluate_precheck_consistency(
2099-
gears=gears,
2100-
mesh_boxes=mesh_boxes,
2101-
mismesh_boxes=mismesh_boxes,
2102-
)
2115+
quality = compute_image_quality_metrics(img_bgr)
2116+
counts = get_gear_counts(gears)
2117+
errors: List[Dict[str, Any]] = []
21032118

21042119
out = {
21052120
"summary": {
@@ -2111,13 +2126,14 @@ def _need_shafts() -> bool:
21112126
"stages": 0,
21122127
},
21132128
"counts": counts,
2129+
"quality": quality,
21142130
"errors": errors,
21152131
"ratio": {"num_stages": 0, "R_total": None, "out_rpm": None, "per_stage": []},
21162132
"cold_start": bool(is_cold_start),
21172133
"task_result": _task_result(
21182134
TASK_PRECHECK,
21192135
errors,
2120-
focus=["precheck"],
2136+
focus=["photo_quality"],
21212137
next_task=TASK_SINGLE_STAGE,
21222138
),
21232139
"timing": {},

0 commit comments

Comments
 (0)