I've noticed that the fft_flowvectors function can produce some erratic behaviour due to both inconsistent rounding between fft_flowvectors and fft_shift, and "Bankers Rounding" in numpy/python. Note fft_flowvectors uses np.round(dims/2, 0) (line 54 of phase_correlation.py) to get the "center" of the matrix, which is subject to Bankers Rounding, whereas fft_shift uses np.int(fft_mat.shape[0]/2) (lines 75 and 76 of phase_correlation.py) which always rounds down. These inconsistencies can produce errors of up to 2 pixels - consider the following examples.
import numpy as np
import tint
from tint.phase_correlation import fft_flowvectors
# 1 Pixel Error - odd and center rounds up
im1 = np.zeros((99,99))
im2 = np.zeros((99,99))
r = np.random.rand(5,5) * 100
im1[55:60,55:60] = r
im2[60:65,60:65] = r
s = fft_flowvectors(im1,im2)
print(s)
# 1 Pixel Error - even
im1 = np.zeros((100,100))
im2 = np.zeros((100,100))
r = np.random.rand(5,5) * 100
im1[55:60,55:60] = r
im2[60:65,60:65] = r
s = fft_flowvectors(im1,im2)
print(s)
# 2 Pixel Error - even and center rounds down
im1 = np.zeros((101,101))
im2 = np.zeros((101,101))
r = np.random.rand(5,5) * 100
im1[55:60,55:60] = r
im2[60:65,60:65] = r
s = fft_flowvectors(im1,im2)
print(s)
With the current version of TINT the above code would produce an output of
[6. 6.]
[6. 6.]
[7. 7.]
With the proposed pull the output would become
[5 5]
[5 5]
[5 5]
I considered many other similar examples with analogous results! Note the flow vectors are now integer arrays, but this doesn't appear to affect TINT downstream in any way.
I discovered this strange behaviour when I tried using the flow vectors to estimate object (in my case mesoscale convective system) velocities, calculated from a 2.5 km resolution radar dataset, with scans every 10 minutes. In this case, a 2 pixel error in each dimension corresponds to a velocity magnitude error of 11.8 m/s, and given that a typical system moves ~10 m/s my velocities also often pointed in the completely wrong direction! Note errors of 2 pixels will probably minimally affect TINT's object matching functions - especially in my case as my objects are generally large. However, because other users may also consider using the flow vectors as velocity estimates I think it's still worth considering this a bug.
The changes I've made to phase_correlation.py are very simple. I've just replaced the rounding functions in fft_flowvectors and fft_shift with np.ceil, and changed the final expression for pshift in fft_flowvectors to better reflect the way fft_shift actually determines the new ``center" point of the matrix.
I've noticed that the
fft_flowvectors
function can produce some erratic behaviour due to both inconsistent rounding betweenfft_flowvectors
andfft_shift
, and "Bankers Rounding" in numpy/python. Notefft_flowvectors
usesnp.round(dims/2, 0)
(line 54 of phase_correlation.py) to get the "center" of the matrix, which is subject to Bankers Rounding, whereasfft_shift
usesnp.int(fft_mat.shape[0]/2)
(lines 75 and 76 of phase_correlation.py) which always rounds down. These inconsistencies can produce errors of up to 2 pixels - consider the following examples.With the current version of TINT the above code would produce an output of
With the proposed pull the output would become
I considered many other similar examples with analogous results! Note the flow vectors are now integer arrays, but this doesn't appear to affect TINT downstream in any way.
I discovered this strange behaviour when I tried using the flow vectors to estimate object (in my case mesoscale convective system) velocities, calculated from a 2.5 km resolution radar dataset, with scans every 10 minutes. In this case, a 2 pixel error in each dimension corresponds to a velocity magnitude error of 11.8 m/s, and given that a typical system moves ~10 m/s my velocities also often pointed in the completely wrong direction! Note errors of 2 pixels will probably minimally affect TINT's object matching functions - especially in my case as my objects are generally large. However, because other users may also consider using the flow vectors as velocity estimates I think it's still worth considering this a bug.
The changes I've made to phase_correlation.py are very simple. I've just replaced the rounding functions in
fft_flowvectors
andfft_shift
withnp.ceil
, and changed the final expression for pshift infft_flowvectors
to better reflect the wayfft_shift
actually determines the new ``center" point of the matrix.