I have video footage shot at shutter speeds of 1/30s under artificial light here in Europe where the AC is 50Hz. Flicker occurs -- obviously I should have used 1/25s or 1/50s but I didn't, and want to save the footage.
I have tried different ffmpeg filters but none did work: deflicker for example is made specifically to remove frame-by-frame luminance changes (e.g., what happens in timelapse videos) but not to fix the banding that I see due to using a shutter speed not in sync with the frequency of the AC feeding the light bulb.
I have found some obscure reference to other ffmpeg filters like hqdn3d but the defaults did not work and I don't really understand how to play with the parameters and how to relate them to my specific case.
I'm looking for a command-line/open source solution (hence, ffmpeg) because my video editor is pretty basic (iMovie) and will not allow me to do tricks like shifting and blending footage.
UPDATE
I have found a 'quick tip' on Philip Bloom's blog that says:
[...] my quick trick fix [...] is simply duplicating layers, shifting top layer over by a frame and adding 50% opacity to it.
So I have spent an hour figuring out the arcane syntax of ffmpeg and tried to replicate the above steps:
$ ffmpeg -i FLICKER.mov -itsoffset 0.1 -i FLICKER.mov \
-filter_complex "[1:v]format=yuva420p,colorchannelmixer=aa=0.5[b]; \
[0:v][b]overlay" -map 0:1 NOFLICKER.mov
With this command I input twice the same input file, the second one is shifted by 0.1 second (-itsoffset 0.1
), a 0.5 transparency is applied in the -filter_complex
argument ([1:v]
means the video stream of the second file) and then overlaid on top of the video stream of the first file ([0:v]
). The audio track is simply copied from the first file (-map 0:1
).
The good news is that this works as expected, no more flickering. The problem is that I had to offset the second copy too much (0.1 seconds) so I have a very clear and evident shadow effect on my final output, not a faint and what would be acceptable motion blur if only I had it shifted by a single frame like in the Bloom's recipe above.
I think that is due to the fact that my original footage is not high-fps but only 24 fps. A shift of a single frame would have meant -itsoffset 0.0416
(1/24 s = 0.0416 s) and that shift doesn't really do anything. I've also tried to understand why a 0.1 second shift is so effective, but could not come up with any reasonable explanation (I thought that could have been related to the AC frequency is 1/50 Hz but that would've meant that a shift of 0.02 seconds would do something...).
Anyway, the problem remains. I could think of a possible solution where perhaps I could instruct ffmpeg to leave a user-selected portion of the footage free from the overlay and simply copy the original stream (that's because it's a footage of my daughter talking under artificial lights, and the flickering is very disturbing on the borders of the frame where it's all dark, but her face is relatively free from the flicker), or again, like I asked before, find one of the many filters in ffmpeg to work its charm.