yolo-object-detection / Websocket_server.py
techventurecrew
Deploying Streamlit YOLO application with CPU-optimized weights
f434690
Raw
History Blame Contribute Delete
3.92 kB
import asyncio
import websockets
import cv2
import base64
import json
import numpy as np
from ultralytics import YOLO
import threading
from datetime import datetime
class WebSocketDetector:
def __init__(self):
self.model = YOLO('yolov8n.pt')
self.connected_clients = set()
self.streaming = False
async def register(self, websocket):
"""Register new client"""
self.connected_clients.add(websocket)
print(f"Client connected. Total clients: {len(self.connected_clients)}")
async def unregister(self, websocket):
"""Unregister client"""
self.connected_clients.remove(websocket)
print(f"Client disconnected. Total clients: {len(self.connected_clients)}")
async def send_frame(self, websocket, frame, detections):
"""Send frame and detection data to client"""
# Encode frame to JPEG
_, buffer = cv2.imencode('.jpg', frame)
frame_base64 = base64.b64encode(buffer).decode('utf-8')
# Create message
message = {
'type': 'frame',
'timestamp': datetime.now().isoformat(),
'image': frame_base64,
'detections': detections,
'total_objects': len(detections)
}
await websocket.send(json.dumps(message))
async def handle_client(self, websocket, path):
"""Handle individual client connection"""
await self.register(websocket)
try:
async for message in websocket:
data = json.loads(message)
if data.get('command') == 'start':
self.streaming = True
elif data.get('command') == 'stop':
self.streaming = False
elif data.get('command') == 'status':
await websocket.send(json.dumps({
'type': 'status',
'streaming': self.streaming,
'clients': len(self.connected_clients)
}))
except websockets.exceptions.ConnectionClosed:
pass
finally:
await self.unregister(websocket)
def detect_frame(self, frame):
"""Run detection on frame"""
results = self.model(frame, verbose=False)
# Extract detections
detections = []
if results[0].boxes is not None:
for box in results[0].boxes:
detections.append({
'class': self.model.names[int(box.cls)],
'confidence': float(box.conf),
'bbox': box.xyxy.tolist()[0]
})
annotated = results[0].plot()
return annotated, detections
async def broadcast_frames(self):
"""Broadcast frames to all connected clients"""
cap = cv2.VideoCapture(0)
while True:
if self.streaming and self.connected_clients:
ret, frame = cap.read()
if ret:
annotated, detections = self.detect_frame(frame)
# Send to all connected clients
await asyncio.gather(
*[self.send_frame(client, annotated, detections)
for client in self.connected_clients]
)
await asyncio.sleep(0.033) # ~30 FPS
cap.release()
async def main():
detector = WebSocketDetector()
# Start broadcasting task
broadcast_task = asyncio.create_task(detector.broadcast_frames())
# Start WebSocket server
async with websockets.serve(detector.handle_client, "localhost", 8765):
print("WebSocket server started on ws://localhost:8765")
await asyncio.Future() # Run forever
if __name__ == "__main__":
asyncio.run(main())