gpt4 book ai didi

python - 在python opencv中通过网络发送实时视频帧

转载 作者:太空狗 更新时间:2023-10-29 17:04:15 26 4
gpt4 key购买 nike

我正在尝试将我用相机捕捉到的实时视频帧发送到服务器并对其进行处理。我使用 opencv 进行图像处理,使用 python 作为语言。这是我的代码

client_cv.py

import cv2
import numpy as np
import socket
import sys
import pickle
cap=cv2.VideoCapture(0)
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('localhost',8089))
while True:
ret,frame=cap.read()
print sys.getsizeof(frame)
print frame
clientsocket.send(pickle.dumps(frame))

server_cv.py

import socket
import sys
import cv2
import pickle
import numpy as np
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()

while True:
data=conn.recv(80)
print sys.getsizeof(data)
frame=pickle.loads(data)
print frame
cv2.imshow('frame',frame)

这段代码给我文件结束错误,这是合乎逻辑的,因为数据总是不断地到达服务器,而 pickle 不知道什么时候结束。我在互联网上的搜索让我使用了泡菜,但目前还没有用。

注意:我将 conn.recv 设置为 80,因为这是我在说 print sys.getsizeof(frame) 时得到的数字。

最佳答案

一些事情:

  • 使用 sendall 而不是 send 因为你不能保证所有的东西都会一次性发送
  • pickle 可以用于数据序列化,但你必须制定一个协议(protocol)您拥有在客户端和服务器之间交换的消息,这您可以提前知道要读取的 unpickling 数据量的方法(请参阅下)
  • 对于 recv,如果您接收大块,您将获得更好的性能,因此将 80 替换为 4096 或更多
  • 注意 sys.getsizeof:它返回内存中对象的大小,这不是与通过网络发送的字节的大小(长度)相同;为一个Python字符串这两个值根本不一样
  • 请注意您要发送的帧的大小。下面的代码支持最大 65535 的帧。如果您有更大的帧,请将“H”更改为“L”。

协议(protocol)示例:

client_cv.py

import cv2
import numpy as np
import socket
import sys
import pickle
import struct ### new code
cap=cv2.VideoCapture(0)
clientsocket=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
clientsocket.connect(('localhost',8089))
while True:
ret,frame=cap.read()
data = pickle.dumps(frame) ### new code
clientsocket.sendall(struct.pack("H", len(data))+data) ### new code

server_cv.py

import socket
import sys
import cv2
import pickle
import numpy as np
import struct ## new

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()

### new
data = ""
payload_size = struct.calcsize("H")
while True:
while len(data) < payload_size:
data += conn.recv(4096)
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("H", packed_msg_size)[0]
while len(data) < msg_size:
data += conn.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
###

frame=pickle.loads(frame_data)
print frame
cv2.imshow('frame',frame)

您可能可以优化所有这些(减少复制、使用缓冲区接口(interface)等),但至少您可以理解。

关于python - 在python opencv中通过网络发送实时视频帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30988033/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com