python - 使用套接字从 Python 中的服务器发送网络摄像头流
问题描述
我正在尝试server.py
使用 Python 套接字将网络摄像头流从文件发送到 client.py 文件。我让它在另一个方向工作,但想要翻转它(当客户端连接到服务器时,服务器会将网络摄像头数据从服务器提供给客户端)。但是,尝试运行这样的结果会导致错误并且只会显示流的第一帧,然后崩溃......我该怎么做才能解决这个问题?
服务器.py
import cv2
import io
import socket
import struct
import time
import pickle
import zlib
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((socket.gethostname(), 1234))
s.listen(5)
cam = cv2.VideoCapture(0)
cam.set(3, 320);
cam.set(4, 240);
img_counter = 0
encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), 100]
while True:
client_socket, address = s.accept()
print(f"Connection from {address} has been established!")
ret, frame = cam.read()
result, frame = cv2.imencode('.jpg', frame, encode_param)
data = pickle.dumps(frame, 0)
size = len(data)
print("{}: {}".format(img_counter, size))
client_socket.send(struct.pack(">L", size) + data)
print("ooga")
img_counter += 1
cam.release()
客户端.py
import socket
import sys
import cv2
import pickle
import numpy as np
import struct ## new
import zlib
HOST=''
PORT=8485
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((socket.gethostname(),1234))
data = b""
payload_size = struct.calcsize(">L")
print("payload_size: {}".format(payload_size))
while True:
while len(data) < payload_size:
print("Recv: {}".format(len(data)))
data += s.recv(4096)
print("Done Recv: {}".format(len(data)))
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack(">L", packed_msg_size)[0]
print("msg_size: {}".format(msg_size))
while len(data) < msg_size:
data += s.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
frame=pickle.loads(frame_data, fix_imports=True, encoding="bytes")
frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
cv2.imshow('ImageWindow',frame)
cv2.waitKey(1)
解决方案
这是一个可行的示例:
客户端.py
import cv2
import numpy as np
import socket
import sys
import pickle
import struct
cap=cv2.VideoCapture(0)
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('localhost',8089))
while True:
ret,frame=cap.read()
# Serialize frame
data = pickle.dumps(frame)
# Send message length first
message_size = struct.pack("L", len(data)) ### CHANGED
# Then data
clientsocket.sendall(message_size + data)
服务器.py
import pickle
import socket
import struct
import cv2
HOST = ''
PORT = 8089
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print('Socket created')
s.bind((HOST, PORT))
print('Socket bind complete')
s.listen(10)
print('Socket now listening')
conn, addr = s.accept()
data = b'' ### CHANGED
payload_size = struct.calcsize("L") ### CHANGED
while True:
# Retrieve message size
while len(data) < payload_size:
data += conn.recv(4096)
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("L", packed_msg_size)[0] ### CHANGED
# Retrieve all data based on message size
while len(data) < msg_size:
data += conn.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
# Extract frame
frame = pickle.loads(frame_data)
# Display
cv2.imshow('frame', frame)
cv2.waitKey(1)
希望这能满足您的需求!!
推荐阅读
- r - Plotly R 与 ggplot2:在 geom_bar 中使用 coord_polar 使用 plotly
- android - 创建没有 gradle、ant 或 cmake 的仅 JNI/NDK apk 命令行
- python-3.x - Python脚本中的可执行文件无法写入文件
- python - Python:多行用户输入,上一行的最后一个单词连接到下一行的第一个单词
- c# - 任意向量的扩展
- python-imaging-library - 尽管`resample = Image.BICUBIC`,为什么PIL.Image.rotate()会导致质量下降
- postgresql - 多个子字符串选项上的 Postgres 模式匹配
- swift - 快速警报未执行操作
- python-3.x - 在 if 语句中查找多个单词或字符串
- laravel - 获取帖子字段和每个帖子:最后评论的详细信息