laring-backend / backend /object_detector.py
Zaid
feat: add support for detecting weapons and dangerous objects (knife, gun, pistol, fire, smoke, etc.)
0276147
Raw
History Blame Contribute Delete
2.7 kB
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