Visual Servoing Platform version 3.6.0
Loading...
Searching...
No Matches
testMomentAlpha.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2023 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See https://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * Test some vpMomentAlpha functionalities.
33 *
34*****************************************************************************/
35
42#include <string>
43#include <visp3/core/vpMomentAlpha.h>
44#include <visp3/core/vpMomentBasic.h>
45#include <visp3/core/vpMomentCentered.h>
46#include <visp3/core/vpMomentDatabase.h>
47#include <visp3/core/vpMomentGravityCenter.h>
48#include <visp3/core/vpMomentObject.h>
49#include <visp3/io/vpImageIo.h>
50
51int test_moment_alpha(const std::string &name, bool symmetry, const std::vector<int> &vec_angle, double tolerance_deg,
52 double symmetry_threshold = 1e-6)
53{
55
56 std::cout << "** Test " << (symmetry == true ? "symmetric " : "non symmetric ") << name << " object" << std::endl;
57
58 // ***************
59 std::cout << "*** Test symmetry detection from mu 3rd order moments" << std::endl;
60 // ***************
61 std::vector<double> mu_ref;
62 double alpha_ref = 0.;
63 for (unsigned int i = (unsigned int)vec_angle.size(); i >= 1; --i) {
64 // Compute reference alpha image <name>-<vec_angle>[i]deg.pgm
65 std::stringstream ss;
66 ss << name << "-" << vec_angle[i - 1] << "deg.pgm";
67 std::cout << "Process image " << ss.str() << std::endl;
68 vpImageIo::read(I, ss.str());
69
70 // Consider the case of a reference alpha
71 {
72 vpMomentObject obj(3);
74 obj.fromImage(I, 127,
75 vpCameraParameters()); // Init the dense object with the image and corresponding camera parameters
76 vpMomentDatabase db; // Database
77 vpMomentGravityCenter mg; // Declaration of gravity center moment
78 vpMomentCentered mc; // Declaration of centered moments
79 vpMomentAlpha malpha_ref; // Declaration of alpha reference moments
80 mg.linkTo(db); // Add gravity center moment to database
81 mc.linkTo(db); // Add centered moments
82 malpha_ref.linkTo(db); // Add alpha moment
83 db.updateAll(obj); // All of the moments must be updated, not just alpha
84 mg.compute(); // Compute gravity center moment
85 mc.compute(); // Compute centered moments AFTER gravity center
86 malpha_ref.compute(); // Compute alpha gravity center
87
88 mu_ref.clear();
89 mu_ref.push_back(mc.get(3, 0));
90 mu_ref.push_back(mc.get(2, 1));
91 mu_ref.push_back(mc.get(1, 2));
92 mu_ref.push_back(mc.get(0, 3));
93 alpha_ref = malpha_ref.get();
94 }
95 // Consider the case of a relative alpha
96 {
97 vpMomentObject obj(3);
99 obj.fromImage(I, 127,
100 vpCameraParameters()); // Init the dense object with the image and corresponding camera parameters
101 vpMomentDatabase db; // Database
102 vpMomentGravityCenter mg; // Declaration of gravity center moment
103 vpMomentCentered mc; // Declaration of centered moments
104 vpMomentAlpha malpha(mu_ref, alpha_ref, symmetry_threshold); // Declaration of alpha relative moments
105 mg.linkTo(db); // Add gravity center moment to database
106 mc.linkTo(db); // Add centered moments
107 malpha.linkTo(db); // Add alpha moment
108 db.updateAll(obj); // All of the moments must be updated, not just alpha
109 mg.compute(); // Compute gravity center moment
110 mc.compute(); // Compute centered moments AFTER gravity center
111 malpha.compute(); // Compute alpha gravity center
112
113 if (malpha.is_symmetric() != symmetry) {
114 std::cout << "Error in symmety detection" << std::endl;
115 return EXIT_FAILURE;
116 }
117 }
118 }
119
120 // ***************
121 std::cout << "*** Compute angle in relative mode using the last reference from the previous test" << std::endl;
122 // ***************
123 for (size_t i = 0; i < vec_angle.size(); i++) {
124 std::stringstream ss;
125 ss << name << "-" << vec_angle[i] << "deg.pgm";
126 std::cout << "Process image " << ss.str() << std::endl;
127 vpImageIo::read(I, ss.str());
128
129 vpMomentObject obj(3);
131 obj.fromImage(I, 127, vpCameraParameters()); // Init the dense object with the image
132 vpMomentDatabase db; // Database
133 vpMomentGravityCenter g; // Declaration of gravity center
134 vpMomentCentered mc; // Centered moments
135 vpMomentAlpha malpha(mu_ref, alpha_ref, symmetry_threshold); // Alpha moment relative to the reference alpha
136 g.linkTo(db); // Add gravity center to database
137 mc.linkTo(db); // Add centered moments
138 malpha.linkTo(db); // Add alpha depending on centered moments
139 db.updateAll(obj); // All of the moments must be updated, not just alpha
140 g.compute(); // Compute the moment
141 mc.compute(); // Compute centered moments AFTER gravity center
142 malpha.compute(); // Compute alpha AFTER centered moments.
143
144 if (!symmetry) {
145 // Tranform input angle from [0; 360] to [-180; +180] range
146 double angle = vec_angle[i];
147 if (angle > 180)
148 angle -= 360;
149 if (angle < -180)
150 angle += 360;
151
152 std::cout << "alpha expected " << angle << " computed " << vpMath::deg(malpha.get()) << " deg" << std::endl;
153
154 if (!vpMath::equal(angle, vpMath::deg(malpha.get()), tolerance_deg)) { // 0.5 deg of tolerance
155 std::cout << "Error: result is not in the tolerance: " << tolerance_deg << std::endl;
156 return EXIT_FAILURE;
157 }
158 } else {
159 // Tranform input angle from [0; 360] to [0; 180] range
160 double angle_des1 = vec_angle[i];
161 double angle_des2 = vec_angle[i] - 180;
162
163 // Tranform input angle from [0; 360] to [0; 180] range
164 double alpha = vpMath::deg(malpha.get());
165
166 std::cout << "alpha expected " << angle_des1 << " or " << angle_des2 << " computed " << alpha << " deg"
167 << std::endl;
168
169 if (!vpMath::equal(angle_des1, alpha, tolerance_deg) &&
170 !vpMath::equal(angle_des2, alpha, tolerance_deg)) { // 0.5 deg of tolerance
171 std::cout << "Error: result is not in the tolerance: " << tolerance_deg << std::endl;
172 return EXIT_FAILURE;
173 }
174 }
175 }
176 std::cout << "Test succeed" << std::endl;
177 return EXIT_SUCCESS;
178}
179
180int main()
181{
182 std::string name;
183 bool symmetry;
184 double tolerance_deg;
185 std::vector<int> vec_angle;
186 double symmetry_threshold;
187
188 // *******************************
189 // Test arrow
190 // *******************************
191 name = "arrow";
192 symmetry = false;
193 tolerance_deg = 0.5;
194 vec_angle.clear();
195 vec_angle.push_back(0);
196 vec_angle.push_back(45);
197 vec_angle.push_back(90);
198 vec_angle.push_back(135);
199 vec_angle.push_back(180);
200 vec_angle.push_back(225);
201 vec_angle.push_back(270);
202 vec_angle.push_back(315);
203
204 if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
205 return EXIT_FAILURE;
206 }
207
208 // *******************************
209 // Test ellipse created with gimp
210 // *******************************
211 name = "ellipse";
212 symmetry = true;
213 tolerance_deg = 0.5;
214 vec_angle.clear();
215 vec_angle.push_back(0);
216 vec_angle.push_back(45);
217 vec_angle.push_back(90);
218 vec_angle.push_back(135);
219
220 if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
221 return EXIT_FAILURE;
222 }
223
224 // *******************************
225 // Test ellipse created with xfig
226 // *******************************
227 name = "ellipse-xfig";
228 symmetry = true;
229 tolerance_deg = 2.5;
230 symmetry_threshold = 1e-2; // Modify default value
231 vec_angle.clear();
232 vec_angle.push_back(0);
233 vec_angle.push_back(45);
234 vec_angle.push_back(90);
235 vec_angle.push_back(135);
236
237 if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg, symmetry_threshold) == EXIT_FAILURE) {
238 return EXIT_FAILURE;
239 }
240
241 // *******************************
242 // Test baleine created with gimp
243 // *******************************
244 name = "baleine";
245 symmetry = false;
246 tolerance_deg = 5.;
247 vec_angle.clear();
248 vec_angle.push_back(0);
249 vec_angle.push_back(45);
250 vec_angle.push_back(90);
251 vec_angle.push_back(135);
252 vec_angle.push_back(180);
253 vec_angle.push_back(225);
254 vec_angle.push_back(270);
255 vec_angle.push_back(315);
256
257 if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
258 return EXIT_FAILURE;
259 }
260
261 return EXIT_SUCCESS;
262}
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:135
static bool equal(double x, double y, double threshold=0.001)
Definition vpMath.h:369
static double deg(double rad)
Definition vpMath.h:106
This class defines the orientation of the object inside the plane parallel to the object.
double get() const
This class defines the double-indexed centered moment descriptor .
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:98