import os import json from barcode_scanner import scan_all_barcodes from ocr import read_chassis, postprocess_with_hint BARCODE_DIR = "images/barcode" CHASSIS_DIR = "images/chassis" RESULTS_DIR = "results" def get_pairs(): barcode_files = {os.path.splitext(f)[0]: f for f in os.listdir(BARCODE_DIR) if f.lower().endswith(('.jpg', '.jpeg', '.png'))} chassis_files = {os.path.splitext(f)[0]: f for f in os.listdir(CHASSIS_DIR) if f.lower().endswith(('.jpg', '.jpeg', '.png'))} common = sorted(set(barcode_files.keys()) & set(chassis_files.keys())) pairs = [] for key in common: pairs.append({ "key": key, "barcode_path": os.path.join(BARCODE_DIR, barcode_files[key]), "chassis_path": os.path.join(CHASSIS_DIR, chassis_files[key]), }) return pairs def evaluate(): os.makedirs(RESULTS_DIR, exist_ok=True) print("=" * 60) print("CHASSIS OCR EVALUATION") print("=" * 60) print("\n[1/3] Scanning barcodes for ground truth...") barcode_results = scan_all_barcodes(BARCODE_DIR) pairs = get_pairs() print(f"\n[2/3] Found {len(pairs)} matching image pairs") print(f"\n[3/3] Running OCR pipeline on chassis images...\n") results = [] exact_match = 0 corrected_match = 0 failed = 0 for pair in pairs: key = pair["key"] expected = barcode_results.get(key) chassis_path = pair["chassis_path"] if not expected: print(f" [WARN] {key} - barcode not decoded, skipping") continue ocr_text, conf = read_chassis(chassis_path, save_comparison=True) corrected, is_match = postprocess_with_hint(ocr_text, expected) if ocr_text == expected: status = "[EXACT]" exact_match += 1 elif is_match: status = "[CORRECTED]" corrected_match += 1 else: status = "[FAILED]" failed += 1 print(f" {status} | {key}") print(f" Expected : {expected}") print(f" Got : {ocr_text} (conf: {conf:.0%})") if is_match and ocr_text != expected: print(f" Fixed to : {corrected}") print() results.append({ "key": key, "expected": expected, "ocr_raw": ocr_text, "corrected": corrected, "confidence": round(conf, 3), "match": is_match, "exact": ocr_text == expected, }) total = len(results) total_correct = exact_match + corrected_match print("=" * 60) print("RESULTS SUMMARY") print("=" * 60) print(f"Total pairs evaluated : {total}") print(f"Exact matches : {exact_match}/{total} ({exact_match/total*100:.1f}%)") print(f"Corrected matches : {corrected_match}/{total} ({corrected_match/total*100:.1f}%)") print(f"Total correct : {total_correct}/{total} ({total_correct/total*100:.1f}%)") print(f"Failed : {failed}/{total} ({failed/total*100:.1f}%)") print("=" * 60) if failed > 0: print("\nFailed images (focus preprocessing tuning here):") for r in results: if not r["match"]: print(f" - {r['key']}: expected '{r['expected']}', got '{r['ocr_raw']}'") report_path = os.path.join(RESULTS_DIR, "report.json") with open(report_path, "w") as f: json.dump(results, f, indent=2) print(f"\nFull report saved -> {report_path}") print(f"Comparison images -> {RESULTS_DIR}/") if __name__ == "__main__": evaluate()