blob: f73e805e595b4c606bc2be2deff7773d8a9e9fe6 [file] [log] [blame]
Keir Mierle8ebb0732012-04-30 23:09:08 -07001// Ceres Solver - A fast non-linear least squares minimizer
2// Copyright 2010, 2011, 2012 Google Inc. All rights reserved.
3// http://code.google.com/p/ceres-solver/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are met:
7//
8// * Redistributions of source code must retain the above copyright notice,
9// this list of conditions and the following disclaimer.
10// * Redistributions in binary form must reproduce the above copyright notice,
11// this list of conditions and the following disclaimer in the documentation
12// and/or other materials provided with the distribution.
13// * Neither the name of Google Inc. nor the names of its contributors may be
14// used to endorse or promote products derived from this software without
15// specific prior written permission.
16//
17// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
21// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27// POSSIBILITY OF SUCH DAMAGE.
28//
29// Author: sameeragarwal@google.com (Sameer Agarwal)
30
31#include "bal_problem.h"
32
33#include <cstdio>
34#include <cstdlib>
35#include <string>
36#include <glog/logging.h>
Sameer Agarwal5476df52012-08-09 21:46:19 -070037#include "ceres/random.h"
Keir Mierle8ebb0732012-04-30 23:09:08 -070038#include "ceres/rotation.h"
39
40namespace ceres {
41namespace examples {
42
43template<typename T>
44void FscanfOrDie(FILE *fptr, const char *format, T *value) {
45 int num_scanned = fscanf(fptr, format, value);
46 if (num_scanned != 1) {
47 LOG(FATAL) << "Invalid UW data file.";
48 }
49}
50
51BALProblem::BALProblem(const std::string filename, bool use_quaternions) {
52 FILE* fptr = fopen(filename.c_str(), "r");
53
54 if (!fptr) {
55 LOG(FATAL) << "Error: unable to open file " << filename;
56 return;
57 };
58
59 // This wil die horribly on invalid files. Them's the breaks.
60 FscanfOrDie(fptr, "%d", &num_cameras_);
61 FscanfOrDie(fptr, "%d", &num_points_);
62 FscanfOrDie(fptr, "%d", &num_observations_);
63
64 VLOG(1) << "Header: " << num_cameras_
65 << " " << num_points_
66 << " " << num_observations_;
67
68 point_index_ = new int[num_observations_];
69 camera_index_ = new int[num_observations_];
70 observations_ = new double[2 * num_observations_];
71
72 num_parameters_ = 9 * num_cameras_ + 3 * num_points_;
73 parameters_ = new double[num_parameters_];
74
75 for (int i = 0; i < num_observations_; ++i) {
76 FscanfOrDie(fptr, "%d", camera_index_ + i);
77 FscanfOrDie(fptr, "%d", point_index_ + i);
78 for (int j = 0; j < 2; ++j) {
79 FscanfOrDie(fptr, "%lf", observations_ + 2*i + j);
80 }
81 }
82
83 for (int i = 0; i < num_parameters_; ++i) {
84 FscanfOrDie(fptr, "%lf", parameters_ + i);
85 }
86
Markus Moll82b689a2012-08-10 14:21:43 +020087 fclose(fptr);
88
Keir Mierle8ebb0732012-04-30 23:09:08 -070089 use_quaternions_ = use_quaternions;
90 if (use_quaternions) {
91 // Switch the angle-axis rotations to quaternions.
92 num_parameters_ = 10 * num_cameras_ + 3 * num_points_;
93 double* quaternion_parameters = new double[num_parameters_];
94 double* original_cursor = parameters_;
95 double* quaternion_cursor = quaternion_parameters;
96 for (int i = 0; i < num_cameras_; ++i) {
97 AngleAxisToQuaternion(original_cursor, quaternion_cursor);
98 quaternion_cursor += 4;
99 original_cursor += 3;
100 for (int j = 4; j < 10; ++j) {
101 *quaternion_cursor++ = *original_cursor++;
102 }
103 }
104 // Copy the rest of the points.
105 for (int i = 0; i < 3 * num_points_; ++i) {
106 *quaternion_cursor++ = *original_cursor++;
107 }
108 // Swap in the quaternion parameters.
109 delete []parameters_;
110 parameters_ = quaternion_parameters;
111 }
112}
113
Sameer Agarwal5476df52012-08-09 21:46:19 -0700114void BALProblem::Perturb(const double rotation_sigma,
115 const double translation_sigma,
116 const double point_sigma) {
117 CHECK_GE(point_sigma, 0.0);
118 CHECK_GE(rotation_sigma, 0.0);
119 CHECK_GE(translation_sigma, 0.0);
120
121 double* points = mutable_points();
122 if (point_sigma > 0) {
123 for (int i = 0; i < 3 * num_points_; ++i) {
124 points[i] += point_sigma * RandNormal();
125 }
126 }
127
128 for (int i = 0; i < num_cameras_; ++i) {
129 double* camera = mutable_cameras() + camera_block_size() * i;
130
131 // First three coordinates of the camera rotation are shared
132 // between the angle-axis and the quaternion representations.
133 if (rotation_sigma > 0.0) {
134 camera[0] += rotation_sigma * RandNormal();
135 camera[1] += rotation_sigma * RandNormal();
136 camera[2] += rotation_sigma * RandNormal();
137
138 if (use_quaternions_) {
139 camera[4] += rotation_sigma * RandNormal();
140
141 // Normalize the quaternion.
142 double norm = 0.0;
143 for (int j = 0; j < 4; ++j) {
144 norm += camera[j] * camera[j];
145 }
146 norm = sqrt(norm);
147 for (int j = 0; j < 4; ++j) {
148 camera[j] /= norm;
149 }
150 }
151 }
152
153 if (translation_sigma > 0.0) {
154 // Translation.
155 camera[camera_block_size() - 5] += translation_sigma * RandNormal();
156 camera[camera_block_size() - 4] += translation_sigma * RandNormal();
157 camera[camera_block_size() - 3] += translation_sigma * RandNormal();
158 }
159 }
160}
161
Keir Mierle8ebb0732012-04-30 23:09:08 -0700162BALProblem::~BALProblem() {
163 delete []point_index_;
164 delete []camera_index_;
165 delete []observations_;
166 delete []parameters_;
167}
168
169} // namespace examples
170} // namespace ceres