在python opencv中通过网络发送实时视频帧 [英] Sending live video frame over network in python opencv

查看:554
本文介绍了在python opencv中通过网络发送实时视频帧的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to send live video frame that I catch with my camera to a server and process them. I'm usig opencv for image processing and python for the language. Here is my code

client_cv.py

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

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不知道何时完成.我在互联网上的搜索使我使用了泡菜,但到目前为止还不能用.

This code gives me end of file error, which is logical because the data always keep coming to the server and pickle doesn't know when to finish. My search on the internet made me use pickle but it doesn't work so far.

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

Note: I set conn.recv to 80 because that's the number I get when I say print sys.getsizeof(frame).

推荐答案

几件事:

  • 使用sendall而不是send,因为您不能保证所有内容都会一口气发送
  • pickle可以进行数据序列化,但是您必须制定一个协议 您拥有客户端和服务器之间交换的消息,这 您可以提前知道要读取的数据量的方式(请参阅 下面)
  • 对于recv,如果收到大块,您将获得更好的性能,因此将80替换为4096甚至更多
  • 当心sys.getsizeof:它返回内存中对象的大小,而不是 与通过网络发送的字节的大小(长度)相同;为一个 Python字符串这两个值根本不一样
  • 请注意您要发送的帧的大小.下面的代码支持最大65535的框架.如果框架较大,请将"H"更改为"L".
  • use sendall instead of send since you're not guaranteed everything will be sent in one go
  • pickle is ok for data serialization but you have to make a protocol of you own for the messages you exchange between the client and the server, this way you can know in advance the amount of data to read for unpickling (see below)
  • for recv you will get better performance if you receive big chunks, so replace 80 by 4096 or even more
  • beware of sys.getsizeof: it returns the size of the object in memory, which is not the same as the size (length) of the bytes to send over the network ; for a Python string the two values are not the same at all
  • be mindful of the size of the frame you are sending. Code below supports a frame up to 65535. Change "H" to "L" if you have a larger frame.

协议示例:

client_cv.py

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

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)

您可能可以对所有这些进行很多优化(减少复制,使用缓冲区接口等),但是至少您可以理解.

You can probably optimize all this a lot (less copying, using the buffer interface, etc) but at least you can get the idea.

这篇关于在python opencv中通过网络发送实时视频帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