ACloudViewer  3.9.4
A Modern Library for 3D Data Processing
camera_models_test.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 #define TEST_NAME "base/camera_models"
33 #include "util/testing.h"
34 
35 #include "base/camera_models.h"
36 
37 using namespace colmap;
38 
39 template <typename CameraModel>
40 void TestWorldToImageToWorld(const std::vector<double> params, const double u0,
41  const double v0) {
42  double u, v, x, y, xx, yy;
43  CameraModel::WorldToImage(params.data(), u0, v0, &x, &y);
44  CameraModelWorldToImage(CameraModel::model_id, params, u0, v0, &xx, &yy);
45  BOOST_CHECK_EQUAL(x, xx);
46  BOOST_CHECK_EQUAL(y, yy);
47  CameraModel::ImageToWorld(params.data(), x, y, &u, &v);
48  BOOST_CHECK_LT(std::abs(u - u0), 1e-6);
49  BOOST_CHECK_LT(std::abs(v - v0), 1e-6);
50 }
51 
52 template <typename CameraModel>
53 void TestImageToWorldToImage(const std::vector<double> params, const double x0,
54  const double y0) {
55  double u, v, x, y, uu, vv;
56  CameraModel::ImageToWorld(params.data(), x0, y0, &u, &v);
57  CameraModelImageToWorld(CameraModel::model_id, params, x0, y0, &uu, &vv);
58  BOOST_CHECK_EQUAL(u, uu);
59  BOOST_CHECK_EQUAL(v, vv);
60  CameraModel::WorldToImage(params.data(), u, v, &x, &y);
61  BOOST_CHECK_LT(std::abs(x - x0), 1e-6);
62  BOOST_CHECK_LT(std::abs(y - y0), 1e-6);
63 }
64 
65 template <typename CameraModel>
66 void TestModel(const std::vector<double>& params) {
67  BOOST_CHECK(CameraModelVerifyParams(CameraModel::model_id, params));
68 
69  const std::vector<double> default_params =
70  CameraModelInitializeParams(CameraModel::model_id, 100, 100, 100);
71  BOOST_CHECK(CameraModelVerifyParams(CameraModel::model_id, default_params));
72 
73  BOOST_CHECK_EQUAL(CameraModelParamsInfo(CameraModel::model_id),
74  CameraModel::params_info);
75  BOOST_CHECK_EQUAL(&CameraModelFocalLengthIdxs(CameraModel::model_id),
76  &CameraModel::focal_length_idxs);
77  BOOST_CHECK_EQUAL(&CameraModelPrincipalPointIdxs(CameraModel::model_id),
78  &CameraModel::principal_point_idxs);
79  BOOST_CHECK_EQUAL(&CameraModelExtraParamsIdxs(CameraModel::model_id),
80  &CameraModel::extra_params_idxs);
81  BOOST_CHECK_EQUAL(CameraModelNumParams(CameraModel::model_id),
82  CameraModel::num_params);
83 
84  BOOST_CHECK(!CameraModelHasBogusParams(CameraModel::model_id, default_params,
85  100, 100, 0.1, 2.0, 1.0));
86  BOOST_CHECK(CameraModelHasBogusParams(CameraModel::model_id, default_params,
87  100, 100, 0.1, 0.5, 1.0));
88  BOOST_CHECK(CameraModelHasBogusParams(CameraModel::model_id, default_params,
89  100, 100, 1.5, 2.0, 1.0));
90  if (CameraModel::extra_params_idxs.size() > 0) {
91  BOOST_CHECK(CameraModelHasBogusParams(CameraModel::model_id, default_params,
92  100, 100, 0.1, 2.0, -0.1));
93  }
94 
95  BOOST_CHECK_EQUAL(
96  CameraModelImageToWorldThreshold(CameraModel::model_id, params, 0), 0);
97  BOOST_CHECK_GT(
98  CameraModelImageToWorldThreshold(CameraModel::model_id, params, 1), 0);
99  BOOST_CHECK_EQUAL(CameraModelImageToWorldThreshold(CameraModel::model_id,
100  default_params, 1),
101  1.0 / 100.0);
102 
103  BOOST_CHECK(ExistsCameraModelWithName(CameraModel::model_name));
104  BOOST_CHECK(!ExistsCameraModelWithName(CameraModel::model_name + "FOO"));
105 
106  BOOST_CHECK(ExistsCameraModelWithId(CameraModel::model_id));
107  BOOST_CHECK(!ExistsCameraModelWithId(CameraModel::model_id + 123456789));
108 
109  BOOST_CHECK_EQUAL(
110  CameraModelNameToId(CameraModelIdToName(CameraModel::model_id)),
111  CameraModel::model_id);
112  BOOST_CHECK_EQUAL(
113  CameraModelIdToName(CameraModelNameToId(CameraModel::model_name)),
114  CameraModel::model_name);
115 
116  for (double u = -0.5; u <= 0.5; u += 0.1) {
117  for (double v = -0.5; v <= 0.5; v += 0.1) {
118  TestWorldToImageToWorld<CameraModel>(params, u, v);
119  }
120  }
121 
122  for (double x = 0; x <= 800; x += 50) {
123  for (double y = 0; y <= 800; y += 50) {
124  TestImageToWorldToImage<CameraModel>(params, x, y);
125  }
126  }
127 
128  const auto pp_idxs = CameraModel::principal_point_idxs;
129  TestImageToWorldToImage<CameraModel>(params, params[pp_idxs.at(0)],
130  params[pp_idxs.at(1)]);
131 }
132 
133 BOOST_AUTO_TEST_CASE(TestSimplePinhole) {
134  std::vector<double> params = {655.123, 386.123, 511.123};
135  TestModel<SimplePinholeCameraModel>(params);
136 }
137 
138 BOOST_AUTO_TEST_CASE(TestPinhole) {
139  std::vector<double> params = {651.123, 655.123, 386.123, 511.123};
140  TestModel<PinholeCameraModel>(params);
141 }
142 
143 BOOST_AUTO_TEST_CASE(TestSimpleRadial) {
144  std::vector<double> params = {651.123, 386.123, 511.123, 0};
145  TestModel<SimpleRadialCameraModel>(params);
146  params[3] = 0.1;
147  TestModel<SimpleRadialCameraModel>(params);
148 }
149 
150 BOOST_AUTO_TEST_CASE(TestRadial) {
151  std::vector<double> params = {651.123, 386.123, 511.123, 0, 0};
152  TestModel<RadialCameraModel>(params);
153  params[3] = 0.1;
154  TestModel<RadialCameraModel>(params);
155  params[3] = 0.05;
156  TestModel<RadialCameraModel>(params);
157  params[4] = 0.03;
158  TestModel<RadialCameraModel>(params);
159 }
160 
161 BOOST_AUTO_TEST_CASE(TestOpenCV) {
162  std::vector<double> params = {651.123, 655.123, 386.123, 511.123,
163  -0.471, 0.223, -0.001, 0.001};
164  TestModel<OpenCVCameraModel>(params);
165 }
166 
167 BOOST_AUTO_TEST_CASE(TestOpenCVFisheye) {
168  std::vector<double> params = {651.123, 655.123, 386.123, 511.123,
169  -0.471, 0.223, -0.001, 0.001};
170  TestModel<OpenCVFisheyeCameraModel>(params);
171 }
172 
173 BOOST_AUTO_TEST_CASE(TestFullOpenCV) {
174  std::vector<double> params = {651.123, 655.123, 386.123, 511.123,
175  -0.471, 0.223, -0.001, 0.001,
176  0.001, 0.02, -0.02, 0.001};
177  TestModel<FullOpenCVCameraModel>(params);
178 }
179 
181  std::vector<double> params = {651.123, 655.123, 386.123, 511.123, 0.9};
182  TestModel<FOVCameraModel>(params);
183  params[4] = 0;
184  TestModel<FOVCameraModel>(params);
185  params[4] = 1e-6;
186  TestModel<FOVCameraModel>(params);
187  params[4] = 1e-2;
188  TestModel<FOVCameraModel>(params);
189  BOOST_CHECK_EQUAL(
191  .back(),
192  1e-2);
193 }
194 
195 BOOST_AUTO_TEST_CASE(TestSimpleRadialFisheye) {
196  std::vector<double> params = {651.123, 386.123, 511.123, 0};
197  TestModel<SimpleRadialFisheyeCameraModel>(params);
198  params[3] = 0.1;
199  TestModel<SimpleRadialFisheyeCameraModel>(params);
200 }
201 
202 BOOST_AUTO_TEST_CASE(TestRadialFisheye) {
203  std::vector<double> params = {651.123, 386.123, 511.123, 0, 0};
204  TestModel<RadialFisheyeCameraModel>(params);
205  params[3] = 0.1;
206  TestModel<RadialFisheyeCameraModel>(params);
207  params[3] = 0.05;
208  TestModel<RadialFisheyeCameraModel>(params);
209  params[4] = 0.03;
210  TestModel<RadialFisheyeCameraModel>(params);
211 }
212 
213 BOOST_AUTO_TEST_CASE(TestThinPrismFisheye) {
214  std::vector<double> params = {651.123, 655.123, 386.123, 511.123,
215  -0.471, 0.223, -0.001, 0.001,
216  0.001, 0.02, -0.02, 0.001};
217  TestModel<ThinPrismFisheyeCameraModel>(params);
218 }
int size
void TestWorldToImageToWorld(const std::vector< double > params, const double u0, const double v0)
BOOST_AUTO_TEST_CASE(TestSimplePinhole)
void TestImageToWorldToImage(const std::vector< double > params, const double x0, const double y0)
void TestModel(const std::vector< double > &params)
const double * e
normal_z y
normal_z x
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)
bool ExistsCameraModelWithId(const int model_id)
bool ExistsCameraModelWithName(const std::string &model_name)
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 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)
static const int model_id