【问题标题】:Creating a function using yield instead of return to generate frames from an http stream continuously使用 yield 而不是 return 创建函数以从 http 流连续生成帧
【发布时间】:2019-04-22 14:03:02
【问题描述】:

我想创建一个函数,它使用requests 从 HTTP 流中读取帧并返回每个帧。但由于流读取器基于迭代器对象(如果我理解正确的话),返回帧会破坏流。

我正在使用的代码(工作得很好,来自this 答案):

import cv2
import requests
import numpy as np

r = requests.get('http://roofcam.warwick.ac.uk/cgi-bin/faststream.jpg', stream=True)
if(r.status_code == 200):
    bytes_buffer = bytes()
    for chunk in r.iter_content(chunk_size=1024):
        bytes += chunk
        a = bytes_buffer.find(b'\xff\xd8')
        b = bytes_buffer.find(b'\xff\xd9')
        if a != -1 and b != -1:
            jpg = bytes_buffer[a:b+2]
            bytes_buffer = bytes_buffer[b+2:]
            i = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
            cv2.imshow('i', i)
            if cv2.waitKey(1) == 27:
                exit(0)
else:
    print("Received unexpected status code {}".format(r.status_code))

我想做的事情的概念(如果它是一个while函数而不是for using iterator,我想工作的返回):

import cv2
import requests
import numpy as np

r = requests.get('http://roofcam.warwick.ac.uk/cgi-bin/faststream.jpg', stream=True)

def get_frame_from_stream(r):
    if(r.status_code == 200):
        bytes_buffer = bytes()
        for chunk in r.iter_content(chunk_size=1024):
            bytes_buffer += chunk
            a = bytes_buffer.find(b'\xff\xd8')
            b = bytes_buffer.find(b'\xff\xd9')
            if a != -1 and b != -1:
                jpg = bytes_buffer[a:b + 2]
                bytes_buffer = bytes_buffer[b + 2:]
                i = cv2.imdecode(np.fromstring(
                    jpg, dtype=np.uint8), cv2.IMREAD_COLOR)
                return i

    else:
        print("Received unexpected status code {}".format(r.status_code))
        return None

while True:
    if img is not None:
        img = get_frame_from_stream(r)
        cv2.imshow('i', img)
        cv2.waitKey(0)
    else:
        break

所以基本上我想返回原始代码显示帧的每个帧,以便我可以对其执行一些处理。但我不明白 iter_content 究竟是如何让原始代码连续工作的。

(我不知道如何命名这个问题 - 欢迎使用更好的标题)

【问题讨论】:

  • iter_content 我相信是一个生​​成器类。
  • @0x52-0x75-0x63-0x79 感谢您的意见。我确实怀疑这一点,但我不确定我是否可以让它像我描述的那样工作,以及如何做到这一点。我正在尝试阅读有关产量和生成器的信息,但理论是一回事,在这种情况下我很难尝试应用它。

标签: python opencv stream iterator python-requests


【解决方案1】:

Python 有一个非常漂亮的概念generators,这可能是你要找的东西,所以基本上要制造一个generator,我们使用关键字yield 而不是return。这两个关键字之间的基本区别在于return 语句只是在遇到函数时停止执行,而另一方面yield 关键字让执行继续并继续生成值直到存活。可以用一个简单的例子来表示:

def sample_function():
    # The body would be replaced by image generating code.
    for i in xrange(20):
        yield i**2

for x in sample_function():
    print x, 
>>> 0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361

如果我们使用return 语句重现相同的场景,那么它可能看起来像:

def sample_function(i):
    return i**2

for i in xrange(0, 20):
    print sample_function(i),

所以在上面的代码中,如果将return关键字替换为yield,那么你可以将帧迭代为:

for frame in get_frame_from_stream(r):
    cv2.imshow('i', frame)

在这种情况下不需要while 循环,除非并且直到此流处于活动状态,否则该方法将继续生成帧。

【讨论】:

  • 像魅力一样工作。我确实尝试过这样做——使用yield而不是return。但是 'for x in sample_function()' 位对我来说是个谜,我尝试像普通函数一样使用它,而不是在 'for' 语句中使用它。谢谢。
猜你喜欢
  • 2013-12-13
  • 2017-07-07
  • 2021-06-02
  • 2021-09-05
  • 2020-02-15
  • 1970-01-01
  • 2017-10-04
  • 2011-05-30
  • 2020-10-23
相关资源
最近更新 更多