{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %% [markdown]\n",
    "# # [0] 시각화 파라미터 커스터마이즈\n",
    "#  • 이 셀에서 FONT_SIZE, LINE_THICKNESS 등을 필요에 맞게 수정 후 실행\n",
    "#  • config.py를 직접 고치지 않고도 런타임에 변경 가능\n",
    "\n",
    "# %%\n",
    "import sys\n",
    "from pathlib import Path\n",
    "PKG_ROOT = Path(\"/ltb/media/ltb/90887173887158A4/Users/ltb/\")\n",
    "sys.path.append(str(PKG_ROOT))\n",
    "\n",
    "from ladder_safety import config as CFG\n",
    "\n",
    "# ── 예시: 글꼴·크기·굵기·라인 굵기 변경\n",
    "CFG.FONT_PATH      = Path(\"/usr/share/fonts/truetype/nanum/NanumGothicBold.ttf\")\n",
    "CFG.FONT_SIZE      = 24\n",
    "CFG.FONT_BOLD      = True\n",
    "CFG.LINE_THICKNESS = 5\n",
    "print(\"✅ 시각화 전역 설정 업데이트 완료\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %% [markdown]\n",
    "# # [1] 초기 설정 & 패키지 로드\n",
    "# 모듈화된 ladder_safety 패키지를 import\n",
    "# (PYTHONPATH에 패키지 루트를 추가하거나, 같은 폴더에서 실행)\n",
    "\n",
    "# %%\n",
    "import sys, gc, time, cv2, torch\n",
    "from pathlib import Path\n",
    "\n",
    "PKG_ROOT = Path(\"/ltb/media/ltb/90887173887158A4/Users/ltb/\")  # ← 패키지 폴더\n",
    "if str(PKG_ROOT) not in sys.path:\n",
    "    sys.path.append(str(PKG_ROOT))\n",
    "\n",
    "from ladder_safety import (\n",
    "    config as CFG, utils, detection, tracking,\n",
    "    rule_engine, visualizer, calibration\n",
    ")\n",
    "\n",
    "save_dir = utils.get_new_exp_dir(CFG.SAVE_ROOT)\n",
    "print(\"[INFO] 결과 폴더:\", save_dir)\n",
    "video_files = utils.collect_videos(CFG.VIDEO_SOURCE)\n",
    "print(f\"[INFO] 처리 대상 {len(video_files)}개 비디오\")\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# %% [markdown]\n",
    "# # [2] 메인 추론 ‑ Ultralytics 트래커 버전\n",
    "\n",
    "# %%\n",
    "import csv, time, cv2, torch\n",
    "from ladder_safety import utils, tracking, rule_engine, visualizer, calibration\n",
    "\n",
    "summary_path = save_dir / \"summary.csv\"\n",
    "with open(summary_path, \"w\", newline=\"\") as f:\n",
    "    csv.writer(f).writerow([\"video\", \"frames\", \"duration_s\", \"avg_fps\"])\n",
    "\n",
    "for vid_idx, vid_path in enumerate(video_files, 1):\n",
    "    cap = cv2.VideoCapture(str(vid_path))\n",
    "    fourcc = cv2.VideoWriter_fourcc(*'mp4v')\n",
    "    out_mp4 = save_dir / f\"{vid_path.stem}_annot.mp4\"\n",
    "    fps = cap.get(cv2.CAP_PROP_FPS) or 30\n",
    "    w  = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))\n",
    "    h  = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))\n",
    "    writer = cv2.VideoWriter(str(out_mp4), fourcc, fps, (w, h))\n",
    "\n",
    "    # ▶ 힌지 높이(cm) 보정\n",
    "    ret, first = cap.read()\n",
    "    if not ret: print(\"영상 읽기 실패:\", vid_path); continue\n",
    "    hinge_cm = calibration.resolve_hinge_cm(vid_path, first)\n",
    "    cap.set(cv2.CAP_PROP_POS_FRAMES, 0)\n",
    "\n",
    "    frame_cnt = 0; t0 = time.time()\n",
    "    while True:\n",
    "        ret, frame = cap.read()\n",
    "        if not ret:\n",
    "            break\n",
    "        # 🔄 감지+추적 한 줄!\n",
    "        dets = tracking.track_frame(frame, persist=True)\n",
    "\n",
    "        status, warns = rule_engine.evaluate_frame(dets, hinge_cm)\n",
    "        vis = visualizer.draw(frame, dets, status, warns)\n",
    "        writer.write(vis)\n",
    "        frame_cnt += 1\n",
    "\n",
    "    cap.release(); writer.release()\n",
    "    dur = time.time() - t0\n",
    "    with open(summary_path, \"a\", newline=\"\") as f:\n",
    "        csv.writer(f).writerow([vid_path.name, frame_cnt, f\"{dur:.1f}\", f\"{frame_cnt/dur:.1f}\"])\n",
    "    print(f\"[{vid_idx}/{len(video_files)}] {vid_path.name} → {frame_cnt}프레임, {dur:.1f}s\")\n",
    "\n",
    "print(\"✅ 전체 완료\")\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "ltb",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.20"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
