如何在YOLOv5的detect.py中集成WebSocket实现实时检测结果传输
YOLOv5 detect.py 集成WebSocket实时传输检测结果解决方案
核心思路:用多线程隔离WebSocket服务与检测循环
WebSocket需要持续监听客户端连接,直接塞进检测主循环会阻塞整个流程。把WebSocket服务单独开一个线程,检测结果通过线程安全队列传递,两边互不干扰,各自跑各自的逻辑。
具体代码修改步骤
1. 导入必要模块
直接在detect.py开头加这些导入:
import threading import queue import json from websockets.sync.server import serve
2. 定义全局线程安全队列
放在所有函数外面,用来暂存检测结果,避免线程间数据冲突:
result_queue = queue.Queue(maxsize=10) # 限制队列大小,防止检测太快撑爆内存
3. 编写WebSocket服务函数
这个函数单独在线程里运行,负责对接客户端、发送检测结果:
def websocket_server(): def handle_client(websocket): while True: try: # 从队列取结果,超时1秒避免一直阻塞 result = result_queue.get(timeout=1) websocket.send(result) except queue.Empty: continue except Exception as e: print(f"WebSocket客户端断开: {e}") break # 绑定本地8765端口启动服务,端口可以自己改 with serve(handle_client, "localhost", 8765): print("WebSocket服务已启动,等客户端连...") threading.Event().wait() # 让线程一直挂着运行
4. 修改检测循环,把结果塞队列
找到detect.py里处理每一帧检测结果的地方(一般在for *xyxy, conf, cls in reversed(det)这块代码附近),把检测结果转成JSON字符串后丢进队列:
# 整理当前帧的所有检测结果 detect_results = [] for *xyxy, conf, cls in reversed(det): class_name = names[int(cls)] # 按前端需要的格式整理数据 result_item = { "class": class_name, "confidence": float(conf), "bbox": [float(xyxy[0]), float(xyxy[1]), float(xyxy[2]), float(xyxy[3])] } detect_results.append(result_item) # 把结果丢进队列,满了就挤掉最旧的 if not result_queue.full(): result_queue.put(json.dumps(detect_results)) else: result_queue.get() result_queue.put(json.dumps(detect_results))
5. 启动程序时拉起WebSocket线程
找到detect.py的主入口(if __name__ == "__main__":块),在启动检测前先开WebSocket线程:
if __name__ == "__main__": # 启动WebSocket线程,设为守护线程,主程序退了它自动跟着退 ws_thread = threading.Thread(target=websocket_server, daemon=True) ws_thread.start() # 原有检测启动代码不动 main()
关键注意事项
- 守护线程标记
daemon=True必须加,防止主程序退出后WebSocket线程还在后台乱跑。 - 队列最大长度根据你的检测帧率调,别太大也别太小,平衡内存占用和实时性。
- 前端要对应WebSocket的连接地址(比如
ws://localhost:8765),才能收到数据。 - 如果用的是异步WebSocket库,逻辑类似,把线程换成异步任务就行,核心还是用队列解耦。
内容的提问来源于stack exchange,提问作者DHWANI JOSHI
相关产品推荐
相关产品推荐

