I need a very fast atan2
for getting the gradient out of the sobel values (I'm implementing canny edge algo.). Does anyone know a very fast implementation, preferable in intrinsics (SIMD) or a very fast approximation. (I think an approximation is enough, because the values are rounded to 0°, 45°, 90°, 135°)
ADD: I'm aware of Intel's IPP atan2 in SVML unfortunately I can't use it.
It seems that you want to round to an octant number, presumably from -22.5°
to 337.5°
in 45°
increments.
The octants are separated by four lines through the origin with equation
Y = X tan(Θ),
or
a.Y - b.X = 0.
with suitable scaling factors.
By computing the signs of these expressions for the four desired angles, you will find the octant. By a clever combination, you can limit to three sign evaluations, as there are 8=2³
possibilities.
It is likely that this can be evaluated with SIMD instructions by computing the discriminant expressions, their signs, and suitable combinations of their signs, but this isn't trivial.
Probably a conversion to a multiple of 45° isn't necessary, not even a sequential numbering. It all depends on what you do with the octant information.
Additional SIMD suggestion:
With preloaded coefficients, you can compute all four line equations in a single go for an (X, Y) pair, using 16 bits integer arithmetic (possibly with multiply-and-add). Then get the signs and pack them to four bits with _mm_movemask_epi8
. Use the four bit value as input to a small lookup table.