Skip to content
Snippets Groups Projects
Commit 57eaf6ac authored by Olivier Bertrand's avatar Olivier Bertrand
Browse files

Speed up OF calc

For loops on viewing directions have been removed.
It leads to 200x faster computation :)
parent c5a07b6c
No related branches found
No related tags found
No related merge requests found
This diff is collapsed.
...@@ -80,9 +80,9 @@ def optic_flow_rotationonal(viewing_directions, velocity): ...@@ -80,9 +80,9 @@ def optic_flow_rotationonal(viewing_directions, velocity):
# Check if rotation are not too large # Check if rotation are not too large
# because we assume small rotation # because we assume small rotation
# according to Koenderink van Dorn # according to Koenderink van Dorn
if ((np.abs(dyaw) > np.pi/2 and 2*np.pi - np.abs(dyaw) > np.pi/2) or if ((np.abs(dyaw) > np.pi / 2 and 2 * np.pi - np.abs(dyaw) > np.pi / 2) or
(np.abs(dpitch) > np.pi/2 and 2*np.pi - np.abs(dpitch) > np.pi/2) or (np.abs(dpitch) > np.pi / 2 and 2 * np.pi - np.abs(dpitch) > np.pi / 2) or
(np.abs(droll) > np.pi/2 and 2*np.pi - np.abs(droll) > np.pi/2)): (np.abs(droll) > np.pi / 2 and 2 * np.pi - np.abs(droll) > np.pi / 2)):
raise ValueError('rotation exceeds 90°, computation aborted') raise ValueError('rotation exceeds 90°, computation aborted')
# we init a matrix for rot # we init a matrix for rot
rof = np.zeros_like(elevation) rof = np.zeros_like(elevation)
...@@ -94,17 +94,22 @@ def optic_flow_rotationonal(viewing_directions, velocity): ...@@ -94,17 +94,22 @@ def optic_flow_rotationonal(viewing_directions, velocity):
M = compose_matrix(angles=[yaw, pitch, roll], translate=None, M = compose_matrix(angles=[yaw, pitch, roll], translate=None,
perspective=None, axes=convention)[:3, :3] perspective=None, axes=convention)[:3, :3]
angvel_bee = np.dot(M, angvel) angvel_bee = np.dot(M, angvel)
# project it on the eye # The spline express in the bee coordinate system
for i, (a, e) in enumerate(zip(azimuth, elevation)): spline = np.array(spherical_to_cartesian(elevation, azimuth))
# in the bee coordinate system # the Rotation-part of the Optic Flow in cartesian coord:
spline = np.array(spherical_to_cartesian(e, a)) # Cross product of angvel_bee and spline
opticFlowR = -np.cross(angvel_bee, spline) opticFlowR = np.zeros_like(spline)
# Decompose into el, az opticFlowR[2, :] = angvel_bee[0] * \
(OF_rho, OF_phi, OF_epsilon) = \ spline[1, :] - angvel_bee[1] * spline[0, :]
cartesian_to_spherical_vectors(opticFlowR, [a, e]) opticFlowR[1, :] = angvel_bee[2] * \
rof[i] = OF_rho spline[0, :] - angvel_bee[0] * spline[2, :]
hof[i] = OF_phi opticFlowR[0, :] = angvel_bee[1] * \
vof[i] = OF_epsilon spline[2, :] - angvel_bee[2] * spline[1, :]
opticFlowR = -opticFlowR
# opticFlow in spherical coordinate system
(rof, hof, vof) = cartesian_to_spherical_vectors(
opticFlowR, [azimuth, elevation])
# Reshape according to eye
rof = np.reshape(rof, final_shape) rof = np.reshape(rof, final_shape)
hof = np.reshape(hof, final_shape) hof = np.reshape(hof, final_shape)
vof = np.reshape(vof, final_shape) vof = np.reshape(vof, final_shape)
...@@ -148,7 +153,8 @@ def optic_flow_translational(distance, viewing_directions, ...@@ -148,7 +153,8 @@ def optic_flow_translational(distance, viewing_directions,
if(v == 0): if(v == 0):
u = [0, 0, 0] u = [0, 0, 0]
else: else:
u = u/np.linalg.norm(u) u = u / np.linalg.norm(u)
# we init a matrix for rot
# we init a matrix for rot # we init a matrix for rot
rof = np.zeros_like(elevation) rof = np.zeros_like(elevation)
hof = np.zeros_like(rof) hof = np.zeros_like(rof)
...@@ -157,22 +163,32 @@ def optic_flow_translational(distance, viewing_directions, ...@@ -157,22 +163,32 @@ def optic_flow_translational(distance, viewing_directions,
M = compose_matrix(angles=[yaw, pitch, roll], translate=None, M = compose_matrix(angles=[yaw, pitch, roll], translate=None,
perspective=None, axes=convention)[:3, :3] perspective=None, axes=convention)[:3, :3]
u_bee = M.dot(u) u_bee = M.dot(u)
for i, (a, e) in enumerate(zip(azimuth, elevation)): # The spline express in the bee coordinate system
# The spline express in the bee coordinate system spline = np.array(spherical_to_cartesian(elevation, azimuth))
spline = np.array(spherical_to_cartesian(e, a)) # the Translation-part of the Optic Flow:
# the Translation-part of the Optic Flow: dotvu = v * u_bee
dotvu = v*u_bee # cross product
opticFlowT = -np.cross(np.cross(spline, dotvu), spline) crossprod = np.zeros_like(spline)
# Decompose into el, az crossprod[2, :] = spline[0, :] * dotvu[1] - spline[1, :] * dotvu[0]
(OF_rho, OF_phi, OF_epsilon) = \ crossprod[1, :] = spline[2, :] * dotvu[0] - spline[0, :] * dotvu[2]
cartesian_to_spherical_vectors(opticFlowT, [a, e]) crossprod[0, :] = spline[1, :] * dotvu[2] - spline[2, :] * dotvu[1]
# Calc opticFlow in cartesian coordinate system
rof[i] = OF_rho opticFlowT = np.zeros_like(spline)
hof[i] = OF_phi opticFlowT[2, :] = crossprod[0, :] * \
vof[i] = OF_epsilon spline[1, :] - crossprod[1, :] * spline[0, :]
opticFlowT[1, :] = crossprod[2, :] * \
spline[0, :] - crossprod[0, :] * spline[2, :]
opticFlowT[0, :] = crossprod[1, :] * \
spline[2, :] - crossprod[2, :] * spline[1, :]
opticFlowT = -opticFlowT
# opticFlow in spherical coordinate system
(rof, hof, vof) = cartesian_to_spherical_vectors(
opticFlowT, [azimuth, elevation])
# Divide by distance
rof /= distance rof /= distance
hof /= distance hof /= distance
vof /= distance vof /= distance
# Reshpae according to eye
rof = np.reshape(rof, final_shape) rof = np.reshape(rof, final_shape)
hof = np.reshape(hof, final_shape) hof = np.reshape(hof, final_shape)
vof = np.reshape(vof, final_shape) vof = np.reshape(vof, final_shape)
...@@ -191,7 +207,7 @@ def optic_flow(distance, viewing_directions, velocity): ...@@ -191,7 +207,7 @@ def optic_flow(distance, viewing_directions, velocity):
rofr, hofr, vofr = optic_flow_rotationonal(viewing_directions, velocity) rofr, hofr, vofr = optic_flow_rotationonal(viewing_directions, velocity)
roft, hoft, voft = optic_flow_translational(distance, viewing_directions, roft, hoft, voft = optic_flow_translational(distance, viewing_directions,
velocity) velocity)
return rofr+roft, hofr+hoft, vofr+voft return rofr + roft, hofr + hoft, vofr + voft
class Module(): class Module():
...@@ -345,7 +361,7 @@ class lp(Module): ...@@ -345,7 +361,7 @@ class lp(Module):
In = self.inM.Input In = self.inM.Input
for i in range(self.size[0]): for i in range(self.size[0]):
for j in range(self.size[1]): for j in range(self.size[1]):
self.Input[i, j] += self.itau*(In[i, j]-self.Input[i, j]) self.Input[i, j] += self.itau * (In[i, j] - self.Input[i, j])
class hp(Module): # for second order just take hp for inM class hp(Module): # for second order just take hp for inM
...@@ -403,7 +419,7 @@ class hp(Module): # for second order just take hp for inM ...@@ -403,7 +419,7 @@ class hp(Module): # for second order just take hp for inM
In = self.inM.Input In = self.inM.Input
for i in range(self.size[0]): for i in range(self.size[0]):
for j in range(self.size[1]): for j in range(self.size[1]):
self.Input[i, j] = (In[i, j]-lpOut[i, j]) self.Input[i, j] = (In[i, j] - lpOut[i, j])
class mul(Module): class mul(Module):
...@@ -490,7 +506,7 @@ class mul(Module): ...@@ -490,7 +506,7 @@ class mul(Module):
for j in range(self.size[1]): for j in range(self.size[1]):
sig_left1 = self.inM1.Input[i, j] sig_left1 = self.inM1.Input[i, j]
sig_left2 = shiftedInput[i, j] sig_left2 = shiftedInput[i, j]
self.Input[i, j] = sig_left1*sig_left2 self.Input[i, j] = sig_left1 * sig_left2
class div(Module): class div(Module):
...@@ -578,6 +594,6 @@ class div(Module): ...@@ -578,6 +594,6 @@ class div(Module):
sig_left1 = self.inM1.Input[i, j] sig_left1 = self.inM1.Input[i, j]
sig_left2 = shiftedInput[i, j] sig_left2 = shiftedInput[i, j]
if sig_left2 != 0: if sig_left2 != 0:
self.Input[i, j] = sig_left1/sig_left2 self.Input[i, j] = sig_left1 / sig_left2
else: else:
self.Input[i, j] = 0 self.Input[i, j] = 0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment