我正在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
答案 0 :(得分:2)
如果视频文件已成功打开,请不要忘记添加支票。
if( !cam.isOpened() )
throw "Error when reading image file";
通过在循环中将它们管道化为cv :: Mat来抓取帧
Mat frame;
for( ; ; )
{
cam >> frame;
if(!frame)
break;
imshow("w", frame);
waitKey(20);
}
在frame为false之后,循环应该正确终止。
为了完全终止循环,你可以做到
cam.get(CV_CAP_PROP_FRAME_COUNT)
获取确切的帧数。无法循环获取视频是不可能的,因为它以增量方式读取。你可以将它包装成一个单独的函数。