Spaces:
Running
Running
Zaid
feat: add support for detecting weapons and dangerous objects (knife, gun, pistol, fire, smoke, etc.)
0276147 | import cv2 | |
| from ultralytics import YOLOWorld | |
| class ObjectDetector: | |
| def __init__(self): | |
| self.model = None | |
| self.classes = [ | |
| "person", | |
| "knife", | |
| "gun", | |
| "pistol", | |
| "scissors", | |
| "lighter", | |
| "fire", | |
| "smoke", | |
| "hammer", | |
| "screwdriver", | |
| "baseball bat", | |
| "cell phone", | |
| "bottle", | |
| "cup", | |
| "pen", | |
| "book" | |
| ] | |
| try: | |
| print("Loading YOLO-World model...") | |
| # Using yolov8s-worldv2.pt which is a lightweight open-vocabulary model (~40MB) | |
| self.model = YOLOWorld('yolov8s-worldv2.pt') | |
| self.model.set_classes(self.classes) | |
| print("YOLO-World loaded and classes set: ", self.classes) | |
| except Exception as e: | |
| print(f"Error loading YOLO-World: {e}. Falling back to standard YOLOv8n.") | |
| try: | |
| from ultralytics import YOLO | |
| self.model = YOLO('yolov8n.pt') | |
| self.classes = None # Will use default COCO labels | |
| print("Standard YOLOv8n loaded successfully as fallback.") | |
| except Exception as ex: | |
| print(f"Critical: Failed to load fallback YOLO model: {ex}") | |
| def detect(self, frame): | |
| """ | |
| Runs object detection on the frame. | |
| Returns: | |
| list of dicts: [{"label": label, "bbox": [x1, y1, x2, y2], "conf": conf}] | |
| """ | |
| if self.model is None: | |
| return [] | |
| # Predict with threshold | |
| results = self.model.predict(frame, conf=0.3, verbose=False) | |
| detections = [] | |
| if not results: | |
| return detections | |
| result = results[0] | |
| boxes = result.boxes | |
| for box in boxes: | |
| cls_id = int(box.cls[0]) | |
| conf = float(box.conf[0]) | |
| xyxy = box.xyxy[0].cpu().numpy().tolist() | |
| x1, y1, x2, y2 = map(int, xyxy) | |
| # Map class ID to label name | |
| if self.classes is not None: | |
| # YOLO-World custom classes mapping | |
| if cls_id < len(self.classes): | |
| label = self.classes[cls_id] | |
| else: | |
| label = f"unknown_{cls_id}" | |
| else: | |
| # Fallback YOLOv8n COCO mapping | |
| label = result.names[cls_id] | |
| detections.append({ | |
| "label": label, | |
| "bbox": [x1, y1, x2, y2], | |
| "conf": conf | |
| }) | |
| return detections | |