[FFmpeg-user] fftfilt

Michael Koch astroelectronic at t-online.de
Thu Oct 14 00:52:39 EEST 2021


Am 13.10.2021 um 23:09 schrieb Michael Koch:
> Am 13.10.2021 um 22:57 schrieb Paul B Mahol:
>> On Wed, Oct 13, 2021 at 10:51 PM Michael Koch 
>> <astroelectronic at t-online.de>
>> wrote:
>>
>>> Am 12.10.2021 um 19:29 schrieb Michael Koch:
>>>> Am 12.10.2021 um 18:52 schrieb Paul B Mahol:
>>>>> On Tue, Oct 12, 2021 at 10:55 AM Michael Koch
>>>>> <astroelectronic at t-online.de>
>>>>> wrote:
>>>>>
>>>>>> I have a question about the "fftfilt" filter. What's the default 
>>>>>> value
>>>>>> of the weight_U and weight_V options? I'm asking because I get an
>>>>>> unexpected result.
>>>>>>
>>>>>> This command line creates my input image for testing:
>>>>>>
>>>>>> ffmpeg -f lavfi -i color=black:s=300x50 -lavfi
>>>>>>
>>> drawgrid=c=white:y=-1:w=2:h=51,split[a][b];[b]crop=iw/2:x=0,scale=2*iw:ih:flags=neighbor,split[b][c];[c]crop=iw/2:x=0,scale=2*iw:ih:flags=neighbor,split[c][d];[d]crop=iw/2:x=0,scale=2*iw:ih:flags=neighbor,split[d][e];[e]crop=iw/2:x=0,scale=2*iw:ih:flags=neighbor,split[e][f];[f]crop=iw/2:x=0,scale=2*iw:ih:flags=neighbor[f];[a][b][c][d][e][f]vstack=6,split[h][v];[v]transpose[v];[v][h]hstack 
>>>
>>>
>>>>>>
>>>>>> -frames 1 -y test.png
>>>>>>
>>>>>> This is the fftfilt lowpass example from the official documentation:
>>>>>>
>>>>>> ffmpeg -i test.png -vf 
>>>>>> fftfilt=dc_Y=0:weight_Y='squish((Y+X)/100-1)' -y
>>>>>> out1.png
>>>>>>
>>>>>> Problem: The output has a greenish tint.
>>>>>>
>>>>> Expressions by default for U and V are copied from Y if are unset.
>>>>> filter works only in YUV or gray space thus in above combination one
>>>>> gets
>>>>> green tint.
>>> I'm trying to make the filter's cutoff frequency independant of the
>>> image size. But that's not so easy because I don't know the size of the
>>> FFT array. It's calculated in vf_fftfilt.c lines 185 and 297.
>>> This calculation is difficult (and slow) to replicate in an expression,
>>> because either a loop or a logarithm is required.
>>> Would it be possible to add two new variables so that the FFT array 
>>> size
>>> can be used in an expression?
>>> ARRAY_H = 1 << rdft_hbits
>>> ARRAY_V = 1 << rdft_vbits
>>> It the array size is known, things would become much easier.
>>>
>> What are you attempting to do?
>
> In the current state the filter's cutoff frequency is a function of 
> image size. The cutoff frequency jumps by a factor 2 when the image 
> size increases from 230 to 232. That's because of the factor 10/9 in 
> line 185.
> I want to make the cutoff frequency independant of image size, and 
> therefore I need the array size.
> Will work for all types of filters: lowpass, highpass, bandpass and 
> notch.

You can reproduce that with these commands:

set "P=8"

rem  create 230x230 test image

ffmpeg -f lavfi -i color=black:s=230x230 -lavfi 
geq='r=127.5+127.5*cos((X-W/2)*PI/(pow(2,
(1+2*Y/H))))',colorchannelmixer=1:0:0:0:1:0:0:0:1:0:0:0,split[h][v];[v]transpose[v];[v][h]hstack 
-frames 1 -y test.png

rem  bandpass for wavelength 8 pixels

ffmpeg -i test.png -vf 
scale=2*iw:2*ih,fftfilt=dc_Y=128:dc_U=1:dc_V=1:weight_Y='between(hypot(Y/H,X/W),1.9/%P%,2.1/%P%)':weight_U=1:weight_V=1,scale=iw/2:ih/2 
-y out230.png

rem  create 232x232 test image

ffmpeg -f lavfi -i color=black:s=232x232 -lavfi 
geq='r=127.5+127.5*cos((X-W/2)*PI/(pow(2,
(1+2*Y/H))))',colorchannelmixer=1:0:0:0:1:0:0:0:1:0:0:0,split[h][v];[v]transpose[v];[v][h]hstack 
-frames 1 -y test.png

rem  bandpass for wavelength 8 pixels

ffmpeg -i test.png -vf 
scale=2*iw:2*ih,fftfilt=dc_Y=128:dc_U=1:dc_V=1:weight_Y='between(hypot(Y/H,X/W),1.9/%P%,2.1/%P%)':weight_U=1:weight_V=1,scale=iw/2:ih/2 
-y out232.png
pause


I did already try to make the cutoff frequency independant on image size 
by using X/W and Y/H. That works fine if the image size is halved or 
doubled. But it doesn't work if the image size is increased by a smaller 
factor.
I think the correct way is to use X/ARRAY_H and Y/ARRAY_V

Michael



More information about the ffmpeg-user mailing list