Opencv视频捕获集CV\u CAP\u PROP\u POS\u帧不工作
我使用opencv从使用mpeg压缩的Vivotek摄像机输出的视频中读取帧。我正在尝试使用该功能从特定位置启动视频,如下所示,其中start是我要跳过的帧数Opencv视频捕获集CV\u CAP\u PROP\u POS\u帧不工作,opencv,Opencv,我使用opencv从使用mpeg压缩的Vivotek摄像机输出的视频中读取帧。我正在尝试使用该功能从特定位置启动视频,如下所示,其中start是我要跳过的帧数 inputVideo.set(CV_CAP_PROP_POS_FRAMES, start); 然而,我有一个问题,这是因为不正确的帧被捕获之前发生的帧开始 我使用的是opencv版本2.4.2 有人能帮我解决这个问题吗?有点晚了,但搜索同一个主题(不针对Vivotek Camera,但更多关于openCV的mpeg问题): 视频是经
inputVideo.set(CV_CAP_PROP_POS_FRAMES, start);
然而,我有一个问题,这是因为不正确的帧被捕获之前发生的帧开始
我使用的是opencv版本2.4.2
有人能帮我解决这个问题吗?有点晚了,但搜索同一个主题(不针对Vivotek Camera,但更多关于openCV的mpeg问题):
- 视频是经过编码的
- OpenCV使用FFMPEG
- 编码使用关键帧
- 跳过某些帧时,编码无法提供所需的确切帧
- 使用带有轨迹栏的openCV 2.4.8/VS2013的示例代码:
- 使用AVI格式测试[MPEG4视频(H264)]:设置帧位置效果良好
- 使用MPG格式[MPEG1/MPEG2]进行测试:设置帧位置效果良好
double currentPos = capture.get(CV_CAP_PROP_POS_FRAMES); std::cout << "CV_CAP_PROP_POS_FRAMES = " << currentPos << std::endl; // position_slider 0 - 100 double noFrame = position_slider*nbFrames / 100; // solution 1 bool success = capture.set(CV_CAP_PROP_POS_FRAMES, noFrame); // solution 2 double frameRate = capture.get(CV_CAP_PROP_FPS); double frameTime = 1000.0 * noFrame / frameRate; bool success = capture.set(CV_CAP_PROP_POS_MSEC, frameTime); if (!success) { std::cout << "Cannot set frame position from video file at " << noFrame << std::endl; return; } currentPos = capture.get(CV_CAP_PROP_POS_FRAMES); if (currentPos != noFrame) { std::cout << "Requesting frame " << noFrame << " but current position == " << currentPos << std::endl; } success = capture.read(frame_aux); if (!success) { std::cout << "Cannot get frame from video file " << std::endl; return; } imshow("test", frame_aux);
double currentPos=capture.get(CV\u CAP\u PROP\u POS\u帧);
正如BlouBlou所说,当你用FFMPEG阅读一些高压缩视频格式时,它使用“关键帧”技术来解码视频。因此,设置
属性将无法按您所需工作 我测试了5个mpeg视频以读取其中的所有帧。使用CV\u CAP\u PROP\u POS\u FRAMES
longtotalframenumber=capture.Get(CV\u CAP\u PROP\u frame\u count)获取总帧数代码> 然后我把每个视频读了两遍,第一次不设置
为0,第二次设置它 当您将CV\u CAP\u PROP\u POS\u FRAMES
设置为0时,它确实删除了一些帧,每个视频大约10帧。我猜是因为关键帧不在视频的第一帧中,所以FFMPEG会将一些帧跳过到第一个关键帧。但是一些视频格式,如.avi,不会出现这样的问题。我希望我的真实经历能为其他人节省很多时间(我花在寻找这个页面上的时间不长,但足够了)CV\u CAP\u PROP\u POS\u frames
无论如何,当您面对mpeg格式的视频时,强烈建议不要使用
获取特定帧。设置CV\u CAP\u PROP\u POS\u FRAMES
:)是一个明智的选择,如果您愿意升级到OpenCV 3.0,以下两个用例可能会对您有所帮助。这可能适用于早期版本,但我还没有尝试过如果希望它捕获帧a和帧b之间的所有帧,请参考第二个用例,并将“所需帧”替换为:CV\u CAP\u PROP\u POS\u MSEC
desired_frames = range(a,b)
首先,导入一些包 每n秒捕获一次(此处,n=5) 或者,每n帧捕获一次(此处,n=10) 差不多就是这样
一些不幸的警告…根据您的opencv版本(这是为opencv V3构建的),您可能需要以不同的方式设置fps变量。有关详细信息,请参阅。要了解您的版本,您可以执行以下操作:(major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.') major_ver
奇怪的是,我面前有一个assert
inputVideo.set(CV_CAP_PROP_POS_FRAMES, start);
删除
解决了问题如何知道帧不正确?assert
#################### Setting up the file ################ videoFile = "Jumanji.mp4" vidcap = cv2.VideoCapture(videoFile) success,image = vidcap.read() #################### Setting up parameters ################ seconds = 5 fps = vidcap.get(cv2.CAP_PROP_FPS) # Gets the frames per second multiplier = fps * seconds #################### Initiate Process ################ while success: frameId = int(round(vidcap.get(1))) #current frame number, rounded b/c sometimes you get frame intervals which aren't integers...this adds a little imprecision but is likely good enough success, image = vidcap.read() if frameId % multiplier == 0: cv2.imwrite("FolderSeconds/frame%d.jpg" % frameId, image) vidcap.release() print "Complete"
#################### Setting up the file ################ videoFile = "Jumanji.mp4" vidcap = cv2.VideoCapture(videoFile) success,image = vidcap.read() #################### Setting up parameters ################ #OpenCV is notorious for not being able to good to # predict how many frames are in a video. The point here is just to # populate the "desired_frames" list for all the individual frames # you'd like to capture. fps = vidcap.get(cv2.CAP_PROP_FPS) est_video_length_minutes = 3 # Round up if not sure. est_tot_frames = est_video_length_minutes * 60 * fps # Sets an upper bound # of frames in video clip n = 5 # Desired interval of frames to include desired_frames = n * np.arange(est_tot_frames) #################### Initiate Process ################ for i in desired_frames: vidcap.set(1,i-1) success,image = vidcap.read(1) # image is an array of array of [R,G,B] values frameId = vidcap.get(1) # The 0th frame is often a throw-away cv2.imwrite("FolderFrames/frame%d.jpg" % frameId, image) vidcap.release() print "Complete"
(major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.') major_ver
inputVideo.set(CV_CAP_PROP_POS_FRAMES, start);