import cv2 import numpy as np from ultralytics import YOLO import os import uuid # Load YOLOv8 model (can be customized for object detection) model = YOLO("yolov8n.pt") # You may switch to yolov8s.pt or yolov8m.pt based on size/accuracy # Maintain state of detected objects for simple tracking unattended_objects_memory = {} def detect_unattended_objects(frame, frame_index, detection_interval=30, stay_threshold=90): """ Detects unattended objects such as bags that appear in the same position for too long. Returns True and the cropped object image if detected. """ detections = model.predict(source=frame, classes=[24, 26, 28, 39], verbose=False)[0] # COCO classes for suitcase (24), handbag (26), backpack (28), and cardboard box (39) h, w, _ = frame.shape detected = False cropped_output = None for result in detections.boxes: cls = int(result.cls[0]) conf = float(result.conf[0]) x1, y1, x2, y2 = map(int, result.xyxy[0]) center = ((x1 + x2) // 2, (y1 + y2) // 2) object_id = f"{cls}-{center[0]//20}-{center[1]//20}" # simple spatial bin id if object_id not in unattended_objects_memory: unattended_objects_memory[object_id] = frame_index else: duration = frame_index - unattended_objects_memory[object_id] if duration >= stay_threshold: detected = True cropped_output = frame[y1:y2, x1:x2] unattended_objects_memory[object_id] = frame_index + 9999 # suppress repeated detection # Clear memory periodically if frame_index % (stay_threshold * 2) == 0: unattended_objects_memory.clear() return detected, cropped_output