imageio-ffmpeg icon indicating copy to clipboard operation
imageio-ffmpeg copied to clipboard

Generator retrieves same image repeatedly when capturing from a webcam

Open asteppke opened this issue 1 year ago • 1 comments

Hello,

With the current imageio 2.31.5 and imageio-ffmpeg 0.4.9 and the following example feeding from a webcam (Logitech StreamCam)

import hashlib
import imageio.v3 as iio

for ix, image in enumerate(iio.imiter("<video0>", size=(1920, 1080), fps=10,)):
    print(hashlib.sha1(image).hexdigest())
    print(f"t: {time.time():.3f} s")

I get the same image several times in a row:

771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.138 s
771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.141 s
771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.145 s
771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.148 s
771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.151 s
771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.155 s
771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.158 s
771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.162 s
771638c35357c92136d5582d3ebbf344c57ca5bc
t: 1699022333.166 s
f19a6b1c5def51e98794025bb7733c846f7997f6
t: 1699022333.169 s
f19a6b1c5def51e98794025bb7733c846f7997f6
t: 1699022333.172 s
f19a6b1c5def51e98794025bb7733c846f7997f6
t: 1699022333.175 s
[...]

The webcam according to ffmpeg can output with a maximum fps of 60, but the imageio generator is yielding images roughly every 2-3 ms, so with more than 200 fps. Changing the fps parameter does not seem to have any influence on this high rate.

Is this expected behavior? Of course I can filter and discard all the extra images but that requires a lot of extra processing at this high rate.

asteppke avatar Nov 03 '23 14:11 asteppke

This is expected behavior for now, because ffmpeg will just read whatever is the current frame. Now that I'm writing this I wonder if there is a way to tell ffmpeg to wait for the next different frame 🤔

A solution could be to introduce your own time.sleep() (or await asyncio.sleep() if that applies).

This is a solution that we could fix in this library though, preferably via ffmpeg, but otherwise with a sleep() matching the video's fps. I'll change the issue tittle accordingly.

almarklein avatar Nov 13 '23 08:11 almarklein