Opened 2 years ago

Closed 2 years ago

Last modified 10 months ago

#9617 closed defect (fixed)

v360: rounding or +-1 errors

Reported by: Michael Koch Owned by:
Priority: normal Component: avfilter
Version: git-master Keywords:
Cc: Blocked By:
Blocking: Reproduced by developer: no
Analyzed by developer: no

Description (last modified by Michael Koch)

I tested the v360 filter with all 36 combinations of these input/output formats: equirectangular, flat, fisheye, dfisheye, cylindrical and ball. The command lines are below.

I found the following problems:

eq2ball: in column y=0 there are 8 black pixels but 9 blue pixels, same problem in column y=179
eq2fish: unsymmetric behaviour in x and y axes, pixel 0,37 is red but pixel 37,0 is black
eq2dfish: the right circle has larger diameter than the left circle

fish2eq: the vertical line in the center is between x=88 and x=89, it should be wetween x=89 and x=90
fish2flat: that's clearly visible
fish2ball: the vertical line in the center is between x=88 and x=89, it should be wetween x=89 and x=90, same problem also for the horizontal line
fish2cyl: the vertical line in the center is between x=87 and x=88, it should be wetween x=89 and x=90

dfish2eq: error at right edge
dfish2dfish: unsymmetric behaviour in left circle, vertical line is between x=43 and x=44, but it should be between x=44 and x=45
dfish2cyl: error at 44,22 and right edege
dfish2ball: that's clearly unsymmetric

flat2eq: unsymmetric behaviour, compare rows y=15 and y=74
flat2fish: unsymmetric behaviour, compare rows y=15 and y=74
flat2dfish: unsymmetric behaviour, compare rows y=15 and y=74
flat2cyl: unsymmetric behaviour, compare rows y=0 and y=44
flat2ball: unsymmetric behaviour, compare row y=45 with row y=134, same problem also for columns x=45 and x=135

cyl2ball: unsymmetric behaviour, pixel 81,43 is black but pixel 81,135 is magenta
cyl2dfish: the right circle has larger diameter than the left circle
cyl2fish: unsymmetric behaviour, pixel 77,29 is red but pixel 77,151 is black

Here are the command lines for the test images and all 36 combinations:

ffmpeg -f lavfi -i color=black:s=180x90 -lavfi geq=r='255*mod(trunc(4*X/W),2)':g='255*trunc(2*X/W)':b='255*trunc(2*Y/H)' -frames 1 -y test.png
ffmpeg -i test.png -lavfi crop=90:90 -y test2.png

ffmpeg -i test.png -lavfi v360=e:e:h_fov=360:v_fov=180:interp=near -y eq2eq.png
ffmpeg -i test.png -lavfi
v360=e:flat:h_fov=120:v_fov=120:interp=near -y eq2flat.png
ffmpeg -i test.png -lavfi v360=e:fisheye:interp=near -y eq2fish.png
ffmpeg -i test.png -lavfi v360=e:dfisheye:h_fov=180:v_fov=180:interp=near -y eq2dfish.png
ffmpeg -i test.png -lavfi v360=e:cylindrical:h_fov=360:v_fov=120:interp=near -y eq2cyl.png
ffmpeg -i test.png -lavfi v360=e:ball:h_fov=180:v_fov=180:interp=near -y eq2ball.png

ffmpeg -i test.png -lavfi v360=flat:e:ih_fov=120:iv_fov=120:h_fov=360:v_fov=180:interp=near -y flat2eq.png
ffmpeg -i test.png -lavfi v360=flat:flat:ih_fov=120:iv_fov=120:h_fov=120:v_fov=120:interp=near -y flat2flat.png
ffmpeg -i test.png -lavfi v360=flat:fisheye:ih_fov=120:iv_fov=120:interp=near -y flat2fish.png
ffmpeg -i test.png -lavfi v360=flat:dfisheye:ih_fov=120:iv_fov=120:interp=near -y flat2dfish.png
ffmpeg -i test.png -lavfi v360=flat:cylindrical:ih_fov=120:iv_fov=120:h_fov=360:v_fov=120:interp=near -y flat2cyl.png
ffmpeg -i test.png -lavfi v360=flat:ball:ih_fov=120:iv_fov=120:interp=near -y flat2ball.png

ffmpeg -i test2.png -lavfi v360=fisheye:e:interp=near -y fish2eq.png
ffmpeg -i test2.png -lavfi v360=fisheye:flat:h_fov=120:v_fov=120:interp=near -y fish2flat.png
ffmpeg -i test2.png -lavfi v360=fisheye:fisheye:interp=near -y fish2fish.png
ffmpeg -i test2.png -lavfi v360=fisheye:dfisheye:interp=near -y fish2dfish.png
ffmpeg -i test2.png -lavfi v360=fisheye:cylindrical:h_fov=120:v_fov=120:interp=near -y fish2cyl.png
ffmpeg -i test2.png -lavfi v360=fisheye:ball:interp=near -y fish2ball.png

