ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
camera.cc
Go to the documentation of this file.
1 // Copyright (c) 2018, ETH Zurich and UNC Chapel Hill.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //
7 // * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 //
14 // * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of
15 // its contributors may be used to endorse or promote products derived
16 // from this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 //
30 // Author: Johannes L. Schoenberger (jsch-at-demuc-dot-de)
31 
32 #include "base/camera.h"
33 
34 #include <iomanip>
35 
36 #include "base/camera_models.h"
37 #include "util/logging.h"
38 #include "util/misc.h"
39 
40 namespace colmap {
41 
43  : camera_id_(kInvalidCameraId),
44  model_id_(kInvalidCameraModelId),
45  width_(0),
46  height_(0),
47  prior_focal_length_(false) {}
48 
49 std::string Camera::ModelName() const { return CameraModelIdToName(model_id_); }
50 
51 void Camera::SetModelId(const int model_id) {
52  CHECK(ExistsCameraModelWithId(model_id));
53  model_id_ = model_id;
54  params_.resize(CameraModelNumParams(model_id_), 0);
55 }
56 
57 void Camera::SetModelIdFromName(const std::string& model_name) {
58  CHECK(ExistsCameraModelWithName(model_name));
59  model_id_ = CameraModelNameToId(model_name);
60  params_.resize(CameraModelNumParams(model_id_), 0);
61 }
62 
63 const std::vector<size_t>& Camera::FocalLengthIdxs() const {
64  return CameraModelFocalLengthIdxs(model_id_);
65 }
66 
67 const std::vector<size_t>& Camera::PrincipalPointIdxs() const {
68  return CameraModelPrincipalPointIdxs(model_id_);
69 }
70 
71 const std::vector<size_t>& Camera::ExtraParamsIdxs() const {
72  return CameraModelExtraParamsIdxs(model_id_);
73 }
74 
75 Eigen::Matrix3d Camera::CalibrationMatrix() const {
76  Eigen::Matrix3d K = Eigen::Matrix3d::Identity();
77 
78  const std::vector<size_t>& idxs = FocalLengthIdxs();
79  if (idxs.size() == 1) {
80  K(0, 0) = params_[idxs[0]];
81  K(1, 1) = params_[idxs[0]];
82  } else if (idxs.size() == 2) {
83  K(0, 0) = params_[idxs[0]];
84  K(1, 1) = params_[idxs[1]];
85  } else {
86  LOG(FATAL)
87  << "Camera model must either have 1 or 2 focal length parameters.";
88  }
89 
90  K(0, 2) = PrincipalPointX();
91  K(1, 2) = PrincipalPointY();
92 
93  return K;
94 }
95 
96 std::string Camera::ParamsInfo() const {
97  return CameraModelParamsInfo(model_id_);
98 }
99 
100 double Camera::MeanFocalLength() const {
101  const auto& focal_length_idxs = FocalLengthIdxs();
102  double focal_length = 0;
103  for (const auto idx : focal_length_idxs) {
104  focal_length += params_[idx];
105  }
106  return focal_length / focal_length_idxs.size();
107 }
108 
109 double Camera::FocalLength() const {
110  const std::vector<size_t>& idxs = FocalLengthIdxs();
111  CHECK_EQ(idxs.size(), 1);
112  return params_[idxs[0]];
113 }
114 
115 double Camera::FocalLengthX() const {
116  const std::vector<size_t>& idxs = FocalLengthIdxs();
117  CHECK_EQ(idxs.size(), 2);
118  return params_[idxs[0]];
119 }
120 
121 double Camera::FocalLengthY() const {
122  const std::vector<size_t>& idxs = FocalLengthIdxs();
123  CHECK_EQ(idxs.size(), 2);
124  return params_[idxs[1]];
125 }
126 
127 void Camera::SetFocalLength(const double focal_length) {
128  const std::vector<size_t>& idxs = FocalLengthIdxs();
129  for (const auto idx : idxs) {
130  params_[idx] = focal_length;
131  }
132 }
133 
134 void Camera::SetFocalLengthX(const double focal_length_x) {
135  const std::vector<size_t>& idxs = FocalLengthIdxs();
136  CHECK_EQ(idxs.size(), 2);
137  params_[idxs[0]] = focal_length_x;
138 }
139 
140 void Camera::SetFocalLengthY(const double focal_length_y) {
141  const std::vector<size_t>& idxs = FocalLengthIdxs();
142  CHECK_EQ(idxs.size(), 2);
143  params_[idxs[1]] = focal_length_y;
144 }
145 
146 double Camera::PrincipalPointX() const {
147  const std::vector<size_t>& idxs = PrincipalPointIdxs();
148  CHECK_EQ(idxs.size(), 2);
149  return params_[idxs[0]];
150 }
151 
152 double Camera::PrincipalPointY() const {
153  const std::vector<size_t>& idxs = PrincipalPointIdxs();
154  CHECK_EQ(idxs.size(), 2);
155  return params_[idxs[1]];
156 }
157 
158 void Camera::SetPrincipalPointX(const double ppx) {
159  const std::vector<size_t>& idxs = PrincipalPointIdxs();
160  CHECK_EQ(idxs.size(), 2);
161  params_[idxs[0]] = ppx;
162 }
163 
164 void Camera::SetPrincipalPointY(const double ppy) {
165  const std::vector<size_t>& idxs = PrincipalPointIdxs();
166  CHECK_EQ(idxs.size(), 2);
167  params_[idxs[1]] = ppy;
168 }
169 
170 std::string Camera::ParamsToString() const { return VectorToCSV(params_); }
171 
172 bool Camera::SetParamsFromString(const std::string& string) {
173  const std::vector<double> new_camera_params = CSVToVector<double>(string);
174  if (!CameraModelVerifyParams(model_id_, new_camera_params)) {
175  return false;
176  }
177 
178  params_ = new_camera_params;
179  return true;
180 }
181 
182 bool Camera::VerifyParams() const {
183  return CameraModelVerifyParams(model_id_, params_);
184 }
185 
186 bool Camera::HasBogusParams(const double min_focal_length_ratio,
187  const double max_focal_length_ratio,
188  const double max_extra_param) const {
189  return CameraModelHasBogusParams(model_id_, params_, width_, height_,
190  min_focal_length_ratio,
191  max_focal_length_ratio, max_extra_param);
192 }
193 
194 bool Camera::IsUndistorted() const {
195  for (const size_t idx : ExtraParamsIdxs()) {
196  if (std::abs(params_[idx]) > 1e-8) {
197  return false;
198  }
199  }
200  return true;
201 }
202 
203 void Camera::InitializeWithId(const int model_id, const double focal_length,
204  const size_t width, const size_t height) {
205  CHECK(ExistsCameraModelWithId(model_id));
206  model_id_ = model_id;
207  width_ = width;
208  height_ = height;
209  params_ = CameraModelInitializeParams(model_id, focal_length, width, height);
210 }
211 
212 void Camera::InitializeWithName(const std::string& model_name,
213  const double focal_length, const size_t width,
214  const size_t height) {
215  InitializeWithId(CameraModelNameToId(model_name), focal_length, width,
216  height);
217 }
218 
219 Eigen::Vector2d Camera::ImageToWorld(const Eigen::Vector2d& image_point) const {
220  Eigen::Vector2d world_point;
221  CameraModelImageToWorld(model_id_, params_, image_point(0), image_point(1),
222  &world_point(0), &world_point(1));
223  return world_point;
224 }
225 
226 double Camera::ImageToWorldThreshold(const double threshold) const {
227  return CameraModelImageToWorldThreshold(model_id_, params_, threshold);
228 }
229 
230 Eigen::Vector2d Camera::WorldToImage(const Eigen::Vector2d& world_point) const {
231  Eigen::Vector2d image_point;
232  CameraModelWorldToImage(model_id_, params_, world_point(0), world_point(1),
233  &image_point(0), &image_point(1));
234  return image_point;
235 }
236 
237 void Camera::Rescale(const double scale) {
238  CHECK_GT(scale, 0.0);
239  const double scale_x =
240  std::round(scale * width_) / static_cast<double>(width_);
241  const double scale_y =
242  std::round(scale * height_) / static_cast<double>(height_);
243  width_ = static_cast<size_t>(std::round(scale * width_));
244  height_ = static_cast<size_t>(std::round(scale * height_));
245  SetPrincipalPointX(scale_x * PrincipalPointX());
246  SetPrincipalPointY(scale_y * PrincipalPointY());
247  if (FocalLengthIdxs().size() == 1) {
248  SetFocalLength((scale_x + scale_y) / 2.0 * FocalLength());
249  } else if (FocalLengthIdxs().size() == 2) {
250  SetFocalLengthX(scale_x * FocalLengthX());
251  SetFocalLengthY(scale_y * FocalLengthY());
252  } else {
253  LOG(FATAL)
254  << "Camera model must either have 1 or 2 focal length parameters.";
255  }
256 }
257 
258 void Camera::Rescale(const size_t width, const size_t height) {
259  const double scale_x =
260  static_cast<double>(width) / static_cast<double>(width_);
261  const double scale_y =
262  static_cast<double>(height) / static_cast<double>(height_);
263  width_ = width;
264  height_ = height;
265  SetPrincipalPointX(scale_x * PrincipalPointX());
266  SetPrincipalPointY(scale_y * PrincipalPointY());
267  if (FocalLengthIdxs().size() == 1) {
268  SetFocalLength((scale_x + scale_y) / 2.0 * FocalLength());
269  } else if (FocalLengthIdxs().size() == 2) {
270  SetFocalLengthX(scale_x * FocalLengthX());
271  SetFocalLengthY(scale_y * FocalLengthY());
272  } else {
273  LOG(FATAL)
274  << "Camera model must either have 1 or 2 focal length parameters.";
275  }
276 }
277 
278 } // namespace colmap
int width
int size
int height
bool VerifyParams() const
Definition: camera.cc:182
void InitializeWithName(const std::string &model_name, const double focal_length, const size_t width, const size_t height)
Definition: camera.cc:212
double FocalLengthY() const
Definition: camera.cc:121
void InitializeWithId(const int model_id, const double focal_length, const size_t width, const size_t height)
Definition: camera.cc:203
Eigen::Vector2d ImageToWorld(const Eigen::Vector2d &image_point) const
Definition: camera.cc:219
double MeanFocalLength() const
Definition: camera.cc:100
void SetModelIdFromName(const std::string &model_name)
Definition: camera.cc:57
double ImageToWorldThreshold(const double threshold) const
Definition: camera.cc:226
bool SetParamsFromString(const std::string &string)
Definition: camera.cc:172
std::string ModelName() const
Definition: camera.cc:49
void SetPrincipalPointX(const double ppx)
Definition: camera.cc:158
std::string ParamsToString() const
Definition: camera.cc:170
void SetFocalLengthX(const double focal_length_x)
Definition: camera.cc:134
const std::vector< size_t > & PrincipalPointIdxs() const
Definition: camera.cc:67
void Rescale(const double scale)
Definition: camera.cc:237
void SetFocalLengthY(const double focal_length_y)
Definition: camera.cc:140
void SetFocalLength(const double focal_length)
Definition: camera.cc:127
bool HasBogusParams(const double min_focal_length_ratio, const double max_focal_length_ratio, const double max_extra_param) const
Definition: camera.cc:186
double FocalLength() const
Definition: camera.cc:109
void SetPrincipalPointY(const double ppy)
Definition: camera.cc:164
std::string ParamsInfo() const
Definition: camera.cc:96
const std::vector< size_t > & ExtraParamsIdxs() const
Definition: camera.cc:71
Eigen::Matrix3d CalibrationMatrix() const
Definition: camera.cc:75
double FocalLengthX() const
Definition: camera.cc:115
const std::vector< size_t > & FocalLengthIdxs() const
Definition: camera.cc:63
double PrincipalPointX() const
Definition: camera.cc:146
Eigen::Vector2d WorldToImage(const Eigen::Vector2d &world_point) const
Definition: camera.cc:230
double PrincipalPointY() const
Definition: camera.cc:152
void SetModelId(const int model_id)
Definition: camera.cc:51
bool IsUndistorted() const
Definition: camera.cc:194
const double * e
void CameraModelImageToWorld(const int model_id, const std::vector< double > &params, const double x, const double y, double *u, double *v)
const std::vector< size_t > & CameraModelFocalLengthIdxs(const int model_id)
static const int kInvalidCameraModelId
Definition: camera_models.h:55
bool ExistsCameraModelWithId(const int model_id)
bool ExistsCameraModelWithName(const std::string &model_name)
const camera_t kInvalidCameraId
Definition: types.h:75
bool CameraModelHasBogusParams(const int model_id, const std::vector< double > &params, const size_t width, const size_t height, const double min_focal_length_ratio, const double max_focal_length_ratio, const double max_extra_param)
size_t CameraModelNumParams(const int model_id)
bool CameraModelVerifyParams(const int model_id, const std::vector< double > &params)
const std::vector< size_t > & CameraModelExtraParamsIdxs(const int model_id)
std::string CameraModelIdToName(const int model_id)
const std::vector< size_t > & CameraModelPrincipalPointIdxs(const int model_id)
double CameraModelImageToWorldThreshold(const int model_id, const std::vector< double > &params, const double threshold)
std::string VectorToCSV(const std::vector< T > &values)
Definition: misc.h:150
std::string CameraModelParamsInfo(const int model_id)
void CameraModelWorldToImage(const int model_id, const std::vector< double > &params, const double u, const double v, double *x, double *y)
std::vector< double > CameraModelInitializeParams(const int model_id, const double focal_length, const size_t width, const size_t height)
int CameraModelNameToId(const std::string &model_name)