使用yield而不是return来创建函数以连续地从http流生成帧 [英] Creating a function using yield instead of return to generate frames from an http stream continuously
问题描述
我想创建一个使用请求来自HTTP流来读取帧的函数并返回每个帧。但由于流读取器基于迭代器对象(如果我理解正确),返回帧会破坏流。
I would like to create a function that reads frames from an HTTP stream using requests and returns each frame. But because of the fact that the stream reader is based on an iterator object (if I understand correctly), returning a frame is breaking the stream.
我正在使用的代码(完全正常,来自此答案):
The code I am using (works perfectly fine, from this answer):
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 for iterator):
Concept of what I'd like to do (with the return that I'd like to work if it was a while function instead of a 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究竟是如何允许原始代码连续工作的。
So basically I'd like to return each frame where the original code is displaying the frame so that I can perform some processing on it. But I don't understand how exactly is the iter_content allowing the original code to work continuously.
(我不知道如何命名这个问题 - 欢迎更好标题)
(I didn't know how to name the question - will welcome a better title)
推荐答案
Python有一个非常漂亮的概念 生成器
,这可能是你正在寻找的东西,所以基本上要制作一个生成器
我们使用关键字 yield
而不是 返回
。这两个关键字之间的基本区别在于 return
语句只会在遇到函数时暂停执行,而另一方面 yield
keyword让执行继续并继续生成值直到alive。它可以通过一个简单的例子显示为:
Python has a very beautiful concept of generators
, which may be the thing you are looking for, so basically to fabricate a generator
we use keyword yield
instead of return
. The basic difference between these two keywords is that the return
statement simply halts the function execution once encountered, while on the other hand yield
keyword let's the execution to continue and keeps on generating value until alive. It can be visualized in a simple example as:
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
语句重现相同的场景,然后它可能看起来像:
If We would had reproduce the same scenario using return
statement then it may look like:
def sample_function(i):
return i**2
for i in xrange(0, 20):
print sample_function(i),
因此,在上面的代码中,如果您将 return
关键字替换为 yield
,然后您可以将帧迭代为:
So in the above code if you replace the return
keyword with yield
, then you can iterate the frames as:
for frame in get_frame_from_stream(r):
cv2.imshow('i', frame)
有这种情况下不需要而
循环,除非并且直到此流存活,该方法将继续生成帧。
There is no need of a while
loop is this case, unless and until this stream is alive, the method would keep on generating frames.
这篇关于使用yield而不是return来创建函数以连续地从http流生成帧的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!