Visual Servoing Platform  version 3.2.0 under development (2019-01-22)
testMomentAlpha.cpp
1 /****************************************************************************
2  *
3  * ViSP, open source Visual Servoing Platform software.
4  * Copyright (C) 2005 - 2019 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 http://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  * Authors:
35  * Fabien Spindler
36  *
37  *****************************************************************************/
38 
45 #include <string>
46 #include <visp3/core/vpMomentObject.h>
47 #include <visp3/core/vpMomentGravityCenter.h>
48 #include <visp3/core/vpMomentDatabase.h>
49 #include <visp3/core/vpMomentCentered.h>
50 #include <visp3/core/vpMomentAlpha.h>
51 #include <visp3/core/vpMomentBasic.h>
52 #include <visp3/io/vpImageIo.h>
53 
54 int test_moment_alpha(const std::string &name, bool symmetry, const std::vector<int> &vec_angle, double tolerance_deg, double symmetry_threshold=1e-6)
55 {
57 
58  std::cout << "** Test " << (symmetry == true ? "symmetric " : "non symmetric ") << name << " object" << std::endl;
59 
60  // ***************
61  std::cout << "*** Test symmetry detection from mu 3rd order moments" << std::endl;
62  // ***************
63  std::vector<double> mu_ref;
64  double alpha_ref = 0.;
65  for(unsigned int i = (unsigned int)vec_angle.size(); i >= 1; --i) {
66  // Compute reference alpha image <name>-<vec_angle>[i]deg.pgm
67  std::stringstream ss;
68  ss << name << "-" << vec_angle[i-1] << "deg.pgm";
69  std::cout << "Process image " << ss.str() << std::endl;
70  vpImageIo::read(I, ss.str());
71 
72  // Consider the case of a reference alpha
73  {
74  vpMomentObject obj(3);
76  obj.fromImage(I, 127, vpCameraParameters()); // Init the dense object with the image and corresponding camera parameters
77  vpMomentDatabase db; // Database
78  vpMomentGravityCenter mg; // Declaration of gravity center moment
79  vpMomentCentered mc; // Declaration of centered moments
80  vpMomentAlpha malpha_ref; // Declaration of alpha reference moments
81  mg.linkTo(db); // Add gravity center moment to database
82  mc.linkTo(db); // Add centered moments
83  malpha_ref.linkTo(db); // Add alpha moment
84  db.updateAll(obj); // All of the moments must be updated, not just alpha
85  mg.compute(); // Compute gravity center moment
86  mc.compute(); // Compute centered moments AFTER gravity center
87  malpha_ref.compute(); // Compute alpha gravity center
88 
89  mu_ref.clear();
90  mu_ref.push_back(mc.get(3,0));
91  mu_ref.push_back(mc.get(2,1));
92  mu_ref.push_back(mc.get(1,2));
93  mu_ref.push_back(mc.get(0,3));
94  alpha_ref = malpha_ref.get();
95  }
96  // Consider the case of a relative alpha
97  {
98  vpMomentObject obj(3);
100  obj.fromImage(I, 127, 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";
127  std::cout << "Process image " << ss.str() << std::endl;
128  vpImageIo::read(I, ss.str());
129 
130  vpMomentObject obj(3);
132  obj.fromImage(I, 127, vpCameraParameters()); // Init the dense object with the image
133  vpMomentDatabase db; // Database
134  vpMomentGravityCenter g; // Declaration of gravity center
135  vpMomentCentered mc; // Centered moments
136  vpMomentAlpha malpha(mu_ref, alpha_ref, symmetry_threshold); // Alpha moment relative to the reference alpha
137  g.linkTo(db); // Add gravity center to database
138  mc.linkTo(db); // Add centered moments
139  malpha.linkTo(db); // Add alpha depending on centered moments
140  db.updateAll(obj); // All of the moments must be updated, not just alpha
141  g.compute(); // Compute the moment
142  mc.compute(); // Compute centered moments AFTER gravity center
143  malpha.compute(); // Compute alpha AFTER centered moments.
144 
145  if (! symmetry) {
146  // Tranform input angle from [0; 360] to [-180; +180] range
147  double angle = vec_angle[i];
148  if (angle > 180)
149  angle -= 360;
150  if (angle < -180)
151  angle += 360;
152 
153  std::cout << "alpha expected " << angle << " computed " << vpMath::deg(malpha.get()) << " deg" << std::endl;
154 
155  if (! vpMath::equal(angle, vpMath::deg(malpha.get()), tolerance_deg)) { // 0.5 deg of tolerance
156  std::cout << "Error: result is not in the tolerance: " << tolerance_deg << std::endl;
157  return EXIT_FAILURE;
158  }
159  }
160  else {
161  // Tranform input angle from [0; 360] to [0; 180] range
162  double angle_des1 = vec_angle[i];
163  double angle_des2 = vec_angle[i] - 180;
164 
165  // Tranform input angle from [0; 360] to [0; 180] range
166  double alpha = vpMath::deg(malpha.get());
167 
168  std::cout << "alpha expected " << angle_des1 << " or " << angle_des2 << " computed " << alpha << " deg" << std::endl;
169 
170  if (! vpMath::equal(angle_des1, alpha, tolerance_deg) && ! 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 
180 int 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 }
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:290
void linkTo(vpMomentDatabase &moments)
Definition: vpMoment.cpp:98
Class for generic objects.
This class allows to register all vpMoments so they can access each other according to their dependen...
Generic class defining intrinsic camera parameters.
virtual void updateAll(vpMomentObject &object)
This class defines the double-indexed centered moment descriptor .
This class defines the orientation of the object inside the plane parallel to the object...
double get(unsigned int i, unsigned int j) const
Class describing 2D gravity center moment.
static double deg(double rad)
Definition: vpMath.h:95
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:207
double get() const