如何使用OpenCV(Python)读取没有循环的视频文件(Mac OS)?

我正在
python中编写一个简单的OpenCV脚本来进行一些机器学习.我想为它提供一系列视频文件,它将处理它然后退出并吐出一些参数.但是,当我用cv2.VideoCapture打开一个视频文件时,它无限循环.如何在视频结束时检测到?

**编辑**所以有些人注意到当读取文件结束时应该返回一个空框架.我试着寻找它,它可以在我的Linux机器上运行但不在我的机器上.在mac上,它只是循环并继续运行,好像文件没有结束一样.有任何想法吗?

读取循环的代码如下所示,除非我按下esc键,否则它会无限循环.

cam = cv2.VideoCapture(sourceVideo)            
while True:
    ret, img = cam.read()                      
    cv2.imshow('detection', img)
    print ret
    if (0xFF & cv2.waitKey(5) == 27) or img.size == 0:
        break

请注意,ret始终返回True,并且img始终是有效数据.是否有可能我不应该使用VideoCapture()来进行这种阅读?我不想使用旧的cv命令,因为我需要使用cv2使用的NumPy数组.

**编辑**好的,找到了合理的解决方案.我发现至少有一个人在Mac OS中遇到过类似的问题:OpenCV capture loops video/Does not detect last frame

我的猜测是,我们在Mac OS中使用OpenCV设置或以某种方式使用文件格式存在问题.

正确的解决方案通常是检查返回帧的类型,所以这应该工作:

    cam = cv2.VideoCapture(sourceVideo)            
    while True:
        ret, img = cam.read()                      
        if (type(img) == type(None)):
            break

        cv2.imshow('detection', img)
        print ret
        if (0xFF & cv2.waitKey(5) == 27) or img.size == 0:
            break

但是,如果您遇到问题,则无法检测到最终帧.无论如何,有一个合理的解决方法,即检查文件中的帧数并简单地跟踪.

    framecount = cam.get(cv2.cv.CV_CAP_PROP_FRAME_COUNT)

    frames = 0
    while frames < framecount:
        ret, img = cam.read()  
        frames += 1     

        if (type(img) == type(None)):
            break

        cv2.imshow('detection', img)
        print ret
        if (0xFF & cv2.waitKey(5) == 27) or img.size == 0:
            break

最佳答案 如果视频文件已成功打开,请不要忘记添加检查.

if( !cam.isOpened() )
  throw "Error when reading image file";

通过在循环中将它们管道化为cv :: Mat来抓取帧

Mat frame;

for( ; ; )
{
    cam >> frame;
    if(!frame)
        break;
    imshow("w", frame);
    waitKey(20);
}

帧为false后,循环应正确终止.

为了也完全终止循环你可以做到

cam.get(CV_CAP_PROP_FRAME_COUNT)

获得确切的帧数.无法循环获取视频是不可能的,因为它以增量方式读取.你可以将它包装成一个单独的函数.

点赞