80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
|
|
"""HDevEngine 全自动驱动:读 roi.hobj,循环所有 png 跑 find_circles,
|
||
|
|
对比 拟合法 vs 计量模型法 两种找圆结果,输出偏差统计,并写 CSV。"""
|
||
|
|
import math
|
||
|
|
import csv
|
||
|
|
from halcon.hdevengine import HDevEngine, HDevProcedure, HDevProcedureCall, HDevEngineError
|
||
|
|
import halcon as ha
|
||
|
|
|
||
|
|
PROJ = r"C:\workspace\agent-studio\halcon-001"
|
||
|
|
IMG_DIR = r"C:\工作文档\2025.10.03_精度实验数据分析\两种找圆算法对比\初始状态-往复-右侧上视左标定片阵列Mark定位"
|
||
|
|
ROI_FILE = PROJ + r"\roi.hobj"
|
||
|
|
CSV_OUT = PROJ + r"\compare_result.csv"
|
||
|
|
|
||
|
|
def as_list(v):
|
||
|
|
return list(v) if isinstance(v, (list, tuple)) else [v]
|
||
|
|
|
||
|
|
# 引擎 + procedure
|
||
|
|
eng = HDevEngine()
|
||
|
|
eng.set_procedure_path(PROJ)
|
||
|
|
proc = HDevProcedure.load_external("find_circles")
|
||
|
|
call = HDevProcedureCall(proc)
|
||
|
|
|
||
|
|
# 图片列表
|
||
|
|
files = ha.list_files(IMG_DIR, "files")
|
||
|
|
pngs = sorted(ha.tuple_regexp_select(files, r"\.png$"))
|
||
|
|
print(f"待处理图片: {len(pngs)} 张")
|
||
|
|
|
||
|
|
all_dists = [] # 所有 图×圆 的中心欧氏距离
|
||
|
|
per_image_mean = [] # 每张图的平均偏差
|
||
|
|
skipped = 0
|
||
|
|
rows_csv = [("image", "circle_idx", "fit_row", "fit_col", "metro_row", "metro_col", "dist_px")]
|
||
|
|
|
||
|
|
for path in pngs:
|
||
|
|
call.reset()
|
||
|
|
call.set_input_control_param_by_name("ImageFile", path)
|
||
|
|
call.set_input_control_param_by_name("RoiFile", ROI_FILE)
|
||
|
|
try:
|
||
|
|
call.execute()
|
||
|
|
except HDevEngineError as e:
|
||
|
|
skipped += 1
|
||
|
|
if skipped <= 3:
|
||
|
|
print(f"[skip] {path.rsplit(chr(92),1)[-1]}: {e}")
|
||
|
|
continue
|
||
|
|
fr = as_list(call.get_output_control_param_by_name("FitRow"))
|
||
|
|
fc = as_list(call.get_output_control_param_by_name("FitCol"))
|
||
|
|
mr = as_list(call.get_output_control_param_by_name("MetroRow"))
|
||
|
|
mc = as_list(call.get_output_control_param_by_name("MetroCol"))
|
||
|
|
|
||
|
|
name = path.rsplit("\\", 1)[-1]
|
||
|
|
dists = []
|
||
|
|
for i in range(16):
|
||
|
|
d = math.hypot(fr[i] - mr[i], fc[i] - mc[i])
|
||
|
|
dists.append(d)
|
||
|
|
all_dists.append(d)
|
||
|
|
rows_csv.append((name, i, f"{fr[i]:.4f}", f"{fc[i]:.4f}",
|
||
|
|
f"{mr[i]:.4f}", f"{mc[i]:.4f}", f"{d:.4f}"))
|
||
|
|
per_image_mean.append(sum(dists) / len(dists))
|
||
|
|
|
||
|
|
# 统计
|
||
|
|
def stats(xs):
|
||
|
|
n = len(xs)
|
||
|
|
m = sum(xs) / n
|
||
|
|
sd = math.sqrt(sum((x - m) ** 2 for x in xs) / n)
|
||
|
|
return n, m, sd, min(xs), max(xs)
|
||
|
|
|
||
|
|
with open(CSV_OUT, "w", newline="", encoding="utf-8-sig") as f:
|
||
|
|
csv.writer(f).writerows(rows_csv)
|
||
|
|
|
||
|
|
print("=" * 60)
|
||
|
|
print(f"成功处理: {len(per_image_mean)} 张 跳过(圆数!=16): {skipped} 张")
|
||
|
|
if all_dists:
|
||
|
|
n, m, sd, lo, hi = stats(all_dists)
|
||
|
|
print(f"两算法圆心偏差 (像素),样本 {n} 个圆:")
|
||
|
|
print(f" 均值 = {m:.4f}")
|
||
|
|
print(f" 标准差 = {sd:.4f}")
|
||
|
|
print(f" 最小 = {lo:.4f}")
|
||
|
|
print(f" 最大 = {hi:.4f}")
|
||
|
|
_, mm, _, _, _ = stats(per_image_mean)
|
||
|
|
print(f" 每图平均偏差的均值 = {mm:.4f}")
|
||
|
|
print(f"明细已写: {CSV_OUT}")
|