| 246 | } |
| 247 | |
| 248 | void BALProblem::Normalize() { |
| 249 | // Compute the marginal median of the geometry. |
| 250 | std::vector<double> tmp(num_points_); |
| 251 | Eigen::Vector3d median; |
| 252 | double* points = mutable_points(); |
| 253 | for (int i = 0; i < 3; ++i) { |
| 254 | for (int j = 0; j < num_points_; ++j) { |
| 255 | tmp[j] = points[3 * j + i]; |
| 256 | } |
| 257 | median(i) = Median(&tmp); |
| 258 | } |
| 259 | |
| 260 | for (int i = 0; i < num_points_; ++i) { |
| 261 | VectorRef point(points + 3 * i, 3); |
| 262 | tmp[i] = (point - median).lpNorm<1>(); |
| 263 | } |
| 264 | |
| 265 | const double median_absolute_deviation = Median(&tmp); |
| 266 | |
| 267 | // Scale so that the median absolute deviation of the resulting |
| 268 | // reconstruction is 100. |
| 269 | const double scale = 100.0 / median_absolute_deviation; |
| 270 | |
| 271 | VLOG(2) << "median: " << median.transpose(); |
| 272 | VLOG(2) << "median absolute deviation: " << median_absolute_deviation; |
| 273 | VLOG(2) << "scale: " << scale; |
| 274 | |
| 275 | // X = scale * (X - median) |
| 276 | for (int i = 0; i < num_points_; ++i) { |
| 277 | VectorRef point(points + 3 * i, 3); |
| 278 | point = scale * (point - median); |
| 279 | } |
| 280 | |
| 281 | double* cameras = mutable_cameras(); |
| 282 | double angle_axis[3]; |
| 283 | double center[3]; |
| 284 | for (int i = 0; i < num_cameras_; ++i) { |
| 285 | double* camera = cameras + camera_block_size() * i; |
| 286 | CameraToAngleAxisAndCenter(camera, angle_axis, center); |
| 287 | // center = scale * (center - median) |
| 288 | VectorRef(center, 3) = scale * (VectorRef(center, 3) - median); |
| 289 | AngleAxisAndCenterToCamera(angle_axis, center, camera); |
| 290 | } |
| 291 | } |
| 292 | |
| 293 | void BALProblem::Perturb(const double rotation_sigma, |
| 294 | const double translation_sigma, |
no test coverage detected