在Python中使用OpenCV VideoCapture获取当前帧

o4tp2gmn  于 2023-10-24  发布在  Python
关注(0)|答案(6)|浏览(263)

我正在使用cv2.VideoCapture在python脚本中读取RTSP视频链接的帧。.read()函数在每秒运行一次的while循环中,然而,我没有从流中获得最新的帧。我得到了旧帧,这样我的滞后就建立了。无论如何,我可以获得最新的帧,而不是已经进入VideoCapture对象的旧帧吗?

xmjla07d

xmjla07d1#

我也遇到了同样的问题。似乎一旦VideoCapture对象被初始化,它就一直将帧存储在某种缓冲区中,并为每次读取操作返回一个帧。我所做的是每次我想读取帧时都初始化VideoCapture对象,然后释放流。下面的代码以10秒的间隔捕获10张图像并存储它们。同样可以使用while(True)在循环中。

  1. for x in range(0,10):
  2. cap = cv2.VideoCapture(0)
  3. ret, frame = cap.read()
  4. cv2.imwrite('test'+str(x)+'.png',frame)
  5. cap.release()
  6. time.sleep(10)
pxiryf3j

pxiryf3j2#

我也遇到了同样的问题,并找到了一个Azure samples的git仓库,用于他们的计算机视觉服务。相关的部分是Camera Capture module,特别是Video Stream class
你可以看到他们已经实现了一个更新的队列,只保留最新的帧:

  1. def update(self):
  2. try:
  3. while True:
  4. if self.stopped:
  5. return
  6. if not self.Q.full():
  7. (grabbed, frame) = self.stream.read()
  8. # if the `grabbed` boolean is `False`, then we have
  9. # reached the end of the video file
  10. if not grabbed:
  11. self.stop()
  12. return
  13. self.Q.put(frame)
  14. # Clean the queue to keep only the latest frame
  15. while self.Q.qsize() > 1:
  16. self.Q.get()
展开查看全部
cclgggtu

cclgggtu3#

我和一个朋友在做同样的事情。我们不想使用所有的帧。到目前为止,我们发现了非常相同的事情:grab()(或read)试图让你所有的帧,我猜是grab():它会保持一个缓冲区,如果你不够响应,它会放弃。
除了read,你也可以使用grab()和receive()。第一个请求帧。receive将其读入内存。所以如果你多次调用grab,它将有效地跳过那些帧。
我们这样做了:

  1. #show some initial image
  2. while True:
  3. cv2.grab()
  4. if cv2.waitKey(10):
  5. im = cv2.receive()
  6. # process
  7. cv2.imshow...

不是生产代码,而是...

s3fp2yjn

s3fp2yjn4#

在“while”中,您可以使用:用途:

  1. while True:
  2. cap = cv2.VideoCapture()
  3. urlDir = 'rtsp://ip:port/h264_ulaw.sdp'
  4. cap.open(urlDir)
  5. # get the current frame
  6. _,frame = cap.read()
  7. cap.release() #releasing camera
  8. image = frame
qybjjes1

qybjjes15#

使用下面的方法给我带来了很多问题。传递给函数的帧不是序列化的。

  1. cap = cv2.VideoCapture(0)
  2. while True:
  3. ret, frame = cap.read()
  4. function_that_uses_frame(frame)
  5. time.sleep(0.5)

下面的建议也不适用于我,正如其他评论所建议的那样。我仍然对最近的帧有问题。

  1. cap = cv2.VideoCapture(0)
  2. while True:
  3. ret = capture.grab()
  4. ret, frame = videocapture.retrieve()
  5. function_that_uses_frame(frame)
  6. time.sleep(0.5)

最后,这个方法成功了,但它太脏了。我只需要每秒抓取几帧,所以暂时可以。对于上下文,我使用相机为ML模型生成一些数据,我的标签与捕获的内容相比不同步。

  1. while True:
  2. ret = capture.grab()
  3. ret, frame = videocapture.retrieve()
  4. ret = capture.grab()
  5. ret, frame = videocapture.retrieve()
  6. function_that_uses_frame(frame)
  7. time.sleep(0.5)
展开查看全部
q5lcpyga

q5lcpyga6#

我做了一个自适应系统,因为其他人在这里张贴在这里仍然导致有点不准确的帧表示,并有完全可变的结果取决于硬件。

  1. from time import time
  2. #...
  3. cap = cv2.VideoCapture(url)
  4. cap_fps = cap.get(cv2.CAP_PROP_FPS)
  5. time_start = time()
  6. time_end = time_start
  7. while True:
  8. time_difference = int((((end_time-start_time))*cap_fps)+1) #Note that the 1 might be changed to fit script bandwidth
  9. for i in range(0, time_difference):
  10. a = cap.grab()
  11. _, frame = cap.read()
  12. time_start = time()
  13. #Put your code here
  14. variable = function(frame)
  15. #...
  16. time_end = time()

这样,跳过的帧适应于视频流中丢失的帧的量-允许更平滑的过渡和相对实时的帧表示。

展开查看全部

相关问题