我正在使用cv2.VideoCapture在python脚本中读取RTSP视频链接的帧。.read()函数在每秒运行一次的while循环中,然而,我没有从流中获得最新的帧。我得到了旧帧,这样我的滞后就建立了。无论如何,我可以获得最新的帧,而不是已经进入VideoCapture对象的旧帧吗?
xmjla07d1#
我也遇到了同样的问题。似乎一旦VideoCapture对象被初始化,它就一直将帧存储在某种缓冲区中,并为每次读取操作返回一个帧。我所做的是每次我想读取帧时都初始化VideoCapture对象,然后释放流。下面的代码以10秒的间隔捕获10张图像并存储它们。同样可以使用while(True)在循环中。
for x in range(0,10): cap = cv2.VideoCapture(0) ret, frame = cap.read() cv2.imwrite('test'+str(x)+'.png',frame) cap.release() time.sleep(10)
for x in range(0,10):
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
cv2.imwrite('test'+str(x)+'.png',frame)
cap.release()
time.sleep(10)
pxiryf3j2#
我也遇到了同样的问题,并找到了一个Azure samples的git仓库,用于他们的计算机视觉服务。相关的部分是Camera Capture module,特别是Video Stream class。你可以看到他们已经实现了一个更新的队列,只保留最新的帧:
def update(self): try: while True: if self.stopped: return if not self.Q.full(): (grabbed, frame) = self.stream.read() # if the `grabbed` boolean is `False`, then we have # reached the end of the video file if not grabbed: self.stop() return self.Q.put(frame) # Clean the queue to keep only the latest frame while self.Q.qsize() > 1: self.Q.get()
def update(self):
try:
while True:
if self.stopped:
return
if not self.Q.full():
(grabbed, frame) = self.stream.read()
# if the `grabbed` boolean is `False`, then we have
# reached the end of the video file
if not grabbed:
self.stop()
self.Q.put(frame)
# Clean the queue to keep only the latest frame
while self.Q.qsize() > 1:
self.Q.get()
cclgggtu3#
我和一个朋友在做同样的事情。我们不想使用所有的帧。到目前为止,我们发现了非常相同的事情:grab()(或read)试图让你所有的帧,我猜是grab():它会保持一个缓冲区,如果你不够响应,它会放弃。除了read,你也可以使用grab()和receive()。第一个请求帧。receive将其读入内存。所以如果你多次调用grab,它将有效地跳过那些帧。我们这样做了:
grab()
#show some initial imagewhile True: cv2.grab() if cv2.waitKey(10): im = cv2.receive() # process cv2.imshow...
#show some initial image
cv2.grab()
if cv2.waitKey(10):
im = cv2.receive()
# process
cv2.imshow...
不是生产代码,而是...
s3fp2yjn4#
在“while”中,您可以使用:用途:
while True: cap = cv2.VideoCapture() urlDir = 'rtsp://ip:port/h264_ulaw.sdp' cap.open(urlDir) # get the current frame _,frame = cap.read() cap.release() #releasing camera image = frame
cap = cv2.VideoCapture()
urlDir = 'rtsp://ip:port/h264_ulaw.sdp'
cap.open(urlDir)
# get the current frame
_,frame = cap.read()
cap.release() #releasing camera
image = frame
qybjjes15#
使用下面的方法给我带来了很多问题。传递给函数的帧不是序列化的。
cap = cv2.VideoCapture(0)while True: ret, frame = cap.read() function_that_uses_frame(frame) time.sleep(0.5)
function_that_uses_frame(frame)
time.sleep(0.5)
下面的建议也不适用于我,正如其他评论所建议的那样。我仍然对最近的帧有问题。
cap = cv2.VideoCapture(0)while True: ret = capture.grab() ret, frame = videocapture.retrieve() function_that_uses_frame(frame) time.sleep(0.5)
ret = capture.grab()
ret, frame = videocapture.retrieve()
最后,这个方法成功了,但它太脏了。我只需要每秒抓取几帧,所以暂时可以。对于上下文,我使用相机为ML模型生成一些数据,我的标签与捕获的内容相比不同步。
while True: ret = capture.grab() ret, frame = videocapture.retrieve() ret = capture.grab() ret, frame = videocapture.retrieve() function_that_uses_frame(frame) time.sleep(0.5)
q5lcpyga6#
我做了一个自适应系统,因为其他人在这里张贴在这里仍然导致有点不准确的帧表示,并有完全可变的结果取决于硬件。
from time import time#...cap = cv2.VideoCapture(url)cap_fps = cap.get(cv2.CAP_PROP_FPS)time_start = time()time_end = time_startwhile True: time_difference = int((((end_time-start_time))*cap_fps)+1) #Note that the 1 might be changed to fit script bandwidth for i in range(0, time_difference): a = cap.grab() _, frame = cap.read() time_start = time() #Put your code here variable = function(frame) #... time_end = time()
from time import time
#...
cap = cv2.VideoCapture(url)
cap_fps = cap.get(cv2.CAP_PROP_FPS)
time_start = time()
time_end = time_start
time_difference = int((((end_time-start_time))*cap_fps)+1) #Note that the 1 might be changed to fit script bandwidth
for i in range(0, time_difference):
a = cap.grab()
_, frame = cap.read()
#Put your code here
variable = function(frame)
time_end = time()
这样,跳过的帧适应于视频流中丢失的帧的量-允许更平滑的过渡和相对实时的帧表示。
6条答案
按热度按时间xmjla07d1#
我也遇到了同样的问题。似乎一旦VideoCapture对象被初始化,它就一直将帧存储在某种缓冲区中,并为每次读取操作返回一个帧。我所做的是每次我想读取帧时都初始化VideoCapture对象,然后释放流。下面的代码以10秒的间隔捕获10张图像并存储它们。同样可以使用while(True)在循环中。
pxiryf3j2#
我也遇到了同样的问题,并找到了一个Azure samples的git仓库,用于他们的计算机视觉服务。相关的部分是Camera Capture module,特别是Video Stream class。
你可以看到他们已经实现了一个更新的队列,只保留最新的帧:
cclgggtu3#
我和一个朋友在做同样的事情。我们不想使用所有的帧。到目前为止,我们发现了非常相同的事情:
grab()
(或read)试图让你所有的帧,我猜是grab()
:它会保持一个缓冲区,如果你不够响应,它会放弃。除了read,你也可以使用grab()和receive()。第一个请求帧。receive将其读入内存。所以如果你多次调用grab,它将有效地跳过那些帧。
我们这样做了:
不是生产代码,而是...
s3fp2yjn4#
在“while”中,您可以使用:用途:
qybjjes15#
使用下面的方法给我带来了很多问题。传递给函数的帧不是序列化的。
下面的建议也不适用于我,正如其他评论所建议的那样。我仍然对最近的帧有问题。
最后,这个方法成功了,但它太脏了。我只需要每秒抓取几帧,所以暂时可以。对于上下文,我使用相机为ML模型生成一些数据,我的标签与捕获的内容相比不同步。
q5lcpyga6#
我做了一个自适应系统,因为其他人在这里张贴在这里仍然导致有点不准确的帧表示,并有完全可变的结果取决于硬件。
这样,跳过的帧适应于视频流中丢失的帧的量-允许更平滑的过渡和相对实时的帧表示。