【树莓派】利用socket改善树莓派3B运行YOLO运力不够
- 前言
- 一、版本一
- 树莓派(客户端)
- PC端(服务端)
- 总结
前言
如标题所示。
目标是树莓派作为客户端只负责捕捉画面,PC端运行yolo识别。
一、版本一
树莓派(客户端)
import cv2
import socket
import pickle
import struct
import time# 初始化摄像头
cap = cv2.VideoCapture(0)# 创建套接字并连接到PC
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('192.168.254.254', 8080)) # 替换为PC的实际IP地址# 添加延时,确保连接稳定
time.sleep(1)while True:ret, frame = cap.read()if not ret:print("无法读取摄像头数据")break# 序列化图像try:data = pickle.dumps(frame)except Exception as e:print(f"序列化图像时出现错误: {e}")break# 发送数据长度try:client_socket.sendall(struct.pack("I", len(data)))except Exception as e:print(f"发送数据长度时出现错误: {e}")break# 发送数据try:client_socket.sendall(data)except Exception as e:print(f"发送数据时出现错误: {e}")break# 释放摄像头和关闭连接
cap.release()
client_socket.close()
PC端(服务端)
'''
#Author :susocool
#Creattime:2024/9/19
#FileName:0-PC2PI-server
#Description: 目标是电脑端作为服务端给客户端(pi)传递信息
'''
import cv2
import torch
import socket
import pickle
import struct
import time# 在循环前设置初始时间
start_time = time.perf_counter()# 加载YOLOv5模型
model_path = 'D:\\yolov5-master\\runs\\train\\exp4\\weights\\best.pt'
model = torch.hub.load ( 'D:\\yolov5-master', 'custom', path=model_path, source='local' )# 创建套接字并监听来自树莓派的连接
server_socket = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
server_socket.bind ( ('0.0.0.0', 8080) ) # 监听所有接口的8080端口
server_socket.listen ( 1 )print ( "等待连接..." )
conn, addr = server_socket.accept ()
print ( f"连接来自 {addr}" )frames = 0
next_frame_time = 0while True :try :# 接收数据长度data_len = struct.unpack ( "L", conn.recv ( struct.calcsize ( "L" ) ) )[0]# 接收数据data = b''while len ( data ) < data_len :packet = conn.recv ( data_len - len ( data ) )if not packet :print ( "连接中断,数据接收失败" )breakdata += packet# 反序列化图像frame = pickle.loads ( data )# 计算延迟和帧率current_time = time.perf_counter ()frames += 1delay = current_time - next_frame_timenext_frame_time = current_timefps = 1 / delay # 计算帧率# 显示帧率信息cv2.putText ( frame, f'FPS: {fps:.2f}', (10, 20),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2 )# 将图像转换为YOLOv5模型所需的格式img = cv2.cvtColor ( frame, cv2.COLOR_BGR2RGB )results = model ( img )# 获取检测结果detections = results.pandas ().xyxy[0] # 使用 pandas 结果annotated_frame = frame.copy ()# 绘制检测框for _, row in detections.iterrows () :x1, y1, x2, y2 = int ( row['xmin'] ), int ( row['ymin'] ), int ( row['xmax'] ), int ( row['ymax'] )label = row['name']conf = row['confidence']color = (0, 255, 0) # 绿色cv2.rectangle ( annotated_frame, (x1, y1), (x2, y2), color, 2 )cv2.putText ( annotated_frame, f'{label} {conf:.2f}', (x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color,2 )# 显示图像cv2.imshow ( 'YOLOv5 Detection', annotated_frame )# 按 'q' 键退出if cv2.waitKey ( 1 ) & 0xFF == ord ( 'q' ) :break# 每20帧才打印帧率,避免过度日志记录if frames % 20 == 0 :print ( f'Frame rate: {fps:.2f}' )except Exception as e :print ( f"处理数据时出现错误: {e}" )break# 释放资源和关闭连接
conn.close ()
server_socket.close ()
cv2.destroyAllWindows ()
注:先运行服务端再到客户端
结果展示
运行起来比树莓派直接运行快一点,但不多。
帧数的计算 也不知道对不对,总之很少。我认为可以被优化吧。
2024/9/19
总结
这篇文章依旧没有总结