Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
testJsonCamera.cpp
1 /*
2  * ViSP, open source Visual Servoing Platform software.
3  * Copyright (C) 2005 - 2024 by Inria. All rights reserved.
4  *
5  * This software is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  * See the file LICENSE.txt at the root directory of this source
10  * distribution for additional information about the GNU GPL.
11  *
12  * For using ViSP with software that can not be combined with the GNU
13  * GPL, please contact Inria about acquiring a ViSP Professional
14  * Edition License.
15  *
16  * See https://visp.inria.fr for more information.
17  *
18  * This software was developed at:
19  * Inria Rennes - Bretagne Atlantique
20  * Campus Universitaire de Beaulieu
21  * 35042 Rennes Cedex
22  * France
23  *
24  * If you have questions regarding the use of this file, please contact
25  * Inria at visp@inria.fr
26  *
27  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
28  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
29  *
30  * Description:
31  * Test vpCameraParameters JSON parse / save.
32  */
33 
40 #include <visp3/core/vpCameraParameters.h>
41 #include <visp3/core/vpIoTools.h>
42 
43 #if defined(VISP_HAVE_NLOHMANN_JSON) && defined(VISP_HAVE_CATCH2)
44 #include <nlohmann/json.hpp>
45 using json = nlohmann::json;
46 
47 #define CATCH_CONFIG_RUNNER
48 #include <catch.hpp>
49 
50 #ifdef ENABLE_VISP_NAMESPACE
51 using namespace VISP_NAMESPACE_NAME;
52 #endif
53 
54 #include <random>
55 namespace
56 {
57 // This class shows how to implement a simple generator for Catch tests
58 class vpRandomCamGenerator : public Catch::Generators::IGenerator<vpCameraParameters>
59 {
60 private:
61  std::minstd_rand m_rand;
62  std::uniform_int_distribution<> m_count_dist;
63  std::uniform_int_distribution<> m_type_dist;
64  std::uniform_real_distribution<> m_dist;
65 
66  vpCameraParameters current;
67 
68 public:
69  vpRandomCamGenerator(double low, double high)
70  : m_rand(std::random_device {}()), m_count_dist(1, 5), m_type_dist(0, 2), m_dist(low, high)
71  {
72  static_cast<void>(next());
73  }
74 
75  const vpCameraParameters &get() const VP_OVERRIDE { return current; }
76  bool next() VP_OVERRIDE
77  {
78  const double px = m_dist(m_rand);
79  const double py = m_dist(m_rand);
80  const double u0 = m_dist(m_rand);
81  const double v0 = m_dist(m_rand);
82 
83  const int type = m_type_dist(m_rand);
84  switch (type) {
85  case 0: {
86  current.initPersProjWithoutDistortion(px, py, u0, v0);
87  break;
88  }
89  case 1: {
90  current.initPersProjWithDistortion(px, py, u0, v0, m_dist(m_rand), m_dist(m_rand));
91  break;
92  }
93  case 2: {
94  std::vector<double> coeffs;
95  const int count = m_count_dist(m_rand);
96  for (int i = 0; i < count; ++i) {
97  coeffs.push_back(m_dist(m_rand));
98  }
99  current.initProjWithKannalaBrandtDistortion(px, py, u0, v0, coeffs);
100  break;
101  }
102  default: {
103  throw vpException(vpException::badValue, "Shouldn't happen");
104  }
105  }
106  return true;
107  }
108 };
109 
110 Catch::Generators::GeneratorWrapper<vpCameraParameters> randomCam(double low, double high)
111 {
112  return Catch::Generators::GeneratorWrapper<vpCameraParameters>(
113  std::unique_ptr<Catch::Generators::IGenerator<vpCameraParameters> >(new vpRandomCamGenerator(low, high)));
114 }
115 } // namespace
116 
117 SCENARIO("Serializing and deserializing a single vpCameraParameters", "[json]")
118 {
119  GIVEN("Some camera intrinsics")
120  {
121  vpCameraParameters cam = GENERATE(take(100, randomCam(50.0, 500.0)));
122  THEN("Serializing and deserializing does not modify the object")
123  {
124  const json j = cam;
125  const vpCameraParameters otherCam = j;
126  REQUIRE(cam == otherCam);
127  }
128  }
129 }
130 
131 SCENARIO("Serializing two cameras", "[json]")
132 {
133  GIVEN("Some camera intrinsics")
134  {
135  vpCameraParameters cam = GENERATE(take(10, randomCam(50.0, 500.0)));
136  vpCameraParameters cam2 = GENERATE(take(10, randomCam(50.0, 500.0)));
137  if (cam != cam2) {
138  WHEN("serializing and deserializing two different cameras")
139  {
140  THEN("The deserialized cams are still different")
141  {
142  const json j1 = cam;
143  const json j2 = cam2;
144 
145  const vpCameraParameters resCam = j1;
146  const vpCameraParameters resCam2 = j2;
147  REQUIRE(resCam != resCam2);
148  }
149  }
150  }
151  }
152 }
153 
154 int main(int argc, char *argv[])
155 {
156  Catch::Session session; // There must be exactly one instance
157  session.applyCommandLine(argc, argv);
158 
159  int numFailed = session.run();
160  return numFailed;
161 }
162 
163 #else
164 
165 int main() { return EXIT_SUCCESS; }
166 
167 #endif
Generic class defining intrinsic camera parameters.
void initPersProjWithoutDistortion(double px, double py, double u0, double v0)
void initPersProjWithDistortion(double px, double py, double u0, double v0, double kud, double kdu)
void initProjWithKannalaBrandtDistortion(double px, double py, double u0, double v0, const std::vector< double > &distortion_coefficients)
error that can be emitted by ViSP classes.
Definition: vpException.h:60
@ badValue
Used to indicate that a value is not in the allowed range.
Definition: vpException.h:73