Python 中用flask 通过socket实现实时摄像头传输到服务端,并使用YOLOv8实时检测人脸并返回给客户端呈现

本文介绍了使用Python编写的客户端和服务端代码,客户端通过Socket发送摄像头捕获的视频帧,服务端接收后使用YOLO模型进行人脸检测,并将处理后的图像回传。通过控制发送和接收帧速度避免粘包问题。
摘要由CSDN通过智能技术生成

这是客户端代码,主要功能是通过使用socket从一个客户端向服务端发送摄像头捕获的视频帧。 这段代码中的time.sleep(0.2)是为了控制发送帧的速度,cv2.waitKey(50)是等待50秒,如果在这段时间内按下任何键,将返回按键的ASCII码,否则返回-1。如果不控制发送帧的速度,容易产生粘包问题。

import socket
import time

import cv2
import numpy as np
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.1.249', 8888) #IP地址为服务端的IP地址,端口号任意
client_socket.connect(server_address)

cap = cv2.VideoCapture(0)  # 打开摄像头,0为默认摄像头


while True:
    ret, frame = cap.read()  # 获取视频的开启状态和每一帧图片
    img_encode = cv2.imencode('.jpg', frame)[1]  # 对每一帧图片进行编码
    data = np.array(img_encode)  # 转化为矩阵
    byte_encode = data.tobytes()  # 编码格式转为字节格式
    data_len = str(len(byte_encode))  # 获取每一帧图片的大小(字节数)
    print('每帧图片大小: %s' % data_len)
    client_socket.send(byte_encode)  # 发送给服务端呈现
    time.sleep(0.2)

    data = client_socket.recv(88888)  # 88888为接受的最大字节数,根据需要调整
    nparr = np.frombuffer(data, dtype='uint8')  # 化为数组
    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)  # 解码为彩色图

    cv2.imshow('clint', img)
    cv2.waitKey(50)    # 等待50毫秒

client_socket.close()

这是服务端代码,它的主要功能是接收客户端发送的视频帧,然后使用YOLO模型进行人脸检测和识别,最后将识别后的图像发送回客户端。

import socket
import cv2
from ultralytics import YOLO
import numpy as np

server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_address = ('192.168.1.249', 8888) #IP地址为服务端的IP地址,端口号任意
server_socket.bind(server_address)
server_socket.listen(1)
print('Server is listening...')

client_socket, client_address = server_socket.accept()
print('Connection from', client_address)
model = YOLO("yolov8n.yaml")
model = YOLO("yolov8n.pt")

while True:
    data = client_socket.recv(88888)  # 88888为接受的最大字节数(默认分辨率情况下图片也就34万字节)
    nparr = np.frombuffer(data, dtype='uint8')  # 化为数组
    img = cv2.imdecode(nparr, cv2.IMREAD_COLOR)  # 解码为彩色图

    res = model.predict(img, classes=[0])  # classes=[0]表示只检测人这一类别
    img = res[0].plot()
    cv2.imshow('server', img)

    cv2.waitKey(50)
    img_encode = cv2.imencode('.jpg', img)[1]  # 对每一帧图片进行编码
    data = np.array(img_encode)  # 转化为矩阵
    byte_encode = data.tobytes()  # 编码格式转为字节格式
    client_socket.send(byte_encode)  # 发送数据


