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

o4tp2gmn  于 8个月前  发布在  Python
关注(0)|答案(6)|浏览(139)

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

xmjla07d

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)
pxiryf3j

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()
cclgggtu

cclgggtu3#

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

#show some initial image
while True:
    cv2.grab()
    if cv2.waitKey(10):
       im = cv2.receive()
       # process
       cv2.imshow...

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

s3fp2yjn

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
qybjjes1

qybjjes15#

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

cap = cv2.VideoCapture(0)

while True:
    ret, frame = cap.read()
    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)

最后,这个方法成功了,但它太脏了。我只需要每秒抓取几帧,所以暂时可以。对于上下文,我使用相机为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)
q5lcpyga

q5lcpyga6#

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

from time import time
#...
cap = cv2.VideoCapture(url)
cap_fps = cap.get(cv2.CAP_PROP_FPS)
time_start = time()
time_end = time_start
while 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()

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

相关问题