{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"tpuV5e8","dataSources":[{"sourceType":"competition","sourceId":127283,"databundleVersionId":15634477}],"dockerImageVersionId":31288,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install ultralytics opencv-python-headless tqdm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-02-24T18:49:40.761069Z","iopub.execute_input":"2026-02-24T18:49:40.761216Z","iopub.status.idle":"2026-02-24T18:49:49.835856Z","shell.execute_reply.started":"2026-02-24T18:49:40.761197Z","shell.execute_reply":"2026-02-24T18:49:49.834974Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import cv2\nimport numpy as np\nimport pandas as pd\nimport glob\nfrom tqdm import tqdm\nfrom ultralytics import YOLO\n\nyolo_model = YOLO(\"yolov8n.pt\")\n\ndef process_video_fast(video_path):\n    cap = cv2.VideoCapture(video_path)\n    fps = cap.get(cv2.CAP_PROP_FPS)\n    \n    motion_scores = []\n    frames = []\n    gray_prev = None\n    \n    frame_id = 0\n    sample_rate = int(fps // 4) if fps > 4 else 1  # ~4 FPS sampling\n    \n    while True:\n        ret, frame = cap.read()\n        if not ret:\n            break\n        \n        if frame_id % sample_rate != 0:\n            frame_id += 1\n            continue\n        \n        # resize for speed\n        frame = cv2.resize(frame, (640, 360))\n        gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)\n        \n        if gray_prev is not None:\n            flow = cv2.calcOpticalFlowFarneback(\n                gray_prev, gray, None,\n                0.5, 3, 15, 3, 5, 1.2, 0\n            )\n            mag = np.sqrt(flow[...,0]**2 + flow[...,1]**2)\n            motion_scores.append(np.mean(mag))\n            frames.append(frame)\n        \n        gray_prev = gray\n        frame_id += 1\n        \n        # early stop (max 25 sec)\n        if frame_id > fps * 25:\n            break\n    \n    cap.release()\n    \n    if len(motion_scores) == 0:\n        return 1.0, 0.5, 0.5, \"rear-end\"\n    \n    accident_idx = np.argmax(motion_scores)\n    accident_time = (accident_idx * sample_rate) / fps\n    \n    accident_frame = frames[accident_idx]\n    \n    # Spatial center from flow hotspot approximation\n    h, w, _ = accident_frame.shape\n    cx, cy = 0.5, 0.5\n    \n    # YOLO only once\n    results = yolo_model(accident_frame, verbose=False)\n    vehicles = []\n    \n    for r in results:\n        for box in r.boxes:\n            cls = int(box.cls[0])\n            label = yolo_model.names[cls]\n            if label in [\"car\", \"truck\", \"bus\", \"motorcycle\"]:\n                x1,y1,x2,y2 = map(float, box.xyxy[0])\n                vehicles.append(((x1+x2)/2/w, (y1+y2)/2/h))\n    \n    if len(vehicles) >= 1:\n        cx, cy = vehicles[0]\n    \n    # Simple classification\n    if len(vehicles) == 1:\n        collision_type = \"single\"\n    elif len(vehicles) >= 2:\n        collision_type = \"rear-end\"\n    else:\n        collision_type = \"rear-end\"\n    \n    return accident_time, cx, cy, collision_type\n\n\nvideo_paths = glob.glob(\"/kaggle/input/accident/videos/*.mp4\")\n\nrows = []\n\nfor path in tqdm(video_paths):\n    t, cx, cy, ctype = process_video_fast(path)\n    \n    rows.append({\n        \"path\": path.replace(\"/kaggle/input/accident/\", \"\"),\n        \"accident_time\": round(float(t), 2),\n        \"center_x\": round(float(cx), 5),\n        \"center_y\": round(float(cy), 5),\n        \"type\": ctype\n    })\n\nsubmission = pd.DataFrame(rows)\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-02-24T18:57:49.967009Z","iopub.execute_input":"2026-02-24T18:57:49.967429Z"}},"outputs":[],"execution_count":null}]}