繁体   English   中英

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

[英]Getting current frame with OpenCV VideoCapture in Python

我正在使用 cv2.VideoCapture 在 python 脚本中读取 RTSP 视频链接的帧。 .read() 函数在一个每秒运行一次的 while 循环中,但是,我没有从流中获取最新的帧。 我得到较旧的框架,这样我的滞后就会增加。 无论如何,我可以获得最新的帧,而不是通过管道传输到 VideoCapture 对象的旧帧吗?

我也面临同样的问题。 似乎一旦 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)

我遇到了同样的问题,并为他们的计算机视觉服务找到了Azure 示例的 git 存储库。 相关部分是Camera Capture 模块,特别是Video Stream 类

您可以看到他们已经实现了一个正在更新的队列以仅保留最新帧:

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

我正在和一个黑客的朋友一起做同样的事情。 我们不想使用所有的帧。 到目前为止,我们发现了同样的事情: grab() (或读取)试图获取所有帧,我猜想使用 rtp:如果您没有足够的响应,它将保持一个缓冲区并丢弃。

除了读取,您还可以使用grab() 和receive()。 第一个要求框架。 接收将其读入内存。 因此,如果您多次调用grab,它将有效地跳过这些。

我们逃脱了这样做:

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

不是生产代码,但...

使用以下内容给我带来了很多问题。 传递给函数的帧不是顺序的。

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)

在“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

我制作了一个自适应系统,因为此处发布的其他人仍然导致帧表示有些不准确,并且根据硬件的不同,结果完全不同。

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

通过这种方式,跳过的帧会适应视频流中丢失的帧数量 - 允许更平滑的过渡和相对实时的帧表示。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM