Lidar_Muxa/tools/check_obstacle.py
Данил Омелечко 623cbb3843 ML-ядро: конвейер обнаружения на схемах мозга дрозофилы
Ретина, ламина, медулла, лобула, грибовидное тело, веерное тело,
центральный комплекс, нисходящие нейроны. Обучение памяти тоннеля и
считывания MBON, оценка leave-one-bag-out, полигон дальности, 24 теста.

Реальный объект на 55 м — 98.9 % кадров, ложных 7.5 трека на км,
кадр обрабатывается за 33 мс на CPU.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-21 17:13:55 +03:00

65 lines
2.7 KiB
Python

"""Опорный тест: реальный объект на ~55 м в бэге `doubleT_obstacle`.
Печатает, в скольких кадрах он попал в кандидаты и в подтверждённые треки,
и сколько при этом было посторонних тревог.
python tools/check_obstacle.py [--memory artifacts/mushroom_body.npz]
"""
from __future__ import annotations
import argparse
import numpy as np
import _bootstrap as B # noqa: F401
from flyguard.bag import Bag
from flyguard.mushroom_body import MushroomBody
from flyguard.pipeline import FlyGuard, Params
TRUE_D = (50.0, 62.0) # объект стоит на 54.7…56.9 м всю запись
def main() -> None:
ap = argparse.ArgumentParser(description=__doc__)
ap.add_argument("--bag", default=str(B.DATA / "for_hackathon" / "doubleT_obstacle"))
ap.add_argument("--memory")
ap.add_argument("--limit", type=int, default=200)
ap.add_argument("--verbose", action="store_true")
args = ap.parse_args()
memory = MushroomBody.load(args.memory) if args.memory else None
fg = FlyGuard(Params(), memory=memory)
bag = Bag(args.bag)
n = cand_hit = track_hit = other = 0
novelties, evid = [], []
for k, (_, pc) in enumerate(bag.frames(stop=args.limit)):
res = fg.process(pc)
if res is None:
continue
n += 1
cs = [c for c in res.candidates if TRUE_D[0] < c.d < TRUE_D[1]]
if cs:
cand_hit += 1
novelties.append(max(c.novelty for c in cs))
objs = res.decision.objects
mine = [o for o in objs if TRUE_D[0] < o.distance < TRUE_D[1]]
if mine:
track_hit += 1
evid.append(max(o.confidence for o in mine))
other += len(objs) - len(mine)
if args.verbose and k % 20 == 0:
print(f" кадр {k:4d}: канд. в зоне {len(cs)}, "
f"треков всего {len(objs)}, в зоне {len(mine)}, "
f"ближайший {res.decision.distance:.1f} м")
print(f"кадров обработано: {n}")
print(f"объект среди кандидатов: {cand_hit}/{n} = {cand_hit/max(n,1):.1%}"
+ (f" новизна медиана {np.median(novelties):.3f}" if novelties else ""))
print(f"объект подтверждён треком: {track_hit}/{n} = {track_hit/max(n,1):.1%}"
+ (f" уверенность медиана {np.median(evid):.3f}" if evid else ""))
print(f"посторонних подтверждённых объектов: {other} ({other/max(n,1):.2f} на кадр)")
if __name__ == "__main__":
main()