| 303 | } |
| 304 | |
| 305 | void BuildProblem(BALProblem* bal_problem, Problem* problem) { |
| 306 | const int point_block_size = bal_problem->point_block_size(); |
| 307 | const int camera_block_size = bal_problem->camera_block_size(); |
| 308 | double* points = bal_problem->mutable_points(); |
| 309 | double* cameras = bal_problem->mutable_cameras(); |
| 310 | |
| 311 | // Observations is 2*num_observations long array observations = |
| 312 | // [u_1, u_2, ... , u_n], where each u_i is two dimensional, the x |
| 313 | // and y positions of the observation. |
| 314 | const double* observations = bal_problem->observations(); |
| 315 | for (int i = 0; i < bal_problem->num_observations(); ++i) { |
| 316 | CostFunction* cost_function; |
| 317 | // Each Residual block takes a point and a camera as input and |
| 318 | // outputs a 2 dimensional residual. |
| 319 | cost_function = (CERES_GET_FLAG(FLAGS_use_quaternions)) |
| 320 | ? SnavelyReprojectionErrorWithQuaternions::Create( |
| 321 | observations[2 * i + 0], observations[2 * i + 1]) |
| 322 | : SnavelyReprojectionError::Create( |
| 323 | observations[2 * i + 0], observations[2 * i + 1]); |
| 324 | |
| 325 | // If enabled use Huber's loss function. |
| 326 | LossFunction* loss_function = |
| 327 | CERES_GET_FLAG(FLAGS_robustify) ? new HuberLoss(1.0) : nullptr; |
| 328 | |
| 329 | // Each observation corresponds to a pair of a camera and a point |
| 330 | // which are identified by camera_index()[i] and point_index()[i] |
| 331 | // respectively. |
| 332 | double* camera = |
| 333 | cameras + camera_block_size * bal_problem->camera_index()[i]; |
| 334 | double* point = points + point_block_size * bal_problem->point_index()[i]; |
| 335 | problem->AddResidualBlock(cost_function, loss_function, camera, point); |
| 336 | } |
| 337 | |
| 338 | if (CERES_GET_FLAG(FLAGS_use_quaternions) && |
| 339 | CERES_GET_FLAG(FLAGS_use_manifolds)) { |
| 340 | Manifold* camera_manifold = |
| 341 | new ProductManifold<QuaternionManifold, EuclideanManifold<6>>{}; |
| 342 | for (int i = 0; i < bal_problem->num_cameras(); ++i) { |
| 343 | problem->SetManifold(cameras + camera_block_size * i, camera_manifold); |
| 344 | } |
| 345 | } |
| 346 | } |
| 347 | |
| 348 | void SolveProblem(const char* filename) { |
| 349 | BALProblem bal_problem(filename, CERES_GET_FLAG(FLAGS_use_quaternions)); |