Visual Servoing Platform  version 3.3.0
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";
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  }
159  else {
160  // Tranform input angle from [0; 360] to [0; 180] range
161  double angle_des1 = vec_angle[i];
162  double angle_des2 = vec_angle[i] - 180;
163 
164  // Tranform input angle from [0; 360] to [0; 180] range
165  double alpha = vpMath::deg(malpha.get());
166 
167  std::cout << "alpha expected " << angle_des1 << " or " << angle_des2 << " computed " << alpha << " deg" << std::endl;
168 
169  if (! vpMath::equal(angle_des1, alpha, tolerance_deg) && ! vpMath::equal(angle_des2, alpha, tolerance_deg)) { // 0.5 deg of tolerance
170  std::cout << "Error: result is not in the tolerance: " << tolerance_deg << std::endl;
171  return EXIT_FAILURE;
172  }
173  }
174  }
175  std::cout << "Test succeed" << std::endl;
176  return EXIT_SUCCESS;
177 }
178 
179 int main()
180 {
181  std::string name;
182  bool symmetry;
183  double tolerance_deg;
184  std::vector<int> vec_angle;
185  double symmetry_threshold;
186 
187  // *******************************
188  // Test arrow
189  // *******************************
190  name = "arrow";
191  symmetry = false;
192  tolerance_deg = 0.5;
193  vec_angle.clear();
194  vec_angle.push_back(0);
195  vec_angle.push_back(45);
196  vec_angle.push_back(90);
197  vec_angle.push_back(135);
198  vec_angle.push_back(180);
199  vec_angle.push_back(225);
200  vec_angle.push_back(270);
201  vec_angle.push_back(315);
202 
203  if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
204  return EXIT_FAILURE;
205  }
206 
207  // *******************************
208  // Test ellipse created with gimp
209  // *******************************
210  name = "ellipse";
211  symmetry = true;
212  tolerance_deg = 0.5;
213  vec_angle.clear();
214  vec_angle.push_back(0);
215  vec_angle.push_back(45);
216  vec_angle.push_back(90);
217  vec_angle.push_back(135);
218 
219  if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
220  return EXIT_FAILURE;
221  }
222 
223  // *******************************
224  // Test ellipse created with xfig
225  // *******************************
226  name = "ellipse-xfig";
227  symmetry = true;
228  tolerance_deg = 2.5;
229  symmetry_threshold = 1e-2; // Modify default value
230  vec_angle.clear();
231  vec_angle.push_back(0);
232  vec_angle.push_back(45);
233  vec_angle.push_back(90);
234  vec_angle.push_back(135);
235 
236  if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg, symmetry_threshold) == EXIT_FAILURE) {
237  return EXIT_FAILURE;
238  }
239 
240  // *******************************
241  // Test baleine created with gimp
242  // *******************************
243  name = "baleine";
244  symmetry = false;
245  tolerance_deg = 5.;
246  vec_angle.clear();
247  vec_angle.push_back(0);
248  vec_angle.push_back(45);
249  vec_angle.push_back(90);
250  vec_angle.push_back(135);
251  vec_angle.push_back(180);
252  vec_angle.push_back(225);
253  vec_angle.push_back(270);
254  vec_angle.push_back(315);
255 
256  if (test_moment_alpha(name, symmetry, vec_angle, tolerance_deg) == EXIT_FAILURE) {
257  return EXIT_FAILURE;
258  }
259 
260  return EXIT_SUCCESS;
261 }
vpMomentAlpha::get
double get() const
Definition: vpMomentAlpha.h:225
vpMoment::linkTo
void linkTo(vpMomentDatabase &moments)
Definition: vpMoment.cpp:98
vpMomentObject::DENSE_FULL_OBJECT
@ DENSE_FULL_OBJECT
Definition: vpMomentObject.h:226
vpMomentCentered
This class defines the double-indexed centered moment descriptor .
Definition: vpMomentCentered.h:79
vpMomentGravityCenter::compute
void compute()
Definition: vpMomentGravityCenter.cpp:45
vpMomentAlpha
This class defines the orientation of the object inside the plane parallel to the object.
Definition: vpMomentAlpha.h:207
vpCameraParameters
Generic class defining intrinsic camera parameters.
Definition: vpCameraParameters.h:233
vpImageIo::read
static void read(vpImage< unsigned char > &I, const std::string &filename)
Definition: vpImageIo.cpp:243
vpMath::deg
static double deg(double rad)
Definition: vpMath.h:101
vpMomentDatabase::updateAll
virtual void updateAll(vpMomentObject &object)
Definition: vpMomentDatabase.cpp:82
vpMomentDatabase
This class allows to register all vpMoments so they can access each other according to their dependen...
Definition: vpMomentDatabase.h:131
vpMomentCentered::get
double get(unsigned int i, unsigned int j) const
Definition: vpMomentCentered.cpp:103
vpMath::equal
static bool equal(double x, double y, double s=0.001)
Definition: vpMath.h:296
vpMomentObject
Class for generic objects.
Definition: vpMomentObject.h:219
vpMomentCentered::compute
void compute()
Definition: vpMomentCentered.cpp:65
vpImage< unsigned char >
vpMomentGravityCenter
Class describing 2D gravity center moment.
Definition: vpMomentGravityCenter.h:113
vpMomentAlpha::compute
void compute()
Definition: vpMomentAlpha.cpp:81