ffmpeg -i test.png -lavfi v360=dfisheye:e:interp=near -y dfish2eq.png
ffmpeg -i test.png -lavfi v360=dfisheye:flat:h_fov=120:v_fov=120:interp=near -y dfish2flat.png
ffmpeg -i test.png -lavfi v360=dfisheye:fisheye:interp=near -y dfish2fish.png
ffmpeg -i test.png -lavfi v360=dfisheye:dfisheye:interp=near -y dfish2dfish.png
ffmpeg -i test.png -lavfi v360=dfisheye:cylindrical:h_fov=360:v_fov=120:interp=near -y dfish2cyl.png
ffmpeg -i test.png -lavfi v360=dfisheye:ball:interp=near -y dfish2ball.png

ffmpeg -i test.png -lavfi v360=cylindrical:e:ih_fov=360:iv_fov=120:interp=near -y cyl2eq.png
ffmpeg -i test.png -lavfi v360=cylindrical:flat:ih_fov=360:iv_fov=120:h_fov=120:v_fov=120:interp=near -y cyl2flat.png
ffmpeg -i test.png -lavfi v360=cylindrical:fisheye:ih_fov=360:iv_fov=120:w=180:h=180:interp=near -y cyl2fish.png
ffmpeg -i test.png -lavfi v360=cylindrical:dfisheye:ih_fov=360:iv_fov=120:w=180:h=90:interp=near -y cyl2dfish.png
ffmpeg -i test.png -lavfi v360=cylindrical:cylindrical:ih_fov=360:iv_fov=120:h_fov=360:v_fov=120:interp=near -y cyl2cyl.png
ffmpeg -i test.png -lavfi v360=cylindrical:ball:ih_fov=360:iv_fov=120:w=180:h=180:interp=near -y cyl2ball.png

ffmpeg -i test2.png -lavfi v360=ball:e:interp=near -y ball2eq.png
ffmpeg -i test2.png -lavfi v360=ball:flat:h_fov=120:v_fov=120:interp=near -y ball2flat.png
ffmpeg -i test2.png -lavfi v360=ball:fisheye:interp=near -y ball2fish.png
ffmpeg -i test2.png -lavfi v360=ball:dfisheye:interp=near -y ball2dfish.png
ffmpeg -i test2.png -lavfi v360=ball:cylindrical:h_fov=360:v_fov=120:interp=near -y ball2cyl.png
ffmpeg -i test2.png -lavfi v360=ball:ball:interp=near -y ball2ball.png

Change History (10)

comment:1 by Balling, 2 years ago

What is the reference implementation of this insanity? I.e. what does google use?

comment:2 by Michael Koch, 2 years ago

Description: modified (diff)

comment:3 by Michael Koch, 2 years ago

All issues with (single-)fisheye as input have already been fixed.
Thank you!

comment:4 by Michael Koch, 2 years ago

The issues with double-fisheye as input can be fixed in line 3471:
uf = ew - 1.f - uf;

I don't fully understand why, but it seems to work.

Michael

comment:5 by Elon Musk, 2 years ago

Resolution: fixed
Status: newclosed

comment:6 by Michael Koch, 2 years ago

Resolution: fixed
Status: closedreopened

It's not yet fixed. The following four cases with double-fisheye input have wrong output:

ffmpeg -f lavfi -i color=black:s=180x90 -lavfi geq=r='255*mod(trunc(4*X/W),2)':g='255*trunc(2*X/W)':b='255*trunc(2*Y/H)' -frames 1 -y test.png

ffmpeg -i test.png -lavfi v360=dfisheye:e:interp=near -y dfish2eq.png
ffmpeg -i test.png -lavfi v360=dfisheye:dfisheye:interp=near -y dfish2dfish.png
ffmpeg -i test.png -lavfi v360=dfisheye:cylindrical:h_fov=360:v_fov=120:w=180:h=90:interp=near -y dfish2cyl.png
ffmpeg -i test.png -lavfi v360=dfisheye:ball:interp=near -y dfish2ball.png

As I already wrote, these issues can be fixed in line 3471:
uf = ew - 1.f - uf;

comment:7 by Elon Musk, 2 years ago

Resolution: fixed
Status: reopenedclosed

Near interpolation is not proof it needs fix.

in reply to:  7 comment:8 by Michael Koch, 2 years ago

Replying to Elon Musk:

Near interpolation is not proof it needs fix.

Near interpolation? Some pixels are mapped to the wrong octants!
In the dfish2dfish case the vertical line in the left circle is shifted one pixel to the left.
In the dfish2cyl and dfish2eq cases the error is clearly visible at the right edge.
In the dfish2ball case the error is clearly visible at the top and bottom.
All these issues can be fixed by subtracting 1 in line 3471.

comment:9 by Balling, 2 years ago

All these issues can be fixed by subtracting 1 in line 3471.

Send a patch then.

comment:10 by Balling, 10 months ago

Substracting 1 was done in e1974622e1e07bee1f6324be60bd0a97f1811b3f.

Note: See TracTickets for help on using tickets.