chore: add stamp match report script

This commit is contained in:
2026-06-24 09:29:17 +08:00
parent 0230d4774f
commit e8666d0271
2 changed files with 170 additions and 0 deletions
+156
View File
@@ -0,0 +1,156 @@
"""Generate a CSV report matching merged images to source stamp images.
This script is intentionally standalone and does not import cmbot project code.
Edit the three paths below, then run:
python match_stamp.py
It does not copy, move, rename, or delete any image files.
"""
from __future__ import print_function
import csv
from datetime import datetime
from pathlib import Path
OUTPUT_DIR = r"D:\chengma\cmbot\output\20260623_094529"
STAMP_DIR = r"D:\chengma\印花和底图\已处理印花\卡通71(66大码200斤 KEKE已上)\横1"
REPORT_PATH = r"D:\chengma\cmbot\match_stamp_report.csv"
IMAGE_EXTENSIONS = {".png", ".jpg", ".jpeg", ".webp"}
FIELDNAMES = [
"status",
"code",
"merged_image",
"stamp_image",
"merged_folder",
"message",
]
def is_image(path):
return path.is_file() and path.suffix.lower() in IMAGE_EXTENSIONS
def extract_code_from_merged_name(path):
"""Extract stamp code from the final underscore suffix.
Example: 1_TY037.png -> TY037.
"""
stem = path.stem
if "_" not in stem:
return ""
code = stem.rsplit("_", 1)[1].strip()
return code
def iter_images(root):
root = Path(root)
if not root.exists():
return
for path in sorted(root.rglob("*")):
if is_image(path):
yield path
def build_stamp_index(stamp_dir):
index = {}
for path in iter_images(stamp_dir):
code = path.stem.strip()
if not code:
continue
index.setdefault(code, []).append(path.resolve())
return index
def match_merged_image(path, stamp_index):
code = extract_code_from_merged_name(path)
if not code:
return {
"status": "bad_name",
"code": "",
"merged_image": str(path.resolve()),
"stamp_image": "",
"merged_folder": str(path.parent.resolve()),
"message": "File name has no underscore suffix code",
}
candidates = stamp_index.get(code, [])
if not candidates:
return {
"status": "missing",
"code": code,
"merged_image": str(path.resolve()),
"stamp_image": "",
"merged_folder": str(path.parent.resolve()),
"message": "No stamp image found for code",
}
stamp_paths = " | ".join(str(p) for p in candidates)
if len(candidates) > 1:
return {
"status": "duplicate",
"code": code,
"merged_image": str(path.resolve()),
"stamp_image": stamp_paths,
"merged_folder": str(path.parent.resolve()),
"message": "Multiple stamp images found for code",
}
return {
"status": "matched",
"code": code,
"merged_image": str(path.resolve()),
"stamp_image": stamp_paths,
"merged_folder": str(path.parent.resolve()),
"message": "",
}
def write_csv(rows, report_path):
report_path = Path(report_path)
report_path.parent.mkdir(parents=True, exist_ok=True)
with report_path.open("w", encoding="utf-8-sig", newline="") as f:
writer = csv.DictWriter(f, fieldnames=FIELDNAMES)
writer.writeheader()
for row in rows:
writer.writerow(row)
def generate_report(output_dir, stamp_dir, report_path):
output_dir = Path(output_dir)
stamp_dir = Path(stamp_dir)
stamp_index = build_stamp_index(stamp_dir)
rows = []
for path in iter_images(output_dir):
rows.append(match_merged_image(path, stamp_index))
write_csv(rows, report_path)
return rows
def summarize(rows):
counts = {}
for row in rows:
status = row.get("status", "")
counts[status] = counts.get(status, 0) + 1
return counts
def main():
started = datetime.now()
rows = generate_report(OUTPUT_DIR, STAMP_DIR, REPORT_PATH)
counts = summarize(rows)
print("Generated report: {}".format(Path(REPORT_PATH).resolve()))
print("Merged images: {}".format(len(rows)))
print("Matched: {}".format(counts.get("matched", 0)))
print("Missing: {}".format(counts.get("missing", 0)))
print("Duplicate: {}".format(counts.get("duplicate", 0)))
print("Bad name: {}".format(counts.get("bad_name", 0)))
print("Elapsed: {}".format(datetime.now() - started))
if __name__ == "__main__":
main()