ViSP  2.10.0
vpFeatureMomentCentered.cpp
1 /****************************************************************************
2  *
3  * $Id: vpFeatureMomentImpl.cpp 3317 2011-09-06 14:14:47Z fnovotny $
4  *
5  * This file is part of the ViSP software.
6  * Copyright (C) 2005 - 2014 by INRIA. All rights reserved.
7  *
8  * This software is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * ("GPL") version 2 as published by the Free Software Foundation.
11  * See the file LICENSE.txt at the root directory of this source
12  * distribution for additional information about the GNU GPL.
13  *
14  * For using ViSP with software that can not be combined with the GNU
15  * GPL, please contact INRIA about acquiring a ViSP Professional
16  * Edition License.
17  *
18  * See http://www.irisa.fr/lagadic/visp/visp.html for more information.
19  *
20  * This software was developed at:
21  * INRIA Rennes - Bretagne Atlantique
22  * Campus Universitaire de Beaulieu
23  * 35042 Rennes Cedex
24  * France
25  * http://www.irisa.fr/lagadic
26  *
27  * If you have questions regarding the use of this file, please contact
28  * INRIA at visp@inria.fr
29  *
30  * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
31  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
32  *
33  *
34  * Description:
35  * Implementation for all supported moment features.
36  *
37  * Authors:
38  * Filip Novotny
39  * Manikandan Bakthavatchalam
40  *****************************************************************************/
41 
42 #include <visp/vpConfig.h>
43 
44 #include <vector>
45 #include <limits>
46 
47 #include <visp/vpMomentCentered.h>
48 #include <visp/vpMomentGravityCenter.h>
49 #include <visp/vpMomentObject.h>
50 #include <visp/vpFeatureMomentBasic.h>
51 #include <visp/vpFeatureMomentCentered.h>
52 #include <visp/vpFeatureMomentDatabase.h>
53 #include <visp/vpFeatureMomentGravityCenter.h>
54 
55 
65  double A_, double B_, double C_,
66  vpFeatureMomentDatabase* featureMoments)
67  : vpFeatureMoment(moments_, A_, B_, C_, featureMoments), order(0)
68 {
69 }
70 
77 vpMatrix vpFeatureMomentCentered::interaction (unsigned int select_one,unsigned int select_two) const {
78  if(select_one+select_two>moment->getObject().getOrder())
80  "The requested value has not been computed, you should specify a higher order.");
81  return interaction_matrices[select_two*order+select_one];
82 }
83 
89 vpFeatureMomentCentered::compute_Lmu_pq(const unsigned int& p, const unsigned int& q, const double& xg, const double& yg,
90  const vpMatrix& L_xg, const vpMatrix& L_yg,
91  const vpMomentBasic& m, const vpFeatureMomentBasic& feature_moment_m) const
92 {
93  // term1, term2 and Lterm3 (matrix) will be repeatedly computed inside the innermost loop
94  double term1 = 0.0;
95  double term2 = 0.0;
96  vpMatrix Lterm3(1,6);
97 
98  double pcombk = 0.0;
99  double qcombl = 0.0;
100  double pcombkqcombl = 0.0;
101 
102  double mkl = 0.0;
103  vpMatrix L_mkl;
104 
105  int pmk = 0; // p-k
106  int qml = 0; // q-l
107  double minus1pow = 0.; // (-1)^(p+q-k-l)
108  double pintom = 0.;
109 
110  for (unsigned int k = 0; k <=p; ++k)
111  {
112  pmk = (int)p-(int)k;
113  pcombk = static_cast<double>(vpMath::comb(p,k));
114  for (unsigned int l = 0; l <= q; ++l)
115  {
116  qml = (int)q - (int)l;
117  qcombl = static_cast<double>(vpMath::comb(q,l));
118  minus1pow = pow((double)-1, (double)(pmk + qml));
119  pcombkqcombl = pcombk * qcombl;
120  mkl = m.get(k, l);
121  pintom = pcombkqcombl * mkl;
122  L_mkl = feature_moment_m.interaction(k, l);
123  if(pmk>0)
124  term1 += pintom * pmk * pow(xg, pmk-1) * pow(yg, qml) * minus1pow;
125  if(qml>0)
126  term2 += pintom * qml * pow(xg, pmk) * pow(yg, qml-1) * minus1pow;
127  Lterm3 += pcombkqcombl * pow(xg, pmk) * pow(yg, qml) * L_mkl * minus1pow;
128  }
129  }
130 
131  // L_xg and L_yg stay constant with respect to the above loops. Lterm3 is summed over
132  vpMatrix L_mupq = L_xg*term1 + L_yg*term2 + Lterm3;
133  return L_mupq;
134 }
135 
148 #ifdef VISP_MOMENTS_COMBINE_MATRICES
149  const vpMomentObject& momentObject = moment->getObject();
150  order = momentObject.getOrder()+1;
152  for(std::vector< vpMatrix >::iterator i=interaction_matrices.begin();i!=interaction_matrices.end(); ++i)
153  i->resize(1,6);
154 
155  bool found_moment_gravity;
156  const vpMomentGravityCenter& momentGravity = static_cast<const vpMomentGravityCenter&>(moments.get("vpMomentGravityCenter",found_moment_gravity));
157  if(!found_moment_gravity) throw vpException(vpException::notInitialized,"vpMomentGravityCenter not found");
158  double xg = momentGravity.get()[0];
159  double yg = momentGravity.get()[1];
160 
161  bool found_feature_gravity_center;
162  vpFeatureMomentGravityCenter& featureMomentGravityCenter= (static_cast<vpFeatureMomentGravityCenter&>(featureMomentsDataBase->get("vpFeatureMomentGravityCenter",found_feature_gravity_center)));
163  if(!found_feature_gravity_center) throw vpException(vpException::notInitialized,"vpFeatureMomentGravityCenter not found");
164  vpMatrix Lxg = featureMomentGravityCenter.interaction(1<<0);
165  vpMatrix Lyg = featureMomentGravityCenter.interaction(1<<1);
166 
167  bool found_moment_basic;
168  const vpMomentBasic& momentbasic = static_cast<const vpMomentBasic&>(moments.get("vpMomentBasic",found_moment_basic));
169  if(!found_moment_basic) throw vpException(vpException::notInitialized,"vpMomentBasic not found");
170 
171  bool found_featuremoment_basic;
172  vpFeatureMomentBasic& featureMomentBasic= (static_cast<vpFeatureMomentBasic&>(featureMomentsDataBase->get("vpFeatureMomentBasic",found_featuremoment_basic)));
173  if(!found_featuremoment_basic) throw vpException(vpException::notInitialized,"vpFeatureMomentBasic not found");
174 
175  // Calls the main compute_Lmu_pq function for moments upto order-1
176  for(int i=0;i<(int)order-1;i++){
177  for(int j=0;j<(int)order-1-i;j++){
178  interaction_matrices[(unsigned int)j*order+(unsigned int)i] = compute_Lmu_pq(i, j, xg, yg, Lxg, Lyg, momentbasic, featureMomentBasic);
179  }
180  }
181 #else // #ifdef VISP_MOMENTS_COMBINE_MATRICES
182  bool found_moment_centered;
183  bool found_moment_gravity;
184 
185  const vpMomentCentered& momentCentered= (static_cast<const vpMomentCentered&>(moments.get("vpMomentCentered",found_moment_centered)));
186  const vpMomentGravityCenter& momentGravity = static_cast<const vpMomentGravityCenter&>(moments.get("vpMomentGravityCenter",found_moment_gravity));
187 
188  if(!found_moment_centered) throw vpException(vpException::notInitialized,"vpMomentCentered not found");
189  if(!found_moment_gravity) throw vpException(vpException::notInitialized,"vpMomentGravityCenter not found");
190 
191  int delta;
192  int epsilon;
193  const vpMomentObject& momentObject = moment->getObject();
194  order = momentObject.getOrder()+1;
195  interaction_matrices.resize(order*order);
196  for (std::vector< vpMatrix >::iterator i=interaction_matrices.begin(); i!=interaction_matrices.end(); ++i)
197  i->resize(1,6);
198  if (momentObject.getType()==vpMomentObject::DISCRETE) {
199  delta=0;
200  epsilon=1;
201  } else {
202  delta=1;
203  epsilon=4;
204  }
205  double n11 = momentCentered.get(1,1)/momentObject.get(0,0);
206  double n20 = momentCentered.get(2,0)/momentObject.get(0,0);
207  double n02 = momentCentered.get(0,2)/momentObject.get(0,0);
208  double Xg = momentGravity.getXg();
209  double Yg = momentGravity.getYg();
210  double mu00 = momentCentered.get(0,0);
211 
212  unsigned int VX = 0;
213  unsigned int VY = 1;
214  unsigned int VZ = 2;
215  unsigned int WX = 3;
216  unsigned int WY = 4;
217  unsigned int WZ = 5;
218 
219  interaction_matrices[0][0][VX] = -(delta)*A*mu00;
220  interaction_matrices[0][0][VY] = -(delta)*B*mu00;
221 
222  // Since mu10=0 and mu01=0
223  // interaction_matrices[0][0][WX] = (3*delta)*MU(0,1)+(3*delta)*Yg*mu00;
224  // interaction_matrices[0][0][WY] = -(3*delta)*MU(1,0)-(3*delta)*Xg*mu00;
225  // we get the simplification:
226  interaction_matrices[0][0][WX] = (3*delta)*Yg*mu00;
227  interaction_matrices[0][0][WY] = -(3*delta)*Xg*mu00;
228  interaction_matrices[0][0][VZ] = -A*interaction_matrices[0][0][WY]+B*interaction_matrices[0][0][WX]+(2*delta)*C*mu00;
229  interaction_matrices[0][0][WZ] = 0.;
230 
231  for (int i=1; i<(int)order-1; i++){
232  unsigned int i_ = (unsigned int) i;
233  unsigned int im1_ = i_ - 1;
234  unsigned int ip1_ = i_ + 1;
235 
236  double mu_im10 = momentCentered.get(im1_,0);
237  double mu_ip10 = momentCentered.get(ip1_,0);
238  double mu_im11 = momentCentered.get(im1_,1);
239  double mu_i0 = momentCentered.get(i_,0);
240  double mu_i1 = momentCentered.get(i_,1);
241 
242  interaction_matrices[i_][0][VX] = -(i+delta)*A*mu_i0-(i*B*mu_im11);
243  interaction_matrices[i_][0][VY] = -(delta)*B*mu_i0;
244 
245  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;
246  interaction_matrices[i_][0][WY] = -(i+3*delta)*mu_ip10-(2*i+3*delta)*Xg*mu_i0+i*epsilon*n20*mu_im10;
247  interaction_matrices[i_][0][VZ] = -A*interaction_matrices[i_][0][WY]+B*interaction_matrices[i_][0][WX]+(i+2*delta)*C*mu_i0;
248  interaction_matrices[i_][0][WZ] = i*mu_im11;
249  }
250 
251  for(int j=1;j<(int)order-1;j++){
252  unsigned int j_ = (unsigned int) j;
253  unsigned int jm1_ = j_ - 1;
254  unsigned int jp1_ = j_ + 1;
255 
256  double mu_0jm1 = momentCentered.get(0,jm1_);
257  double mu_0jp1 = momentCentered.get(0,jp1_);
258  double mu_1jm1 = momentCentered.get(1,jm1_);
259  double mu_0j = momentCentered.get(0,j_);
260  double mu_1j = momentCentered.get(1,j_);
261 
262  interaction_matrices[j_*order][0][VX] = -(delta)*A*mu_0j;
263  interaction_matrices[j_*order][0][VY] = -j*A*mu_1jm1-(j+delta)*B*mu_0j;
264 
265  interaction_matrices[j_*order][0][WX] = (j+3*delta)*mu_0jp1+(2*j+3*delta)*Yg*mu_0j-j*epsilon*n02*mu_0jm1;
266  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;
267  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;
268  interaction_matrices[j_*order][0][WZ] = -j*mu_1jm1;
269  }
270 
271  for(int j=1; j<(int)order-1; j++) {
272  unsigned int j_ = (unsigned int) j;
273  unsigned int jm1_ = j_ - 1;
274  unsigned int jp1_ = j_ + 1;
275  for(int i=1; i<(int)order-j-1; i++) {
276  unsigned int i_ = (unsigned int) i;
277  unsigned int im1_ = i_ - 1;
278  unsigned int ip1_ = i_ + 1;
279 
280  double mu_ijm1 = momentCentered.get(i_,jm1_);
281  double mu_ij = momentCentered.get(i_,j_);
282  double mu_ijp1 = momentCentered.get(i_,jp1_);
283  double mu_im1j = momentCentered.get(im1_,j_);
284  double mu_im1jp1 = momentCentered.get(im1_,jp1_);
285  double mu_ip1jm1 = momentCentered.get(ip1_,jm1_);
286  double mu_ip1j = momentCentered.get(ip1_,j_);
287 
288  interaction_matrices[j_*order+i_][0][VX] = -(i+delta)*A*mu_ij-i*B*mu_im1jp1;
289  interaction_matrices[j_*order+i_][0][VY] = -j*A*mu_ip1jm1-(j+delta)*B*mu_ij;
290 
291  interaction_matrices[j_*order+i_][0][WX] = (i+j+3*delta)*mu_ijp1+(i+2*j+3*delta)*Yg*mu_ij
292  +i*Xg*mu_im1jp1-i*epsilon*n11*mu_im1j-j*epsilon*n02*mu_ijm1;
293  interaction_matrices[j_*order+i_][0][WY] = -(i+j+3*delta)*mu_ip1j-(2*i+j+3*delta)*Xg*mu_ij
294  -j*Yg*mu_ip1jm1+i*epsilon*n20*mu_im1j+j*epsilon*n11*mu_ijm1;
295  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;
296  interaction_matrices[j_*order+i_][0][WZ] = i*mu_im1jp1-j*mu_ip1jm1;
297  }
298  }
299 #endif // #ifdef VISP_MOMENTS_COMBINE_MATRICES
300 }
301 
302 
303 std::ostream& operator<<(std::ostream & os, const vpFeatureMomentCentered& mu){
304  vpTRACE(" << Ls - CENTRED MOMENTS >>");
305  unsigned int order_m_1 = (unsigned int)(mu.order - 1);
306  for(unsigned int i=0; i<order_m_1; i++){
307  for(unsigned int j=0; j<order_m_1-i; j++){
308  os << "L_mu[" << i << "," << j << "] = ";
309  mu.interaction(i,j).matlabPrint(os);
310  }
311  }
312  return os;
313 }
314 
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)
Definition of the vpMatrix class.
Definition: vpMatrix.h:98
This class defines the 2D basic moment . This class is a wrapper for vpMomentObject wich allows to us...
Definition: vpMomentBasic.h:74
const vpMoment * moment
#define vpTRACE
Definition: vpDebug.h:418
Functionality computation for centered moment feature. Computes the interaction matrix associated wit...
error that can be emited by ViSP classes.
Definition: vpException.h:76
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)
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 .
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:213
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
Print using matlab syntax, to be put in matlab later.
Definition: vpMatrix.cpp:3032
const vpMomentObject & getObject() const
Definition: vpMoment.h:121
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