Visual Servoing Platform version 3.7.0
Loading...
Searching...
No Matches
testMomentAlpha.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 some vpMomentAlpha functionalities.
32 */
33
39
40#include <string>
41#include <visp3/core/vpMomentAlpha.h>
42#include <visp3/core/vpMomentBasic.h>
43#include <visp3/core/vpMomentCentered.h>
44#include <visp3/core/vpMomentDatabase.h>
45#include <visp3/core/vpMomentGravityCenter.h>
46#include <visp3/core/vpMomentObject.h>
47#include <visp3/io/vpImageIo.h>
48
49#ifdef ENABLE_VISP_NAMESPACE
50using namespace VISP_NAMESPACE_NAME;
51#endif
52
53int test_moment_alpha(const std::string &name, bool symmetry, const std::vector<int> &vec_angle, double tolerance_deg,
54 double symmetry_threshold = 1e-6);
55
56int test_moment_alpha(const std::string &name, bool symmetry, const std::vector<int> &vec_angle, double tolerance_deg,
57 double symmetry_threshold)
58{
60
61 std::cout << "** Test " << (symmetry == true ? "symmetric " : "non symmetric ") << name << " object" << std::endl;
62
63 // ***************
64 std::cout << "*** Test symmetry detection from mu 3rd order moments" << std::endl;
65 // ***************
66 std::vector<double> mu_ref;
67 double alpha_ref = 0.;
68 for (unsigned int i = static_cast<unsigned int>(vec_angle.size()); i >= 1; --i) {
69 // Compute reference alpha image <name>-<vec_angle>[i]deg.pgm
70 std::stringstream ss;
71 ss << name << "-" << vec_angle[i - 1] << "deg.pgm";
72 std::cout << "Process image " << ss.str() << std::endl;
73 vpImageIo::read(I, ss.str());
74
75 // Consider the case of a reference alpha
76 {
77 vpMomentObject obj(3);
79 obj.fromImage(I, 127,
80 vpCameraParameters()); // Init the dense object with the image and corresponding camera parameters
81 vpMomentDatabase db; // Database
82 vpMomentGravityCenter mg; // Declaration of gravity center moment
83 vpMomentCentered mc; // Declaration of centered moments
84 vpMomentAlpha malpha_ref; // Declaration of alpha reference moments
85 mg.linkTo(db); // Add gravity center moment to database
86 mc.linkTo(db); // Add centered moments
87 malpha_ref.linkTo(db); // Add alpha moment
88 db.updateAll(obj); // All of the moments must be updated, not just alpha
89 mg.compute(); // Compute gravity center moment
90 mc.compute(); // Compute centered moments AFTER gravity center
91 malpha_ref.compute(); // Compute alpha gravity center
92
93 mu_ref.clear();
94 mu_ref.push_back(mc.get(3, 0));
95 mu_ref.push_back(mc.get(2, 1));
96 mu_ref.push_back(mc.get(1, 2));
97 mu_ref.push_back(mc.get(0, 3));
98 alpha_ref = malpha_ref.get();
99 }
100 // Consider the case of a relative alpha
101 {
102 vpMomentObject obj(3);
104 obj.fromImage(I, 127,
105 vpCameraParameters()); // Init the dense object with the image and corresponding camera parameters
106 vpMomentDatabase db; // Database
107 vpMomentGravityCenter mg; // Declaration of gravity center moment
108 vpMomentCentered mc; // Declaration of centered moments
109 vpMomentAlpha malpha(mu_ref, alpha_ref, symmetry_threshold); // Declaration of alpha relative moments
110 mg.linkTo(db); // Add gravity center moment to database
111 mc.linkTo(db); // Add centered moments
112 malpha.linkTo(db); // Add alpha moment
113 db.updateAll(obj); // All of the moments must be updated, not just alpha
114 mg.compute(); // Compute gravity center moment
115 mc.compute(); // Compute centered moments AFTER gravity center
116 malpha.compute(); // Compute alpha gravity center
117
118 if (malpha.is_symmetric() != symmetry) {
119 std::cout << "Error in symmety detection" << std::endl;
120 return EXIT_FAILURE;
121 }
122 }
123 }
124
125 // ***************
126 std::cout << "*** Compute angle in relative mode using the last reference from the previous test" << std::endl;
127 // ***************
128 for (size_t i = 0; i < vec_angle.size(); i++) {
129 std::stringstream ss;
130 ss << name << "-" << vec_angle[i] << "deg.pgm";
131 std::cout << "Process image " << ss.str() << std::endl;
132 vpImageIo::read(I, ss.str());
133
134 vpMomentObject obj(3);
136 obj.fromImage(I, 127, vpCameraParameters()); // Init the dense object with the image
137 vpMomentDatabase db; // Database
138 vpMomentGravityCenter g; // Declaration of gravity center
139 vpMomentCentered mc; // Centered moments
140 vpMomentAlpha malpha(mu_ref, alpha_ref, symmetry_threshold); // Alpha moment relative to the reference alpha
141 g.linkTo(db); // Add gravity center to database
142 mc.linkTo(db); // Add centered moments
143 malpha.linkTo(db); // Add alpha depending on centered moments
144 db.updateAll(obj); // All of the moments must be updated, not just alpha
145 g.compute(); // Compute the moment
146 mc.compute(); // Compute centered moments AFTER gravity center
147 malpha.compute(); // Compute alpha AFTER centered moments.
148
149 if (!symmetry) {
150 // Transform input angle from [0; 360] to [-180; +180] range
151 double angle = vec_angle[i];
152 if (angle > 180)
153 angle -= 360;
154 if (angle < -180)
155 angle += 360;
156
157 std::cout << "alpha expected " << angle << " computed " << vpMath::deg(malpha.get()) << " deg" << std::endl;
158
159 if (!vpMath::equal(angle, vpMath::deg(malpha.get()), tolerance_deg)) { // 0.5 deg of tolerance
160 std::cout << "Error: result is not in the tolerance: " << tolerance_deg << std::endl;
161 return EXIT_FAILURE;
162 }
163 }
164 else {
165 // Transform input angle from [0; 360] to [0; 180] range
166 double angle_des1 = vec_angle[i];
167 double angle_des2 = vec_angle[i] - 180;
168
169 // Transform input angle from [0; 360] to [0; 180] range
170 double alpha = vpMath::deg(malpha.get());
171
172 std::cout << "alpha expected " << angle_des1 << " or " << angle_des2 << " computed " << alpha << " deg"
173 << std::endl;
174
175 if (!vpMath::equal(angle_des1, alpha, tolerance_deg) &&
176 !vpMath::equal(angle_des2, alpha, tolerance_deg)) { // 0.5 deg of tolerance
177 std::cout << "Error: result is not in the tolerance: " << tolerance_deg << std::endl;
178 return EXIT_FAILURE;
179 }
180 }
181 }
182 std::cout << "Test succeed" << std::endl;
183 return EXIT_SUCCESS;
184}
185
186int main()
187{
188 std::string name;
189 bool symmetry;
190 double tolerance_deg;
191 std::vector<int> vec_angle;
192 double symmetry_threshold;
193
194 // *******************************
195 // Test arrow
196 // *******************************
197 name = "arrow";
198 symmetry = false;
199 tolerance_deg = 0.5;
200 vec_angle.clear();
201 vec_angle.push_back(0);
202 vec_angle.push_back(45);
203 vec_angle.push_back(90);
204 vec_angle.push_back(135);
205 vec_angle.push_back(180);
206 vec_angle.push_back(225);
207 vec_angle.push_back(270);
208 vec_angle.push_back(315);
209
210 if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
211 return EXIT_FAILURE;
212 }
213
214 // *******************************
215 // Test ellipse created with gimp
216 // *******************************
217 name = "ellipse";
218 symmetry = true;
219 tolerance_deg = 0.5;
220 vec_angle.clear();
221 vec_angle.push_back(0);
222 vec_angle.push_back(45);
223 vec_angle.push_back(90);
224 vec_angle.push_back(135);
225
226 if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
227 return EXIT_FAILURE;
228 }
229
230 // *******************************
231 // Test ellipse created with xfig
232 // *******************************
233 name = "ellipse-xfig";
234 symmetry = true;
235 tolerance_deg = 2.5;
236 symmetry_threshold = 1e-2; // Modify default value
237 vec_angle.clear();
238 vec_angle.push_back(0);
239 vec_angle.push_back(45);
240 vec_angle.push_back(90);
241 vec_angle.push_back(135);
242
243 if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg, symmetry_threshold) == EXIT_FAILURE) {
244 return EXIT_FAILURE;
245 }
246
247 // *******************************
248 // Test baleine created with gimp
249 // *******************************
250 name = "baleine";
251 symmetry = false;
252 tolerance_deg = 5.;
253 vec_angle.clear();
254 vec_angle.push_back(0);
255 vec_angle.push_back(45);
256 vec_angle.push_back(90);
257 vec_angle.push_back(135);
258 vec_angle.push_back(180);
259 vec_angle.push_back(225);
260 vec_angle.push_back(270);
261 vec_angle.push_back(315);
262
263 if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
264 return EXIT_FAILURE;
265 }
266
267 return EXIT_SUCCESS;
268}
Generic class defining intrinsic camera parameters.
static void read(vpImage< unsigned char > &I, const std::string &filename, int backend=IO_DEFAULT_BACKEND)
Definition of the vpImage class member functions.
Definition vpImage.h:131
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:470
static double deg(double rad)
Definition vpMath.h:119
This class defines the orientation of the object inside the plane parallel to the object.
double get() const
void compute() VP_OVERRIDE
This class defines the double-indexed centered moment descriptor .
void compute() VP_OVERRIDE
double get(unsigned int i, unsigned int j) const
This class allows to register all vpMoments so they can access each other according to their dependen...
virtual void updateAll(vpMomentObject &object)
Class describing 2D gravity center moment.
Class for generic objects.
void linkTo(vpMomentDatabase &moments)
Definition vpMoment.cpp:114