I am trying to sample every 5th frame from a source. I can either iterate through the frames and pick every 5th frame and discard the rest like:
def sample_video_loop(capture, sampling_gap=5, batch_size=5):
frames = []
for i in range(batch_size):
for j in range(sampling_gap):
ret, f0 = capture.read()
frames += [f0]
return frames
Or I can use the VideoCapture set()
method to set the property cv2.CAP_PROP_POS_FRAMES
to like:
def sample_video_set_pos(capture, sampling_gap=5, batch_size=5):
frames = []
pos = 0
for i in range(batch_size):
ret, f0 = capture.read()
pos += sampling_gap
capture.set(cv2.CAP_PROP_POS_FRAMES, pos)
frames += [f0]
return frames
Without checking the implementation ideally the latter method should be faster. But when i timed it, it is 3-4 times slower.
%%timeit
frames = sample_video_loop(dataset, 5, 5)
>>> 98.4 ms ± 5.49 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%%timeit
frames = sample_video_set_pos(dataset, 5, 5)
>>> 305 ms ± 16.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
Is this a bug or am i missing something? If not then what is the best practice to sample frames?
Thanks in advance.