Sockets Udp套接字上的Python网络摄像头流
我试图在同一网络中的两台计算机上制作网络摄像头流, 所以我在互联网上做了一些研究,发现了这个客户端和服务器代码这是客户端Sockets Udp套接字上的Python网络摄像头流,sockets,video,stream,udp,Sockets,Video,Stream,Udp,我试图在同一网络中的两台计算机上制作网络摄像头流, 所以我在互联网上做了一些研究,发现了这个客户端和服务器代码这是客户端 import socket import numpy as np import cv2 UDP_IP = '127.0.0.1' UDP_PORT = 999 cap = cv2.VideoCapture(0) while(True): ret, frame = cap.read() cv2.imshow('fr
import socket
import numpy as np
import cv2
UDP_IP = '127.0.0.1'
UDP_PORT = 999
cap = cv2.VideoCapture(0)
while(True):
ret, frame = cap.read()
cv2.imshow('frame',frame)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
d = frame.flatten ()
s = d.tostring ()
for i in xrange(20):
sock.sendto (s[i*46080:(i+1)*46080],(UDP_IP, UDP_PORT))
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
这是服务器:
#Server prog
import socket
import numpy
import time
import cv2
UDP_IP="127.0.0.1"
UDP_PORT = 999
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((UDP_IP, UDP_PORT))
s=""
while True:
data, addr = sock.recvfrom(46080)
s+= data
if len(s) == (46080*20):
frame = numpy.fromstring (s, dtype=numpy.uint8)
frame = frame.reshape(480,640,3)
cv2.imshow("frame",frame)
s=""
if cv2.waitKey(1) & 0xFF == ord('q'):
break
有些台词我不能理解,就像这样
for i in xrange(20):
sock.sendto (s[i*46080:(i+1)*46080],(UDP_IP, UDP_PORT))
他为什么要用它?(我知道在UDP中,你不能发送一个大文件,你需要发送部分,但为什么会这样?为什么是46080?)
如果len(s)=(46080*20):
+运行服务器和客户端时,服务器接收到的视频流会延迟,帧会重复。46080,因为每个帧由640x480 RGB像素组成,每个通道一个字节,因此每个像素三个字节,并以20个片段发送:
>>> 640 * 480 * 3 / 20
46080
如果您的cam捕获不同分辨率的帧,则该值应不同于46080。对于您的网络来说,46k大小的帧可能有点大,因此您可能希望尝试将其分为20多个帧发送
s[i*46080:(i+1)*46080]
表示“第i个大小为46080的片段”。这是所谓的切片表示法的一个示例:
这是一个简单但功能强大的工具,所以我建议您使用它。您还可以使用numpy-numpy支持对n维数组进行切片。有点复杂,但更强大
关于拉吉河
首先,在UPD中,帧可能丢失、重新排序和复制。为了避免重复和重新排序的数据报,您可以在发送的每个数据报上附加一个序列号,并且在接收器上有一个优先级队列
第二,我怀疑cv2.imshow是显示平滑视频的好选择。您可能想试试ffmpeg
第三,确保你的发送者足够快,至少以20-30 fps的速度捕获和发送帧。如果没有,请尝试将图像采集+处理和传输分割为单独的线程。我盲目的猜测是你花了很多时间在sock.sendto
上。不要犹豫,分析你的代码
第四,以逐图的方式发送视频可能会非常低效,即使对于非常小的期望分辨率和fps也是如此。您需要在流式代码中添加压缩/解压缩阶段。以30 fps的速度发送未压缩的768x1024x3需要70 MBytes/s的带宽。同样,ffmpeg可能会对您有所帮助。首先,请回答!但是我不明白为什么s[i*46080:(i+1)*46080]什么意思?@Ziroff这叫做切片-我已经更新了我的asnwerOk,我的网络摄像头正在以768x1024记录数据,那么我该如何传输数据呢?这是一个很大的房间number@Ziroff在这一点上,UDP不应该是您的首要任务。从压缩视频流开始,然后考虑如何传输它。再次更新了答案。
>>> a = [0, 1, 2, 3, 4, 5]
>>> a[0:2] # take element #0 and #1
[0, 1]
>>> a[2:4] # take element #2 and #3
[2, 3]