Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 29-add-apply_func_on_time_window-time-version
  • 30-perform-data-augmentation
  • develop
  • main
  • v0.1.0-alpha
  • v0.2.0-alpha
6 results

Target

Select target project
  • raphael.sturgis/skais
1 result
Select Git revision
  • 29-add-apply_func_on_time_window-time-version
  • 30-perform-data-augmentation
  • develop
  • main
  • v0.1.0-alpha
  • v0.2.0-alpha
6 results
Show changes
Commits on Source (2)
import random
from copy import deepcopy
import numpy as np
from skais.utils.geometry import vectorize_angle, local_ref, transpose_matrix, \
quaternion_multiply, angleize_vector, rotation_quaternions, spherical_to_carthesian, carthesian_to_spherical, \
rotate_vector_by_quaternion
base_ref = np.array(
[
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
]
)
def shift_positions(aisPositions, axis_lat, axis_long, angle):
copy = deepcopy(aisPositions)
rotation_quaternion, inverse_rotation_quaternion = rotation_quaternions(axis_lat, axis_long, angle)
latitudes = np.radians(aisPositions.df['latitude'].to_numpy())
longitudes = np.radians(aisPositions.df['longitude'].to_numpy())
cogs = np.radians(aisPositions.df['cog'].to_numpy())
headings = np.radians(aisPositions.df['heading'].to_numpy())
for i in range(len(latitudes)):
lat = latitudes[i]
long = longitudes[i]
v_cog = vectorize_angle(cogs[i])
v_heading = vectorize_angle(headings[i])
new_position = rotate_vector_by_quaternion(spherical_to_carthesian(lat, long), rotation_quaternion, inverse_rotation_quaternion)
new_lat, new_long = carthesian_to_spherical(new_position)
origin_ref = local_ref(lat, long)
target_ref = local_ref(new_lat, new_long)
matrix_ob = transpose_matrix(origin_ref, base_ref)
matrix_bt = transpose_matrix(base_ref, target_ref)
# transpose vectors to base referential
v_cog = np.matmul(matrix_ob, v_cog)
v_heading = np.matmul(matrix_ob, v_heading)
# rotate vector
v_cog = rotate_vector_by_quaternion(v_cog, rotation_quaternion, inverse_rotation_quaternion)
v_heading = rotate_vector_by_quaternion(v_heading, rotation_quaternion, inverse_rotation_quaternion)
# transpose vector back to local referential of the new position
v_cog = np.matmul(matrix_bt, v_cog)
v_heading = np.matmul(matrix_bt, v_heading)
latitudes[i] = new_lat
longitudes[i] = new_long
cogs[i] = angleize_vector(v_cog)
headings[i] = angleize_vector(v_heading)
copy.df['latitude'] = np.degrees(latitudes)
copy.df['longitude'] = np.degrees(longitudes)
copy.df['cog'] = np.degrees(cogs)
copy.df['heading'] = np.degrees(headings)
return copy
import random
import numpy as np
from skais.learn.data_augmentation import shift_positions
class RandomAxisRotationEngine:
def __init__(self, shifts_per_trajectory=1):
self.shifts_per_trajectory = shifts_per_trajectory
def apply(self, trajectories, shuffle=True):
new_trajectories = []
for trajectory in trajectories:
for _ in range(self.shifts_per_trajectory):
new_trajectories.append(shift_positions(trajectory, random.uniform(0, 1)*np.pi - np.pi/2,
2*(random.uniform(0, 1)*np.pi) - np.pi,
2*(random.uniform(0, 1)*np.pi) - np.pi))
if not shuffle:
return new_trajectories
else:
return random.shuffle(new_trajectories)
import unittest
from skais.ais.ais_trajectory import AISTrajectory
from skais.learn.data_augmentation import *
import pandas as pd
class data_augmentation(unittest.TestCase):
def test_shift(self):
trajectory = AISTrajectory(
pd.DataFrame(
{
'ts_sec': [i for i in range(10)],
'latitude': [0 for _ in range(5)] + [45 for _ in range(5)],
'longitude': [0 for _ in range(10)],
'cog': [0 for _ in range(10)],
'heading': [90 for _ in range(10)]
}
)
)
shifted = shift_positions(trajectory, 0, 0, np.pi / 2)
self.assertTrue(True)
def test_shift_2(self):
trajectory = AISTrajectory(
pd.DataFrame(
{
'ts_sec': [i for i in range(10)],
'latitude': [0 for _ in range(10)],
'longitude': [-150, -120, -60, -30, 0, 30, 60, 120, 150, 180],
'cog': [0 for _ in range(10)],
'heading': [90 for _ in range(10)]
}
)
)
shifted = shift_positions(trajectory, 0, 0, np.pi / 2)
self.assertTrue(True)
def test_shift_3(self):
trajectory = AISTrajectory(
pd.DataFrame(
{
'ts_sec': [0],
'latitude': [-45],
'longitude': [45],
'cog': [45],
'heading': [120]
}
)
)
shifted = shift_positions(trajectory, np.pi/2, 0, np.pi / 2)
self.assertTrue(True)
import unittest
from skais.utils.geometry import bresenham
import numpy as np
from skais.process.geography import PI
from skais.utils.geometry import bresenham, vectorize_angle, transpose_matrix, vector_rotation, local_ref
class TestGeometry(unittest.TestCase):
......@@ -18,7 +21,6 @@ class TestGeometry(unittest.TestCase):
self.assertListEqual(result, expected)
def test_bresenham_inverted_2(self):
result = bresenham(16, 4, 3, 9)
expected = [(3, 9), (4, 9), (5, 8), (6, 8), (7, 7), (8, 7), (9, 7), (10, 6), (11, 6), (12, 6), (13, 5), (14, 5),
......@@ -37,6 +39,74 @@ class TestGeometry(unittest.TestCase):
self.assertListEqual(result, expected)
def test_vectorize_angle_0(self):
vectorized_angle = vectorize_angle(0)
np.testing.assert_almost_equal(vectorized_angle, np.array([1, 0, 0]))
def test_vectorize_angle_half_PI(self):
vectorized_angle = vectorize_angle(PI / 2)
np.testing.assert_almost_equal(vectorized_angle, np.array([0, 1, 0]))
def test_vectorize_angle_PI(self):
vectorized_angle = vectorize_angle(PI)
np.testing.assert_almost_equal(vectorized_angle, np.array([-1, 0, 0]))
def test_transpose_matrix_1(self):
origin = np.array(
[[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
)
target = np.array(
[[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
)
result = transpose_matrix(origin, target)
expected = np.array(
[[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
)
np.testing.assert_almost_equal(result, expected)
def test_transpose_matrix_2(self):
origin = np.array(
[[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]
)
target = np.array(
[[0, 1, 0],
[1, 0, 0],
[0, 0, 1]]
)
result = transpose_matrix(origin, target)
expected = np.array(
[[0, 1, 0],
[1, 0, 0],
[0, 0, 1]]
)
np.testing.assert_almost_equal(result, expected)
def test_rotate_vector(self):
result = vector_rotation(np.array([0, 0, 1]), 0, 0, np.pi / 2)
np.testing.assert_almost_equal(result, np.array([0, -1, 0]))
def test_local_ref_0(self):
result = local_ref(0, 0)
np.testing.assert_almost_equal(result, np.array([[0, 0, -1],
[0, 1, 0],
[1, 0, 0]]))
def test_local_ref_1(self):
result = local_ref(np.pi/2, 0)
np.testing.assert_almost_equal(result, np.array([[1, 0, 0],
[0, 1, 0],
[0, 0, 1]]))
if __name__ == '__main__':
unittest.main()
......@@ -4,7 +4,7 @@ from numba import jit
R = 6371000
@jit(nopython=True)
@jit(nopython=True, fastmath=True)
def great_circle(lat1, lat2, long1, long2):
x1 = np.radians(lat1)
y1 = np.radians(long1)
......
import numpy as np
from numba import jit
import math as m
@jit(nopython=True)
def dist_on_grid(x1, y1, x2, y2):
......@@ -65,3 +67,101 @@ def bresenham(x1, y1, x2, y2):
pixels.append((x, y))
return pixels
@jit(nopython=True, cache=True)
def vectorize_angle(angle):
return np.array([-np.cos(angle), np.sin(angle), 0])
@jit(nopython=True, cache=True)
def angleize_vector(vector):
if vector[2] > 0.0001:
raise ValueError
return np.arctan2(vector[1], -vector[0])
@jit(nopython=True, cache=True)
def local_ref(lat, long):
theta = (np.pi / 2) - lat
phi = long
return np.array(
[
[np.cos(theta) * np.cos(phi), np.cos(theta) * np.sin(phi), -np.sin(theta)],
[-np.sin(phi), np.cos(phi), 0],
[np.sin(theta) * np.cos(phi), np.sin(theta) * np.sin(phi), np.cos(theta)]
]
)
# @jit(nopython=True, cache=True)
def transpose_matrix(origin_ref, target_ref):
i1 = origin_ref[0, :]
j1 = origin_ref[1, :]
k1 = origin_ref[2, :]
i2 = target_ref[0, :]
j2 = target_ref[1, :]
k2 = target_ref[2, :]
return np.array(
[
[i1.dot(i2), j1.dot( i2), k1.dot(i2)],
[i1.dot(j2), j1.dot(j2), k1.dot(j2)],
[i1.dot(k2), j1.dot(k2), k1.dot(k2)]
]
)
# return np.matmul(origin_ref, target_ref)
@jit(nopython=True, cache=True)
def rotation_quaternions(lat, long, angle):
theta = (np.pi / 2) - lat
phi = long
vx = np.cos(phi) * np.sin(theta)
vy = np.sin(phi) * np.sin(theta)
vz = np.cos(theta)
return (np.array([np.cos(angle / 2), vx * np.sin(angle / 2), vy * np.sin(angle / 2), vz * np.sin(angle / 2)]),
np.array([np.cos(angle / 2), -vx * np.sin(angle / 2), -vy * np.sin(angle / 2), -vz * np.sin(angle / 2)]))
@jit(nopython=True, cache=True)
def quaternion_multiply(quaternion0, quaternion1):
w0, x0, y0, z0 = quaternion0
w1, x1, y1, z1 = quaternion1
return np.array([(w0 * w1) - (x0 * x1) - (y0 * y1) - (z0 * z1),
(w0 * x1) + (x0 * w1) + (y0 * z1) - (z0 * y1),
(w0 * y1) - (x0 * z1) + (y0 * w1) + (z0 * x1),
(w0 * z1) + (x0 * y1) - (y0 * x1) + (z0 * w1)])
@jit(nopython=True, cache=True)
def vector_rotation(vect, lat, long, angle):
q, q_conjugate = rotation_quaternions(lat, long, angle)
v = np.insert(vect, 0, 0)
return quaternion_multiply(quaternion_multiply(q, v), q_conjugate)[1:]
@jit(nopython=True, cache=True)
def spherical_to_carthesian(lat, long):
theta = (np.pi / 2) - lat
phi = long
return np.array([np.cos(phi) * np.sin(theta), np.sin(phi) * np.sin(theta), np.cos(theta)])
@jit(nopython=True, cache=True)
def carthesian_to_spherical(vect):
x = vect[0]
y = vect[1]
z = vect[2]
XsqPlusYsq = x ** 2 + y ** 2
return m.atan2(z, m.sqrt(XsqPlusYsq)), m.atan2(y, x)
@jit(nopython=True, cache=True)
def rotate_vector_by_quaternion(vector, quaternion, inverse_quaternion):
vect = np.zeros(4)
vect[1:] = vector
return quaternion_multiply(quaternion_multiply(quaternion, vect), inverse_quaternion)[1:]