client_socket.close()
server_socket.close()


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: 抱歉,由于我的训练数据只截止到2021年,所以我不了解yolov5的详细信息。但是,如果你想实现树莓派通过USB摄像头传输视频流到PC端,PC端通过对视频的识别并返回坐标给树莓派,可以参考以下步骤: 1. 在树莓派上安装摄像头驱动和所需的库。 2. 在PC端安装yolov5,并对需要识别的目标进行训练。 3. 在树莓派上通过代码读取摄像头的视频帧,并通过网络将视频帧传输到PC端。 4. 在PC端使用yolov5对视频帧进行识别,并返回识别到的目标的坐标。 5. 在树莓派上接收PC端返回的坐标,并通过代码进行处理。 希望这些信息能帮助你!如果需要更多帮助,请随时告诉我。 ### 回答2: 在树莓派上,你可以使用OpenCV库来实现通过USB摄像头传输视频流到PC端。首先,需要先在树莓派上安装OpenCV库和USB摄像头的驱动。以下是一个示例代码: ```python import cv2 import numpy as np import requests import json # 设置USB摄像头的索引号 cap = cv2.VideoCapture(0) while True: # 读取视频流 ret, frame = cap.read() # 将帧转换为字节流 _, img_encoded = cv2.imencode('.jpg', frame) img_bytes = img_encoded.tobytes() # 发送POST请求到PC端 response = requests.post("http://your-pc-ip:5000/detect", data=img_bytes) # 解析PC端返回的JSON数据 result = json.loads(response.text) # 获取目标坐标 x = result['x'] y = result['y'] # 在帧上绘制目标位置 cv2.rectangle(frame, (x, y), (x+100, y+100), (0, 255, 0), 2) # 显示帧 cv2.imshow('frame', frame) # 按下q键退出循环 if cv2.waitKey(1) & 0xFF == ord('q'): break # 释放内存 cap.release() cv2.destroyAllWindows() ``` 在PC端上,你需要搭建一个基于Yolov5的目标检测模型,并监听树莓派发送过来的视频流请求。以下是一个示例代码: ```python from flask import Flask, request from PIL import Image import torch import json # 加载预训练模型 model = torch.hub.load('ultralytics/yolov5', 'yolov5s') app = Flask(__name__) @app.route('/detect', methods=['POST']) def detect(): # 从POST请求中获取传输视频流 img_bytes = request.data # 将字节流转换为图像 img = Image.open(io.BytesIO(img_bytes)) # 使用Yolov5模型进行目标检测 results = model(img) # 提取目标坐标(这里只取第一个目标) boxes = results.pandas().xyxy[0] x = int(boxes['xmin']) y = int(boxes['ymin']) # 构建返回的JSON数据 response_data = {'x': x, 'y': y} # 返回JSON响应 return json.dumps(response_data) # 启动Flask服务器 if __name__ == '__main__': app.run(host='0.0.0.0', port=5000) ``` 在PC端中,你需要安装Flask库和Yolov5库。将以上代码保存到一个.py文件,并在PC端运行该文件,就可以监听树莓派发送过来的视频流请求,并返回目标的坐标信息。在树莓派上运行树莓派代码,即可实现树莓派通过USB摄像头传输视频流到PC端,并通过Yolov5识别目标位置,最后将坐标信息返回给树莓派。 ### 回答3: 树莓派通常使用Linux系统,可以通过安装相应的驱动和软件来支持USB摄像头。以下是通过USB摄像头传输视频流到PC端,并使用yolov5识别目标位置并返回坐标给树莓派的代码示例: 在树莓派端: ```python import cv2 import numpy as np import socket # 连接PC端IP地址和端口号 PC_IP = '192.168.1.100' PC_PORT = 8888 # 初始化USB摄像头 cap = cv2.VideoCapture(0) # 设置摄像头分辨率 cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) # 创建socket连接 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect((PC_IP, PC_PORT)) while True: # 读取摄像头每一帧 ret, frame = cap.read() # 转换图片格式 img_encode = cv2.imencode('.jpg', frame)[1] data = np.array(img_encode) string_data = data.tostring() # 发送图片数据 client_socket.sendall((str(len(string_data))).encode().ljust(16) + string_data) # 接收目标位置坐标 response = client_socket.recv(1024).decode().strip() print("目标位置坐标:", response) cap.release() client_socket.close() ``` 在PC端: ```python import cv2 from yolov5.detect import Detect # yolov5识别模型 # PC端IP地址和端口号 PC_IP = '192.168.1.100' PC_PORT = 8888 # 加载yolov5模型 model = Detect() # 创建socket连接 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind((PC_IP, PC_PORT)) server_socket.listen(1) # 接收树莓派传输的图片数据 client_socket, address = server_socket.accept() while True: length_str = client_socket.recv(16) img_data = b'' total_size = int(length_str) while len(img_data) < total_size: img_data += client_socket.recv(4096) # 解码图片 nparr = np.frombuffer(img_data, np.uint8) img = cv2.imdecode(nparr, cv2.IMREAD_COLOR) # 使用yolov5模型检测目标 result = model.detect_object(img) # 提取目标位置坐标 coordinates = [] for obj in result: x, y, w, h = obj['rect'] coordinates.append((x, y, x + w, y + h)) # 发送目标位置坐标给树莓派 response = ' '.join([str(coord) for coord in coordinates]) client_socket.send(response.encode()) client_socket.close() server_socket.close() ``` 需要注意的是,上述示例代码中,PC端的yolov5识别模型代码是伪代码,请根据自己的具体情况进行修改和替换。同时,树莓派和PC端需要处于同一个局域网中,并确保树莓派可以连接到PC端的IP地址和端口号。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值