【问题标题】:UDP video streaming latency - OPENCV pythonUDP视频流延迟 - OPENCV python
【发布时间】:2020-06-14 13:12:37
【问题描述】:

我有流媒体视频 UDP,但数据包延迟且混乱。 这是我从 opencv 网站获取的参考代码。

但是当我让 Socket.Stream 使用 TCP 连接时,它可以正常传输并且帧是连续的。

服务器.py

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=b''

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=b''

  if cv2.waitKey(1) & 0xFF == ord ('q'):
    break

客户端.py

import socket
import numpy as np
import cv2

UDP_IP = '127.0.0.1'
UDP_PORT = 999
cap = cv2.VideoCapture(0)
#cap.set(cv2.CAP_PROP_FRAME_WIDTH,320)
#cap.set(cv2.CAP_PROP_FRAME_HEIGHT,240)
def xrange(x):

  return iter(range(x))
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()

【问题讨论】:

  • "但是数据包延迟和混乱" 欢迎来到 UDP 的世界!
  • Klaus D... 我尝试了很多解决方案,但没有一个能解决问题..要么帮助 mw 增加 TCP 延迟或 UDP 的数据包丢失

标签: python sockets opencv udp


【解决方案1】:

看起来client.py 脚本发送 UDP 帧(比server.py 将它们拼凑在一起的速度快得多)。我不确定为什么会这样。也许在每次迭代后增加字节s 的大小后,Python 需要找到一个新的位置来存储s,这会导致它错过从client.py 发送的帧。但是,同步它们的一种方法是告诉client.pyserver.py 确认收到帧后发送。

在下面的代码中,server.py 将通过b'eframe' 监听图像开始传输。 server.py 将连续回复 client.pyb'n' 以提示发送下一帧。 client.py 将通过发送 b'eframe' 来通知图像结束

server.py

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=b''

while True:

  data, addr = sock.recvfrom(6) # b'eframe' is 6 byte long

  if data == b'sframe':
    while True:
      sock.sendto(b'n', addr)
      data, addr = sock.recvfrom(46080)
      if data == b'eframe':
        break
      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=b''

  if cv2.waitKey(1) & 0xFF == ord ('q'):
    break

client.py

import socket
import numpy as np
import cv2

UDP_IP = '127.0.0.1'
UDP_PORT = 999
cap = cv2.VideoCapture(0)
#cap.set(cv2.CAP_PROP_FRAME_WIDTH,320)
#cap.set(cv2.CAP_PROP_FRAME_HEIGHT,240)
def xrange(x):

  return iter(range(x))
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()

  sock.sendto(b'sframe', (UDP_IP, UDP_PORT))
  for i in xrange(20):
    data, addr = sock.recvfrom(1) # b'n' is 1 byte long
    if data == b'n':
      sock.sendto(s[i * 46080:(i + 1) * 46080], (UDP_IP, UDP_PORT))
  data, addr = sock.recvfrom(1)
  sock.sendto(b'eframe', (UDP_IP, UDP_PORT))

  if cv2.waitKey(1) & 0xFF == ord('q'):
    break

cap.release()
cv2.destroyAllWindows()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-11
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-11
    相关资源
    最近更新 更多