Reading in only specific video frames with readFrame

35 views (last 30 days)
Is there any way to read in only specified frames from a video using readFrame? It is possible using VideoReader.read, which accepts an "index" argument to specify which frames are to be read:
video = read(v,index)
But readFrame doesn't have the same option. The read function is being deprecated in a future release, and I would like to ensure that the code that I am writing will continue to work as long as possible into the future. Is this functionality being lost?
The code will potentially need to handle very large video files, so efficiency is important here - I can't just read in every single frame and discard the ones that are not required.
  2 Comments
Swarooph
Swarooph on 9 Aug 2016
The same documentation says VideoReader will replace this functionality. You can try using that. Although it does not seem to have the ability to read a particular frame #, it does have the ability to specify CurrentTime of frame and read between intervals.
Brian Tang
Brian Tang on 10 Aug 2016
Edited: Brian Tang on 10 Aug 2016
The VideoReader function that is replacing VideoReader.read is VideoReader.readFrame (hence the title of my question - though admittedly not the clearest wording ever); the problem is that for videos with unknown or variable frame rates, stepping through a video by time becomes (at best) unreliable.
As far as I can see, using VideoReader, there's no way to step through to the next frame (as opposed to jumping in time) without first reading the previous frame, which is rather inefficient. At present though, reading in the frame and discarding it just to move on to the next frame is the best option that I have come up with.

Sign in to comment.

Answers (2)

Patrick Feaster
Patrick Feaster on 1 Sep 2017
I ran into the same issue. The solution I came up with, presuming a constant frame rate, is to detect the video frame rate and then divide the desired frame index number, minus 1, by it. Thus, if you want frame index number 10 and your frame rate is 30 fps, set (10-1)/30 as the current time before using readFrame. Frame index number 1 comes out as (1-1)/30 = current time 0. The following function "readindex" can also substitute for "read" with an index specified and should continue to work after "read" is deprecated, with minimal alteration to existing code. Again, this would only work with a constant frame rate.
function outputFrame=readindex(videoSource,frameNumber)
info=get(videoSource);
videoSource.CurrentTime=(frameNumber-1)/info.FrameRate;
outputFrame=readFrame(videoSource);

Iris Hagoort
Iris Hagoort on 3 Jan 2017
Have you already found the solution? I also want to change my code so that it will stay functional in the future. I have build a GUI with a scroller, you can open the movie and use the scroller to go to the desired frame. Are there any other solutions?
  1 Comment
Brian Tang
Brian Tang on 10 Jan 2017
I never found a decent solution. My scroll bar doesn't need to access every single frame, so is driven based on time which works well enough. As far as being able to skip frames efficiently, I don't think it's possible using VideoReader.readFrame. As a workaround, I am telling my users to pre-process their videos externally to Matlab if they need to remove frames.

Sign in to comment.

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!