繁体   English   中英

OpenCV (Python) VideoCapture.read() 丢失帧

[英]OpenCV (Python) VideoCapture.read() on missing frames

New to python, new to OpenCV, which I'm gonna use for my master-thesis, and already got some problems using the VideoCapture object of OpenCV.

情况:我有 2 个包含相应图像的文件夹(使用 RGB 和红外相机拍摄)。 我想使用 while 循环在 Window 中并排显示它们。 当其中一个图像序列中缺少一些图像时,问题就出现了(由于记录时的问题或其他原因,我真的不知道,但这应该不重要)。 我的想法是使用 the.read() function 的布尔返回值来检查是否有要读取的帧,如果没有,则将图像替换为黑色。 这就是我所做的:

代码:

import cv2
import numpy as np

pathRGB = "Bilder/RGB"
pathIR = "Bilder/IR"
# the paths to the folders containing the images

capRGB = cv2.VideoCapture(pathRGB + "/frame_%06d.jpg")
capIR = cv2.VideoCapture(pathIR + "/frame_%06d.jpg")
# setting up the VideoCapture-elements with the according format

shapeRGB = capRGB.read()[1].shape
shapeIR = capIR.read()[1].shape
# get the shape of the first image in each folder to later create the black
# dummy-image

dtypeRGB = capRGB.read()[1].dtype
dtypeIR = capIR.read()[1].dtype
# get the type of the first image in each folder to later create the black
# dummy-image

if (capRGB.isOpened() is False):
    print("Error opening RGB images")
if (capIR.isOpened() is False):
    print("Error opening IR images")

cv2.namedWindow("frames", cv2.WINDOW_NORMAL)

while capRGB.isOpened() and capIR.isOpened() is True:
    retRGB, imgRGB = capRGB.read()
    retIR, imgIR = capIR.read()
    # read both images

    if retRGB is True and retIR is False:
        imgIR = np.zeros(shapeIR, dtype=dtypeIR)
    # if there is no IR image, crate a dummy one
    if retIR is True and retRGB is False:
        imgRGB = np.zeros(shapeRGB, dtype=dtypeRGB)
    # if there is no RGB image, crate a dummy one
    if retRGB is False and retIR is False:
        break

    imgCombined = np.hstack((imgRGB, imgIR))
    # put both images together
    cv2.imshow("frames", imgCombined)
    k = cv2.waitKey(1)
    if k == ord("q"):
        break

capRGB.release()
capIR.release()
cv2.destroyAllWindows()

问题:据我了解,问题出现在 capIR.read() 尝试读取丢失的图像(在我的情况下为第 527 个)而不是仅返回 false/None 时,它会尝试一遍又一遍地读取相同的图像。 直到丢失帧,一切正常,右侧的“IR”图像甚至变黑,但随后视频播放开始变慢,虽然我仍然可以通过按“q”关闭 window,但 spyder IDE 冻结,如果我等待“太长”我什至不得不关闭它。 控制台一遍又一遍地发出“[image2 @ 000002a7af8f0480] 无法打开文件:Bilder/IR/frame_000527.jpg”,以至于我无法滚动到顶部。 我想我要问的是:有什么方法可以使 the.read() function 只尝试 1 次读取,然后在失败后继续下一帧?

最好的问候,并在此先感谢您!

假设 directory1 中的图像与 directory2 图像具有相同的名称,但我们知道某些图像可能不存在于两个目录中......

import glob,os,cv2

path1 = "folder1/"
path2 = "folder2/"

l1 = glob.glob(path1+"*.jpg")
l2 = glob.glob(path2+"*.jpg")#not used 

blackimg = cv2.imread("blackimg.jpg")

for fname in l1:

    #check if image1 exists , then read it .  otherwise im1 = blackimg
    if os.path.isfile(path1+fname):
        im1=cv2.imread(path1+fname)
    else:
        im1=blackimg
    
    #check if image2 exists , then read it .  otherwise im2 = blackimg
    if os.path.isfile(path2+fname):
        im2=cv2.imread(path2+fname)
    else:
        im2=blackimg

    imgCombined = np.hstack((im1, im2))


    cv2.imshow("Combined", imgCombined)
    print("press any key to continue, q to exit")
    k = cv2.waitKey(0) 
    if k == ord("q"):break


cv2.destroyAllWindows()

模拟使用不同的文件和目录名称进行测试。

将从两个目录中检索最大的帧号,然后遍历所有帧号以从两个目录中读取文件。

import os
import cv2
import re
import glob

image_dir1 = 'test1'
image_dir2 = 'test2'

# retrieve all frames in both directories
frames_cap1 = glob.glob(os.path.join(image_dir1, "frame_*.jpg"))
frames_cap2 = glob.glob(os.path.join(image_dir2, "frame_*.jpg"))

# sort inscending
frames_cap1.sort()
frames_cap2.sort()

# retrieve last frame No for both directories
last_frame_cap1 = frames_cap1[-1]
last_frame_cap2 = frames_cap2[-1]

# extract integer counter
match_cap1 = re.search('frame_(\d+).jpg', last_frame_cap1)
match_cap2 = re.search('frame_(\d+).jpg', last_frame_cap2)
last_frame_no_cap1 = int(match_cap1.group(1))
last_frame_no_cap2 = int(match_cap2.group(1))

# retrieve max frame No
max_frame_no = max(last_frame_no_cap1, last_frame_no_cap2)

for i in range(max_frame_no + 1):
    image_path_cap1 = os.path.join(image_dir1, f"frame_{i:06d}.jpg")
    image_path_cap2 = os.path.join(image_dir2, f"frame_{i:06d}.jpg")
    
    if not os.path.isfile(image_path_cap1):
        print(f"handle missing file: '{image_path_cap1}'")
        # ...
    else:
        img1 = cv2.imread(image_path_cap1)
        # …

    if not os.path.isfile(image_path_cap2):
        print(f"handle missing file: '{image_path_cap2}'")
        # ...
    else:
        img2 = cv2.imread(image_path_cap2)
        # …
# …

暂无
暂无

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

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