|
2 | 2 | from typing import Tuple |
3 | 3 |
|
4 | 4 | import numpy as np |
| 5 | +from numba import njit |
5 | 6 |
|
6 | 7 | from .calibration import Calibration |
7 | 8 | from .lsqadj import matmul |
@@ -48,70 +49,202 @@ def ray_tracing( |
48 | 49 | ------- |
49 | 50 | _type_: _description_ |
50 | 51 | """ |
51 | | - # Initial ray direction in global coordinate system |
52 | | - tmp1 = np.r_[x, y, -1 * cal.int_par.cc] |
53 | | - tmp1 = unit_vector(tmp1) |
54 | | - start_dir = np.empty(3, dtype=float) |
55 | | - matmul(start_dir, cal.ext_par.dm, tmp1, 3, 3, 1, 3, 3) |
56 | | - |
57 | 52 | primary_point = np.r_[cal.ext_par.x0, cal.ext_par.y0, cal.ext_par.z0] |
| 53 | + glass = np.r_[cal.glass_par.vec_x, cal.glass_par.vec_y, cal.glass_par.vec_z] |
| 54 | + return fast_ray_tracing( |
| 55 | + x, |
| 56 | + y, |
| 57 | + cal.int_par.cc, |
| 58 | + cal.ext_par.dm, |
| 59 | + primary_point, |
| 60 | + glass, |
| 61 | + mm.d[0], |
| 62 | + mm.n1, |
| 63 | + mm.n2[0], |
| 64 | + mm.n3, |
| 65 | + ) |
| 66 | + |
| 67 | +@njit |
| 68 | +def fast_ray_tracing( |
| 69 | + camera_x: float, |
| 70 | + camera_y: float, |
| 71 | + camera_cc: float, |
| 72 | + distortion_matrix: np.ndarray, |
| 73 | + primary_point: np.ndarray, |
| 74 | + glass_vector: np.ndarray, |
| 75 | + distance_param: float, |
| 76 | + refractive_index_medium1: float, |
| 77 | + refractive_index_medium2: float, |
| 78 | + refractive_index_medium3: float, |
| 79 | +) -> Tuple[np.ndarray, np.ndarray]: |
| 80 | + """ |
| 81 | + Fast ray tracing. |
58 | 82 |
|
59 | | - tmp1 = np.r_[cal.glass_par.vec_x, cal.glass_par.vec_y, cal.glass_par.vec_z] |
60 | | - glass_dir = unit_vector(tmp1) |
61 | | - c = vec_norm(tmp1) + mm.d[0] |
| 83 | + Parameters |
| 84 | + ---------- |
| 85 | + - camera_x, camera_y, camera_cc: Camera parameters |
| 86 | + - distortion_matrix: Distortion matrix |
| 87 | + - primary_point: Primary point coordinates |
| 88 | + - glass_vector: Glass vector |
| 89 | + - distance_param: Distance parameter |
| 90 | + - refractive_index_medium1, refractive_index_medium2, refractive_index_medium3: Refractive indices |
| 91 | +
|
| 92 | + Returns |
| 93 | + ------- |
| 94 | + - Tuple containing the resulting point X and output direction vector |
| 95 | + """ |
| 96 | + # Initial ray direction in global coordinate system |
| 97 | + initial_ray_direction = np.array([camera_x, camera_y, -1 * camera_cc]) |
| 98 | + initial_ray_direction = unit_vector(initial_ray_direction) |
| 99 | + transformed_direction = np.empty(3, dtype=float) |
| 100 | + matmul(transformed_direction, distortion_matrix, initial_ray_direction, 3, 3, 1, 3, 3) |
| 101 | + |
| 102 | + glass_direction = unit_vector(glass_vector) |
| 103 | + c_param = vec_norm(glass_vector) + distance_param |
62 | 104 |
|
63 | 105 | # Project start ray on glass vector to find n1/n2 interface. |
64 | | - dist_cam_glass = vec_dot(glass_dir, primary_point) - c |
65 | | - tmp1 = vec_dot(glass_dir, start_dir) |
| 106 | + dist_cam_glass = vec_dot(glass_direction, primary_point) - c_param |
| 107 | + dot_product_start_dir = float(vec_dot(glass_direction, transformed_direction)) |
66 | 108 |
|
67 | 109 | # avoid division by zero |
68 | | - if tmp1 == 0: |
69 | | - tmp1 = 1.0 |
70 | | - d1 = -dist_cam_glass / tmp1 |
| 110 | + if dot_product_start_dir == 0.0: |
| 111 | + dot_product_start_dir = 1.0 |
| 112 | + d1 = -dist_cam_glass / dot_product_start_dir |
71 | 113 |
|
72 | | - tmp1 = vec_scalar_mul(start_dir, d1) |
73 | | - Xb = vec_add(primary_point, tmp1) |
| 114 | + transformed_direction_scaled = vec_scalar_mul(transformed_direction, d1) |
| 115 | + Xb = vec_add(primary_point, transformed_direction_scaled) |
74 | 116 |
|
75 | 117 | # Break down ray into glass-normal and glass-parallel components. */ |
76 | | - n = vec_dot(start_dir, glass_dir) |
77 | | - tmp1 = vec_scalar_mul(glass_dir, n) |
| 118 | + n = vec_dot(transformed_direction, glass_direction) |
| 119 | + transformed_direction_parallel = vec_scalar_mul(glass_direction, n) |
78 | 120 |
|
79 | | - tmp2 = vec_subt(start_dir, tmp1) |
80 | | - bp = unit_vector(tmp2) |
| 121 | + transformed_direction_perpendicular = vec_subt(transformed_direction, transformed_direction_parallel) |
| 122 | + bp = unit_vector(transformed_direction_perpendicular) |
81 | 123 |
|
82 | 124 | # Transform to direction inside glass, using Snell's law |
83 | | - p = np.sqrt(1 - n * n) * mm.n1 / mm.n2[0] |
| 125 | + p = np.sqrt(1 - n * n) * refractive_index_medium1 / refractive_index_medium2 |
84 | 126 | # glass parallel |
85 | 127 | n = -np.sqrt(1 - p * p) |
86 | 128 | # glass normal |
87 | 129 |
|
88 | 130 | # Propagation length in glass parallel to glass vector */ |
89 | | - tmp1 = vec_scalar_mul(bp, p) |
90 | | - tmp2 = vec_scalar_mul(glass_dir, n) |
91 | | - a2 = vec_add(tmp1, tmp2) |
| 131 | + transformed_direction_parallel_scaled = vec_scalar_mul(bp, p) |
| 132 | + transformed_direction_perpendicular_scaled = vec_scalar_mul(glass_direction, n) |
| 133 | + a2 = vec_add(transformed_direction_parallel_scaled, transformed_direction_perpendicular_scaled) |
92 | 134 |
|
93 | | - tmp1 = np.abs(vec_dot(glass_dir, a2)) |
| 135 | + abs_dot_product = np.abs(vec_dot(glass_direction, a2)) |
94 | 136 |
|
95 | 137 | # avoid division by zero |
96 | | - if tmp1 == 0: |
97 | | - tmp1 = 1.0 |
98 | | - d2 = mm.d[0] / tmp1 |
| 138 | + if abs_dot_product == 0: |
| 139 | + abs_dot_product = 1.0 |
| 140 | + d2 = distance_param / abs_dot_product |
99 | 141 |
|
100 | | - # point on the horizontal plane between n2,n3 */ |
101 | | - tmp1 = vec_scalar_mul(a2, d2) |
102 | | - X = vec_add(Xb, tmp1) |
| 142 | + # point on the horizontal plane between n2,n3 |
| 143 | + a2_scaled = vec_scalar_mul(a2, d2) |
| 144 | + X = vec_add(Xb, a2_scaled) |
103 | 145 |
|
104 | | - # Again, direction in next medium */ |
105 | | - n = vec_dot(a2, glass_dir) |
106 | | - tmp2 = vec_subt(a2, tmp2) |
107 | | - bp = unit_vector(tmp2) |
| 146 | + # Again, direction in next medium |
| 147 | + n = vec_dot(a2, glass_direction) |
| 148 | + transformed_direction_perpendicular_scaled = vec_subt(a2, transformed_direction_perpendicular_scaled) |
| 149 | + bp = unit_vector(transformed_direction_perpendicular_scaled) |
108 | 150 |
|
109 | 151 | p = np.sqrt(1 - n * n) |
110 | | - p = p * mm.n2[0] / mm.n3 |
| 152 | + p = p * refractive_index_medium2 / refractive_index_medium3 |
111 | 153 | n = -np.sqrt(1 - p * p) |
112 | 154 |
|
113 | | - tmp1 = vec_scalar_mul(bp, p) |
114 | | - tmp2 = vec_scalar_mul(glass_dir, n) |
115 | | - out = vec_add(tmp1, tmp2) |
| 155 | + transformed_direction_parallel_scaled = vec_scalar_mul(bp, p) |
| 156 | + transformed_direction_perpendicular_scaled = vec_scalar_mul(glass_direction, n) |
| 157 | + out = vec_add(transformed_direction_parallel_scaled, transformed_direction_perpendicular_scaled) |
116 | 158 |
|
117 | 159 | return X, out |
| 160 | + |
| 161 | +# def fast_ray_tracing( |
| 162 | +# x, |
| 163 | +# y, |
| 164 | +# cc, |
| 165 | +# dm, |
| 166 | +# primary_point, |
| 167 | +# glass, |
| 168 | +# d, |
| 169 | +# n1, |
| 170 | +# n2, |
| 171 | +# n3, |
| 172 | +# ) -> Tuple[np.ndarray, np.ndarray]: |
| 173 | +# """ Fast ray tracing. |
| 174 | + |
| 175 | +# Parameters: |
| 176 | +# - x, y, cc: Camera parameters |
| 177 | +# - dm: Distortion matrix |
| 178 | +# - primary_point: Primary point coordinates |
| 179 | +# - glass: Glass vector |
| 180 | +# - d: Distance parameter |
| 181 | +# - n1, n2, n3: Refractive indices |
| 182 | + |
| 183 | +# Returns: |
| 184 | +# - Tuple containing the resulting point X and output direction vector |
| 185 | +# """ |
| 186 | +# # Initial ray direction in global coordinate system |
| 187 | +# tmp1 = np.array([x, y, -1 * cc]) |
| 188 | +# tmp1 = unit_vector(tmp1) |
| 189 | +# start_dir = np.empty(3, dtype=float) |
| 190 | +# matmul(start_dir, dm, tmp1, 3, 3, 1, 3, 3) |
| 191 | + |
| 192 | + |
| 193 | +# glass_dir = unit_vector(glass) |
| 194 | +# c = vec_norm(glass) + d |
| 195 | + |
| 196 | +# # Project start ray on glass vector to find n1/n2 interface. |
| 197 | +# dist_cam_glass = vec_dot(glass_dir, primary_point) - c |
| 198 | +# tmp1 = float(vec_dot(glass_dir, start_dir)) |
| 199 | + |
| 200 | +# # avoid division by zero |
| 201 | +# if tmp1 == 0.0: |
| 202 | +# tmp1 = 1.0 |
| 203 | +# d1 = -dist_cam_glass / tmp1 |
| 204 | + |
| 205 | +# tmp1 = vec_scalar_mul(start_dir, d1) |
| 206 | +# Xb = vec_add(primary_point, tmp1) |
| 207 | + |
| 208 | +# # Break down ray into glass-normal and glass-parallel components. */ |
| 209 | +# n = vec_dot(start_dir, glass_dir) |
| 210 | +# tmp1 = vec_scalar_mul(glass_dir, n) |
| 211 | + |
| 212 | +# tmp2 = vec_subt(start_dir, tmp1) |
| 213 | +# bp = unit_vector(tmp2) |
| 214 | + |
| 215 | +# # Transform to direction inside glass, using Snell's law |
| 216 | +# p = np.sqrt(1 - n * n) * n1 / n2 |
| 217 | +# # glass parallel |
| 218 | +# n = -np.sqrt(1 - p * p) |
| 219 | +# # glass normal |
| 220 | + |
| 221 | +# # Propagation length in glass parallel to glass vector */ |
| 222 | +# tmp1 = vec_scalar_mul(bp, p) |
| 223 | +# tmp2 = vec_scalar_mul(glass_dir, n) |
| 224 | +# a2 = vec_add(tmp1, tmp2) |
| 225 | + |
| 226 | +# tmp1 = np.abs(vec_dot(glass_dir, a2)) |
| 227 | + |
| 228 | +# # avoid division by zero |
| 229 | +# if tmp1 == 0: |
| 230 | +# tmp1 = 1.0 |
| 231 | +# d2 = d / tmp1 |
| 232 | + |
| 233 | +# # point on the horizontal plane between n2,n3 */ |
| 234 | +# tmp1 = vec_scalar_mul(a2, d2) |
| 235 | +# X = vec_add(Xb, tmp1) |
| 236 | + |
| 237 | +# # Again, direction in next medium */ |
| 238 | +# n = vec_dot(a2, glass_dir) |
| 239 | +# tmp2 = vec_subt(a2, tmp2) |
| 240 | +# bp = unit_vector(tmp2) |
| 241 | + |
| 242 | +# p = np.sqrt(1 - n * n) |
| 243 | +# p = p * n2 / n3 |
| 244 | +# n = -np.sqrt(1 - p * p) |
| 245 | + |
| 246 | +# tmp1 = vec_scalar_mul(bp, p) |
| 247 | +# tmp2 = vec_scalar_mul(glass_dir, n) |
| 248 | +# out = vec_add(tmp1, tmp2) |
| 249 | + |
| 250 | +# return X, out |
0 commit comments