Visual Servoing Platform  version 3.0.1
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
vpFeatureMomentCentered.cpp
1 /****************************************************************************
2  *
3  * This file is part of the ViSP software.
4  * Copyright (C) 2005 - 2017 by Inria. All rights reserved.
5  *
6  * This software is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * ("GPL") version 2 as published by the Free Software Foundation.
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 http://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  * Implementation for all supported moment features.
32  *
33  * Authors:
34  * Filip Novotny
35  * Manikandan Bakthavatchalam
36  *****************************************************************************/
37 
38 #include <visp3/core/vpConfig.h>
39 
40 #include <vector>
41 #include <limits>
42 
43 #include <visp3/core/vpMomentCentered.h>
44 #include <visp3/core/vpMomentGravityCenter.h>
45 #include <visp3/core/vpMomentObject.h>
46 #include <visp3/visual_features/vpFeatureMomentBasic.h>
47 #include <visp3/visual_features/vpFeatureMomentCentered.h>
48 #include <visp3/visual_features/vpFeatureMomentDatabase.h>
49 #include <visp3/visual_features/vpFeatureMomentGravityCenter.h>
50 
51 
61  double A_, double B_, double C_,
62  vpFeatureMomentDatabase* featureMoments)
63  : vpFeatureMoment(moments_, A_, B_, C_, featureMoments), order(0)
64 {
65 }
66 
73 vpMatrix vpFeatureMomentCentered::interaction (unsigned int select_one,unsigned int select_two) const {
74  if(select_one+select_two>moment->getObject().getOrder())
76  "The requested value has not been computed, you should specify a higher order.");
77  return interaction_matrices[select_two*order+select_one];
78 }
79 
85 vpFeatureMomentCentered::compute_Lmu_pq(const unsigned int& p, const unsigned int& q, const double& xg, const double& yg,
86  const vpMatrix& L_xg, const vpMatrix& L_yg,
87  const vpMomentBasic& m, const vpFeatureMomentBasic& feature_moment_m) const
88 {
89  // term1, term2 and Lterm3 (matrix) will be repeatedly computed inside the innermost loop
90  double term1 = 0.0;
91  double term2 = 0.0;
92  vpMatrix Lterm3(1,6);
93 
94  double qcombl = 0.0;
95  double pcombkqcombl = 0.0;
96 
97  double mkl = 0.0;
98  vpMatrix L_mkl;
99 
100  int qml = 0; // q-l
101  double minus1pow = 0.; // (-1)^(p+q-k-l)
102  double pintom = 0.;
103 
104  for (unsigned int k = 0; k <=p; ++k)
105  {
106  int pmk = (int)p-(int)k;
107  double pcombk = static_cast<double>(vpMath::comb(p,k));
108  for (unsigned int l = 0; l <= q; ++l)
109  {
110  qml = (int)q - (int)l;
111  qcombl = static_cast<double>(vpMath::comb(q,l));
112  minus1pow = pow((double)-1, (double)(pmk + qml));
113  pcombkqcombl = pcombk * qcombl;
114  mkl = m.get(k, l);
115  pintom = pcombkqcombl * mkl;
116  L_mkl = feature_moment_m.interaction(k, l);
117  if(pmk>0)
118  term1 += pintom * pmk * pow(xg, pmk-1) * pow(yg, qml) * minus1pow;
119  if(qml>0)
120  term2 += pintom * qml * pow(xg, pmk) * pow(yg, qml-1) * minus1pow;
121  Lterm3 += pcombkqcombl * pow(xg, pmk) * pow(yg, qml) * L_mkl * minus1pow;
122  }
123  }
124 
125  // L_xg and L_yg stay constant with respect to the above loops. Lterm3 is summed over
126  vpMatrix L_mupq = L_xg*term1 + L_yg*term2 + Lterm3;
127  return L_mupq;
128 }
129 
142 #ifdef VISP_MOMENTS_COMBINE_MATRICES
143  const vpMomentObject& momentObject = moment->getObject();
144  order = momentObject.getOrder()+1;
146  for(std::vector< vpMatrix >::iterator i=interaction_matrices.begin();i!=interaction_matrices.end(); ++i)
147  i->resize(1,6);
148 
149  bool found_moment_gravity;
150  const vpMomentGravityCenter& momentGravity = static_cast<const vpMomentGravityCenter&>(moments.get("vpMomentGravityCenter",found_moment_gravity));
151  if(!found_moment_gravity) throw vpException(vpException::notInitialized,"vpMomentGravityCenter not found");
152  double xg = momentGravity.get()[0];
153  double yg = momentGravity.get()[1];
154 
155  bool found_feature_gravity_center;
156  vpFeatureMomentGravityCenter& featureMomentGravityCenter= (static_cast<vpFeatureMomentGravityCenter&>(featureMomentsDataBase->get("vpFeatureMomentGravityCenter",found_feature_gravity_center)));
157  if(!found_feature_gravity_center) throw vpException(vpException::notInitialized,"vpFeatureMomentGravityCenter not found");
158  vpMatrix Lxg = featureMomentGravityCenter.interaction(1<<0);
159  vpMatrix Lyg = featureMomentGravityCenter.interaction(1<<1);
160 
161  bool found_moment_basic;
162  const vpMomentBasic& momentbasic = static_cast<const vpMomentBasic&>(moments.get("vpMomentBasic",found_moment_basic));
163  if(!found_moment_basic) throw vpException(vpException::notInitialized,"vpMomentBasic not found");
164 
165  bool found_featuremoment_basic;
166  vpFeatureMomentBasic& featureMomentBasic= (static_cast<vpFeatureMomentBasic&>(featureMomentsDataBase->get("vpFeatureMomentBasic",found_featuremoment_basic)));
167  if(!found_featuremoment_basic) throw vpException(vpException::notInitialized,"vpFeatureMomentBasic not found");
168 
169  // Calls the main compute_Lmu_pq function for moments upto order-1
170  for(int i=0;i<(int)order-1;i++){
171  for(int j=0;j<(int)order-1-i;j++){
172  interaction_matrices[(unsigned int)j*order+(unsigned int)i] = compute_Lmu_pq(i, j, xg, yg, Lxg, Lyg, momentbasic, featureMomentBasic);
173  }
174  }
175 #else // #ifdef VISP_MOMENTS_COMBINE_MATRICES
176  bool found_moment_centered;
177  bool found_moment_gravity;
178 
179  const vpMomentCentered& momentCentered= (static_cast<const vpMomentCentered&>(moments.get("vpMomentCentered",found_moment_centered)));
180  const vpMomentGravityCenter& momentGravity = static_cast<const vpMomentGravityCenter&>(moments.get("vpMomentGravityCenter",found_moment_gravity));
181 
182  if(!found_moment_centered) throw vpException(vpException::notInitialized,"vpMomentCentered not found");
183  if(!found_moment_gravity) throw vpException(vpException::notInitialized,"vpMomentGravityCenter not found");
184 
185  int delta;
186  int epsilon;
187  const vpMomentObject& momentObject = moment->getObject();
188  order = momentObject.getOrder()+1;
189  interaction_matrices.resize(order*order);
190  for (std::vector< vpMatrix >::iterator i=interaction_matrices.begin(); i!=interaction_matrices.end(); ++i)
191  i->resize(1,6);
192  if (momentObject.getType()==vpMomentObject::DISCRETE) {
193  delta=0;
194  epsilon=1;
195  } else {
196  delta=1;
197  epsilon=4;
198  }
199  double n11 = momentCentered.get(1,1)/momentObject.get(0,0);
200  double n20 = momentCentered.get(2,0)/momentObject.get(0,0);
201  double n02 = momentCentered.get(0,2)/momentObject.get(0,0);
202  double Xg = momentGravity.getXg();
203  double Yg = momentGravity.getYg();
204  double mu00 = momentCentered.get(0,0);
205 
206  unsigned int VX = 0;
207  unsigned int VY = 1;
208  unsigned int VZ = 2;
209  unsigned int WX = 3;
210  unsigned int WY = 4;
211  unsigned int WZ = 5;
212 
213  interaction_matrices[0][0][VX] = -(delta)*A*mu00;
214  interaction_matrices[0][0][VY] = -(delta)*B*mu00;
215 
216  // Since mu10=0 and mu01=0
217  // interaction_matrices[0][0][WX] = (3*delta)*MU(0,1)+(3*delta)*Yg*mu00;
218  // interaction_matrices[0][0][WY] = -(3*delta)*MU(1,0)-(3*delta)*Xg*mu00;
219  // we get the simplification:
220  interaction_matrices[0][0][WX] = (3*delta)*Yg*mu00;
221  interaction_matrices[0][0][WY] = -(3*delta)*Xg*mu00;
222  interaction_matrices[0][0][VZ] = -A*interaction_matrices[0][0][WY]+B*interaction_matrices[0][0][WX]+(2*delta)*C*mu00;
223  interaction_matrices[0][0][WZ] = 0.;
224 
225  for (int i=1; i<(int)order-1; i++){
226  unsigned int i_ = (unsigned int) i;
227  unsigned int im1_ = i_ - 1;
228  unsigned int ip1_ = i_ + 1;
229 
230  double mu_im10 = momentCentered.get(im1_,0);
231  double mu_ip10 = momentCentered.get(ip1_,0);
232  double mu_im11 = momentCentered.get(im1_,1);
233  double mu_i0 = momentCentered.get(i_,0);
234  double mu_i1 = momentCentered.get(i_,1);
235 
236  interaction_matrices[i_][0][VX] = -(i+delta)*A*mu_i0-(i*B*mu_im11);
237  interaction_matrices[i_][0][VY] = -(delta)*B*mu_i0;
238 
239  interaction_matrices[i_][0][WX] = (i+3*delta)*mu_i1+(i+3*delta)*Yg*mu_i0+i*Xg*mu_im11-i*epsilon*n11*mu_im10;
240  interaction_matrices[i_][0][WY] = -(i+3*delta)*mu_ip10-(2*i+3*delta)*Xg*mu_i0+i*epsilon*n20*mu_im10;
241  interaction_matrices[i_][0][VZ] = -A*interaction_matrices[i_][0][WY]+B*interaction_matrices[i_][0][WX]+(i+2*delta)*C*mu_i0;
242  interaction_matrices[i_][0][WZ] = i*mu_im11;
243  }
244 
245  for(int j=1;j<(int)order-1;j++){
246  unsigned int j_ = (unsigned int) j;
247  unsigned int jm1_ = j_ - 1;
248  unsigned int jp1_ = j_ + 1;
249 
250  double mu_0jm1 = momentCentered.get(0,jm1_);
251  double mu_0jp1 = momentCentered.get(0,jp1_);
252  double mu_1jm1 = momentCentered.get(1,jm1_);
253  double mu_0j = momentCentered.get(0,j_);
254  double mu_1j = momentCentered.get(1,j_);
255 
256  interaction_matrices[j_*order][0][VX] = -(delta)*A*mu_0j;
257  interaction_matrices[j_*order][0][VY] = -j*A*mu_1jm1-(j+delta)*B*mu_0j;
258 
259  interaction_matrices[j_*order][0][WX] = (j+3*delta)*mu_0jp1+(2*j+3*delta)*Yg*mu_0j-j*epsilon*n02*mu_0jm1;
260  interaction_matrices[j_*order][0][WY] = -(j+3*delta)*mu_1j-(j+3*delta)*Xg*mu_0j-j*Yg*mu_1jm1+j*epsilon*n11*mu_0jm1;
261  interaction_matrices[j_*order][0][VZ] = -A*interaction_matrices[j_*order][0][WY]+B*interaction_matrices[j_*order][0][WX]+(j+2*delta)*C*mu_0j;
262  interaction_matrices[j_*order][0][WZ] = -j*mu_1jm1;
263  }
264 
265  for(int j=1; j<(int)order-1; j++) {
266  unsigned int j_ = (unsigned int) j;
267  unsigned int jm1_ = j_ - 1;
268  unsigned int jp1_ = j_ + 1;
269  for(int i=1; i<(int)order-j-1; i++) {
270  unsigned int i_ = (unsigned int) i;
271  unsigned int im1_ = i_ - 1;
272  unsigned int ip1_ = i_ + 1;
273 
274  double mu_ijm1 = momentCentered.get(i_,jm1_);
275  double mu_ij = momentCentered.get(i_,j_);
276  double mu_ijp1 = momentCentered.get(i_,jp1_);
277  double mu_im1j = momentCentered.get(im1_,j_);
278  double mu_im1jp1 = momentCentered.get(im1_,jp1_);
279  double mu_ip1jm1 = momentCentered.get(ip1_,jm1_);
280  double mu_ip1j = momentCentered.get(ip1_,j_);
281 
282  interaction_matrices[j_*order+i_][0][VX] = -(i+delta)*A*mu_ij-i*B*mu_im1jp1;
283  interaction_matrices[j_*order+i_][0][VY] = -j*A*mu_ip1jm1-(j+delta)*B*mu_ij;
284 
285  interaction_matrices[j_*order+i_][0][WX] = (i+j+3*delta)*mu_ijp1+(i+2*j+3*delta)*Yg*mu_ij
286  +i*Xg*mu_im1jp1-i*epsilon*n11*mu_im1j-j*epsilon*n02*mu_ijm1;
287  interaction_matrices[j_*order+i_][0][WY] = -(i+j+3*delta)*mu_ip1j-(2*i+j+3*delta)*Xg*mu_ij
288  -j*Yg*mu_ip1jm1+i*epsilon*n20*mu_im1j+j*epsilon*n11*mu_ijm1;
289  interaction_matrices[j_*order+i_][0][VZ] = -A*interaction_matrices[j_*order+i_][0][WY]+B*interaction_matrices[j_*order+i_][0][WX]+(i+j+2*delta)*C*mu_ij;
290  interaction_matrices[j_*order+i_][0][WZ] = i*mu_im1jp1-j*mu_ip1jm1;
291  }
292  }
293 #endif // #ifdef VISP_MOMENTS_COMBINE_MATRICES
294 }
295 
296 
301 std::ostream& operator<<(std::ostream & os, const vpFeatureMomentCentered& mu){
302  vpTRACE(" << Ls - CENTRED MOMENTS >>");
303  unsigned int order_m_1 = (unsigned int)(mu.order - 1);
304  for(unsigned int i=0; i<order_m_1; i++){
305  for(unsigned int j=0; j<order_m_1-i; j++){
306  os << "L_mu[" << i << "," << j << "] = ";
307  mu.interaction(i,j).matlabPrint(os);
308  }
309  }
310  return os;
311 }
312 
Functionality computation for basic moment feature. Computes the interaction matrix associated with v...
vpFeatureMomentCentered(vpMomentDatabase &moments, double A, double B, double C, vpFeatureMomentDatabase *featureMoments=NULL)
Implementation of a matrix and operations on matrices.
Definition: vpMatrix.h:97
This class defines the 2D basic moment . This class is a wrapper for vpMomentObject wich allows to us...
Definition: vpMomentBasic.h:70
const vpMoment * moment
Functionality computation for centered moment feature. Computes the interaction matrix associated wit...
error that can be emited by ViSP classes.
Definition: vpException.h:73
Class for generic objects.
const std::vector< double > & get() const
const std::vector< double > & get() const
std::vector< vpMatrix > interaction_matrices
vpMatrix interaction(unsigned int select_one, unsigned int select_two) const
vpMatrix interaction(unsigned int select_one, unsigned int select_two) const
This class allows to register all vpMoments so they can access each other according to their dependen...
vpMatrix interaction(const unsigned int select=FEATURE_ALL)
#define vpTRACE
Definition: vpDebug.h:414
This class defines shared system methods/attributes for 2D moment features but no functional code...
const vpMoment & get(const char *type, bool &found) const
vpMomentDatabase & moments
This class defines the double-indexed centered moment descriptor .
friend std::ostream & operator<<(std::ostream &s, const vpArray2D< Type > &A)
Definition: vpArray2D.h:267
double get(unsigned int i, unsigned int j) const
Class describing 2D gravity center moment.
vpObjectType getType() const
const std::vector< double > & get() const
vpFeatureMomentDatabase * featureMomentsDataBase
static long double comb(unsigned int n, unsigned int p)
Definition: vpMath.h:234
vpMatrix compute_Lmu_pq(const unsigned int &p, const unsigned int &q, const double &xg, const double &yg, const vpMatrix &L_xg, const vpMatrix &L_yg, const vpMomentBasic &m, const vpFeatureMomentBasic &feature_moment_m) const
std::ostream & matlabPrint(std::ostream &os) const
Definition: vpMatrix.cpp:2756
const vpMomentObject & getObject() const
Definition: vpMoment.h:145
Functionality computation for gravity center moment feature. Computes the interaction matrix associat...
vpFeatureMoment & get(const char *type, bool &found)
This class allows to register all feature moments (implemented in vpFeatureMoment... classes) so they can access each other according to their dependencies.
unsigned int getOrder() const