Util.cpp
Go to the documentation of this file.
1 /*
2  * This file is part of ALVAR, A Library for Virtual and Augmented Reality.
3  *
4  * Copyright 2007-2012 VTT Technical Research Centre of Finland
5  *
6  * Contact: VTT Augmented Reality Team <alvar.info@vtt.fi>
7  * <http://www.vtt.fi/multimedia/alvar.html>
8  *
9  * ALVAR is free software; you can redistribute it and/or modify it under the
10  * terms of the GNU Lesser General Public License as published by the Free
11  * Software Foundation; either version 2.1 of the License, or (at your option)
12  * any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
17  * for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with ALVAR; if not, see
21  * <http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html>.
22  */
23 
24 #include "ar_track_alvar/Util.h"
26 
27 using namespace std;
28 
29 namespace alvar {
30 using namespace std;
31 
32 //ttesis
33 
34 int dot(CvPoint *A, CvPoint *B, CvPoint *C){
35  CvPoint AB, BC;
36  AB.x = B->x-A->x;
37  AB.y = B->y-A->y;
38  BC.x = C->x-B->x;
39  BC.y = C->y-B->y;
40  int dot = AB.x * BC.x + AB.y * BC.y;
41  return dot;
42 }
43 
44 int cross(CvPoint *A,CvPoint *B, CvPoint *C){
45  CvPoint AB, AC;
46  AB.x = B->x-A->x;
47  AB.y = B->y-A->y;
48  AC.x = C->x-A->x;
49  AC.y = C->y-A->y;
50  int cross = AB.x * AC.y - AB.y * AC.x;
51  return cross;
52 }
53 
54 double distance(CvPoint *A,CvPoint *B){
55  double d1 = A->x - B->x;
56  double d2 = A->y - B->y;
57  return sqrt(d1*d1+d2*d2);
58 }
59 
60 
61 double linePointDist(CvPoint *A,CvPoint *B,CvPoint *C, bool isSegment){
62  double dist = cross(A,B,C) / distance(A,B);
63  if(isSegment){
64  int dot1 = dot(A,B,C);
65  if(dot1 > 0)return distance(B,C);
66  int dot2 = dot(B,A,C);
67  if(dot2 > 0)return distance(A,C);
68  }
69  return abs(dist);
70 }
71 
72 double angle(CvPoint *A,CvPoint *B, CvPoint *C,CvPoint *D, int isDirectionDependent){
73  double angle;
74  double a = B->x - A->x;
75  double b = B->y - A->y;
76  double c = D->x - C->x;
77  double d = D->y - C->y;
78  angle = acos( ((a * c) + (b * d) )/(sqrt(a*a + b*b) * sqrt(c*c + d*d)));
79  if(isDirectionDependent){
80  return angle;
81  }else{
82  if (angle > CV_PI/2){
83  return CV_PI - angle;
84  }else
85  return angle;
86  }
87 }
88 
89 double polyLinePointDist(CvPoint *PointList, int nPnts,CvPoint *C, int *index, int isClosedPolygon){
90 // Calculate minimum distance of Point C to Polygon whose points are in list PointList
91 // if isClosedPolygon is true polygon is closed (segnment of the first and last point is also checked)
92 // index is the index of point A in pointlist,
93 // where A is the starting point of the closest polygon segment
94  *index = -1;
95  double mindist= -1;
96  double dist;
97  for( int i=0; i < nPnts-1; i++){
98  dist=linePointDist(&PointList[i],&PointList[i+1],C,1);
99  if (mindist == -1 || dist<mindist){
100  mindist = dist;
101  *index = i;
102  }
103  }
104  if(isClosedPolygon){
105  dist=linePointDist(&PointList[nPnts-1],&PointList[0],C,1);
106  if (dist<mindist){
107  mindist = dist;
108  *index = nPnts-1;
109  }
110  }
111  return mindist;
112 
113 }
114 
115 //ttesis
116 
117 void FitCVEllipse(const vector<PointDouble> &points, CvBox2D& ellipse_box)
118 {
119  if(points.size() < 8) return;
120 
121  CvMat* vector = cvCreateMat(1, int(points.size()), CV_64FC2);
122  for(size_t i = 0; i < points.size(); ++i)
123  {
124  CV_MAT_ELEM(*vector, CvPoint2D64f, 0, i) = (CvPoint2D64f)points[i];
125  }
126  ellipse_box = cvFitEllipse2(vector);
127  cvReleaseMat(&vector);
128 }
129 
130 int exp_filt2(vector<double> &v, vector<double> &ret, bool clamp)
131 {
132  double y;
133  int n = (int)v.size();
134 
135  double a = pow(0.01, 8.0/n);//0.8;
136  double k = -log(a);
137 
138  // Forward
139  vector<double> yp(n);
140 
141  y = 0;
142  for(int i = 0; i < n; ++i)
143  y = a * y + v[i];
144 
145  y *= 1.0 / (1.0-pow(a,n));
146 
147  for(int i = 0; i < n; ++i)
148  {
149  y = a * y + v[i];
150  yp[i] = y;
151  }
152 
153  // Backward
154  vector<double> ym(n);
155 
156  y = 0;
157  for(int i = n-1; i >= 0; --i)
158  y = a * y + v[i];
159 
160  y *= 1.0 / (1.0-pow(a,n));
161 
162  for(int i = n-1; i >= 0; --i)
163  {
164  y = a * y + v[i];
165  ym[i] = y;
166  }
167 
168  // Filter
169  ret.resize(n);
170  for(int i = 0; i < n; ++i)
171  {
172  ret[i] = (k/2.0) * (yp[i] + ym[i] - v[i]);
173  }
174 
175  return int(ret.size());
176 }
177 
178 int find_zero_crossings(const vector<double>& v, vector<int> &corners, int offs)
179 {
180  int ind = 0;
181  int len = (int)v.size();
182 
183  int state;
184  if(Sign(v.at(0)) == 1)
185  state = 1;
186  else
187  state = 2;
188 
189  corners.clear();
190  for(int i = 0; i < len+offs; ++i)
191  {
192  if(i<len)
193  ind = i;
194  else
195  ind = i-len;
196 
197  int s = Sign(v.at(ind));
198  if(state == 1 && s == -1)
199  state = 2;
200  if(state == 2 && s == 1)
201  {
202  state = 1;
203  bool test = true;
204  for(unsigned j = 0; j < corners.size(); ++j)
205  if(corners.at(j) == ind)
206  test = false;
207 
208  if(test)
209  corners.push_back(ind);
210  }
211  }
212 
213  return int(corners.size());
214 }
215 
216 void out_matrix(const CvMat *m, const char *name) {
217  if (m->cols == 1) {
218  std::cout<<name<<" = [";
219  for (int j=0; j<m->rows; j++) {
220  std::cout<<" "<<cvGet2D(m, j, 0).val[0];
221  }
222  std::cout<<"]^T"<<std::endl;
223  } else if (m->rows == 1) {
224  std::cout<<name<<" = [";
225  for (int i=0; i<m->cols; i++) {
226  std::cout<<" "<<cvGet2D(m, 0, i).val[0];
227  }
228  std::cout<<"]^T"<<std::endl;
229  } else {
230  std::cout<<name<<" = ["<<std::endl;
231  for (int j=0; j<m->rows; j++) {
232  for (int i=0; i<m->cols; i++) {
233  std::cout<<" "<<cvGet2D(m, j, i).val[0];
234  }
235  std::cout<<std::endl;
236  }
237  std::cout<<"]"<<std::endl;
238  }
239 }
240 
241 double Limit(double val, double min_val, double max_val) {
242  return max(min_val, min(max_val, val));
243 }
244 
245 Index::Index(int a) { val.push_back(a); }
246 
247 Index::Index(int a, int b) {
248  val.push_back(a);
249  val.push_back(b);
250 }
251 
252 Index::Index(int a, int b, int c) {
253  val.push_back(a);
254  val.push_back(b);
255  val.push_back(c);
256 }
257 
258 bool Index::operator<(const Index &index) const {
259  int comp=0;
260  size_t d=0;
261  // Go through the dimensions (last being the most significant)
262  while ((d < val.size()) || (d < index.val.size())) {
263  int v0 = (d < val.size() ? val[d] : 0);
264  int v1 = (d < index.val.size() ? index.val[d] : 0);
265  if (v0<v1) comp=-1;
266  else if (v1<v0) comp=1;
267  d++;
268  }
269  if (comp == -1) return true;
270  return false;
271 }
272 
273 int Histogram::DimIndex(int dim, double val) {
274  int binsize = (dim < int(dim_binsize.size()) ? dim_binsize[dim] : 1);
275  if (val >= 0) return int(val+(binsize/2))/binsize;
276  return int(val-(binsize/2))/binsize;
277 }
278 double Histogram::DimVal(int dim, int index) {
279  int binsize = (dim < int(dim_binsize.size()) ? dim_binsize[dim] : 1);
280  return (index * binsize);
281 }
282 void Histogram::AddDimension(int binsize) {
283  dim_binsize.push_back(binsize);
284 }
285 void Histogram::Clear() {
286  bins.clear();
287 }
288 void Histogram::Inc(double dim0, double dim1, double dim2) {
289  Index index(DimIndex(0,dim0), DimIndex(1,dim1), DimIndex(2,dim2));
290  if (bins.find(index) != bins.end()) {
291  bins[index]++;
292  } else {
293  bins[index] = 1;
294  }
295 }
296 int Histogram::GetMax(double *dim0, double *dim1, double *dim2) {
297  map<Index, int>::const_iterator iter, max_iter;
298  int max=0;
299  for (max_iter = iter = bins.begin(); iter != bins.end(); iter++) {
300  if (iter->second > max) {
301  max = iter->second;
302  max_iter = iter;
303  }
304  }
305  if (max > 0) {
306  *dim0 = DimVal(0, max_iter->first.val[0]);
307  if (dim1) *dim1 = DimVal(1, max_iter->first.val[1]);
308  if (dim2) *dim2 = DimVal(2, max_iter->first.val[2]);
309  }
310  return max;
311 }
312 void HistogramSubpixel::Clear() {
313  bins.clear();
314  acc_dim0.clear();
315  acc_dim1.clear();
316  acc_dim2.clear();
317 }
318 void HistogramSubpixel::Inc(double dim0, double dim1, double dim2) {
319  Index index(DimIndex(0,dim0), DimIndex(1,dim1), DimIndex(2,dim2));
320  if (bins.find(index) != bins.end()) {
321  bins[index]++;
322  acc_dim0[index] += dim0;
323  acc_dim1[index] += dim1;
324  acc_dim2[index] += dim2;
325  } else {
326  bins[index] = 1;
327  acc_dim0[index] = dim0;
328  acc_dim1[index] = dim1;
329  acc_dim2[index] = dim2;
330  }
331 }
332 int HistogramSubpixel::GetMax(double *dim0, double *dim1, double *dim2) {
333  map<Index, int>::const_iterator iter;
334  int max=0;
335  int divider=0;
336  for (iter = bins.begin(); iter != bins.end(); iter++) {
337  if (iter->second > max) {
338  divider = max = iter->second;
339  *dim0 = acc_dim0[iter->first];
340  if (dim1) *dim1 = acc_dim1[iter->first];
341  if (dim2) *dim2 = acc_dim2[iter->first];
342  } else if (iter->second == max) {
343  divider += iter->second;
344  *dim0 += acc_dim0[iter->first];
345  if (dim1) *dim1 += acc_dim1[iter->first];
346  if (dim2) *dim2 += acc_dim2[iter->first];
347  }
348  }
349  if (max > 0) {
350  *dim0 /= divider;
351  if (dim1) *dim1 /= divider;
352  if (dim2) *dim2 /= divider;
353  }
354  return max;
355 }
356 
358  TiXmlDocument document;
359  TiXmlElement *xml_current;
360  SerializationFormatterXml() : xml_current(0) {}
361 };
362 
363 bool Serialization::Output() {
364  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
365  if (filename.size() > 0) {
366  //xml->document.LinkEndChild(new TiXmlDeclaration("1.0", "UTF-8", "no"));
367  xml->document.InsertBeforeChild (xml->document.RootElement(), TiXmlDeclaration("1.0", "UTF-8", "no"));
368  xml->document.SaveFile(filename.c_str());
369  } else {
370  const TiXmlNode *node = (xml->xml_current ? xml->xml_current : xml->document.RootElement());
371  std::basic_ostream<char> *os = dynamic_cast<std::basic_ostream<char> *>(stream);
372  (*os)<<(*node);
373  //(*stream)<<(*node);
374  }
375  return true;
376 }
377 
378 bool Serialization::Input() {
379  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
380  if (filename.size() > 0) {
381  xml->document.LoadFile(filename.c_str());
382  } else {
383  // TODO: How this should be handled with nested classes?
384  TiXmlNode *node = (xml->xml_current ? xml->xml_current : xml->document.RootElement());
385  if (node == 0) {
386  node = (TiXmlElement*)xml->document.LinkEndChild(new TiXmlElement("root"));
387  }
388  std::basic_istream<char> *is = dynamic_cast<std::basic_istream<char> *>(stream);
389  (*is)>>(*node);
390  //(*stream)>>(*node);
391  }
392  return true;
393 }
394 
395 bool Serialization::Descend(const char *id) {
396  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
397  if (input) {
398  if (xml->xml_current == 0) {
399  xml->xml_current = xml->document.RootElement();
400  if (!xml->xml_current || (strcmp(xml->xml_current->Value(), id) != 0)) {
401  return false;
402  }
403  } else {
404  xml->xml_current = (TiXmlElement*)xml->xml_current->FirstChild (id);
405  if (xml->xml_current == NULL) return false;
406  }
407  } else {
408  if (xml->xml_current == 0) {
409  xml->xml_current = (TiXmlElement*)xml->document.LinkEndChild(new TiXmlElement(id));
410  } else {
411  xml->xml_current = (TiXmlElement*)xml->xml_current->LinkEndChild(new TiXmlElement(id));
412  }
413  }
414  return true;
415 }
416 bool Serialization::Ascend() {
417  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
418  xml->xml_current = (TiXmlElement*)xml->xml_current->Parent();
419  return true;
420 }
421 
422 Serialization::Serialization(std::string _filename) {
424  formatter_handle = xml;
425  filename = _filename;
426  input = false; // by default output
427 }
428 
429 Serialization::Serialization(std::basic_iostream<char> &_stream)
430 {
432  formatter_handle = xml;
433  stream = &_stream;
434 }
435 
436 Serialization::Serialization(std::basic_istream<char> &_stream) {
438  formatter_handle = xml;
439  stream = &_stream;
440 }
441 
442 Serialization::Serialization(std::basic_ostream<char> &_stream) {
444  formatter_handle = xml;
445  stream = &_stream;
446 }
447 
448 Serialization::~Serialization() {
449  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
450  delete xml;
451 }
452 
453 bool Serialization::Serialize(int &data, const std::string &name) {
454  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
455  if (!xml || !xml->xml_current) return false;
456  bool ret = true;
457  if (input) ret = (xml->xml_current->QueryIntAttribute(name, &data) == TIXML_SUCCESS);
458  else xml->xml_current->SetAttribute(name, data);
459  return ret;
460 }
461 
462 bool Serialization::Serialize(unsigned short &data, const std::string &name) {
463  int i = data;
464  bool ret = Serialize(i, name);
465  data = i;
466  return ret;
467 }
468 
469 bool Serialization::Serialize(unsigned long &data, const std::string &name) {
470  // TODO: Possible overflow here...
471  int i = data;
472  bool ret = Serialize(i, name);
473  data = i;
474  return ret;
475 }
476 
477 bool Serialization::Serialize(double &data, const std::string &name) {
478  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
479  bool ret = true;
480  if (input) ret = (xml->xml_current->QueryDoubleAttribute(name, &data) == TIXML_SUCCESS);
481  else xml->xml_current->SetDoubleAttribute(name.c_str(), data);
482  return ret;
483 }
484 
485 bool Serialization::Serialize(std::string &data, const std::string &name) {
486  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
487  bool ret = true;
488  if (input) {
489  const char *tmp = xml->xml_current->Attribute(name.c_str());
490  if (tmp == NULL) ret=false;
491  else data = tmp;
492  }
493  else xml->xml_current->SetAttribute(name.c_str(), data.c_str());
494  return ret;
495 }
496 
497 bool Serialization::Serialize(CvMat &data, const std::string &name) {
498  SerializationFormatterXml *xml = (SerializationFormatterXml *)formatter_handle;
499  bool ret = true;
500  if (input) {
501  TiXmlElement *xml_matrix = (TiXmlElement*)xml->xml_current->FirstChild(name);
502  if (xml_matrix == NULL) return false;
503  if (!FileFormatUtils::parseXMLMatrix(xml_matrix, &data)) return false;
504  }
505  else {
506  xml->xml_current->LinkEndChild(FileFormatUtils::createXMLMatrix(name.c_str(), &data));
507  }
508  return ret;
509 }
510 
511 } // namespace alvar
Main ALVAR namespace.
Definition: Alvar.h:174
filename
TiXmlElement * xml_current
Definition: Util.cpp:359
TFSIMD_FORCE_INLINE Vector3 cross(const Vector3 &v) const
double ALVAR_EXPORT polyLinePointDist(CvPoint *PointList, int nPnts, CvPoint *C, int *index, int isClosedPolygon)
Calculates minimum distance from Point C to Polygon whose points are in list PointList.
Definition: Util.cpp:89
XmlRpcServer s
int ALVAR_EXPORT dot(CvPoint *A, CvPoint *B, CvPoint *C)
Computes dot product AB.BC.
Definition: Util.cpp:34
TFSIMD_FORCE_INLINE tfScalar distance(const Vector3 &v) const
TFSIMD_FORCE_INLINE const tfScalar & y() const
void ALVAR_EXPORT out_matrix(const CvMat *m, const char *name)
Output OpenCV matrix for debug purposes.
Definition: Util.cpp:216
int find_zero_crossings(const vector< double > &v, vector< int > &corners, int offs)
Definition: Util.cpp:178
int ALVAR_EXPORT Sign(const C &v)
Returns the sign of a number.
Definition: Util.h:54
double ALVAR_EXPORT linePointDist(CvPoint *A, CvPoint *B, CvPoint *C, bool isSegment)
Computes the distance from point C to line (segment) AB.
Definition: Util.cpp:61
int exp_filt2(vector< double > &v, vector< double > &ret, bool clamp)
Definition: Util.cpp:130
This file implements utilities that assist in reading and writing files.
Class for N-dimensional index to be used e.g. with STL maps.
Definition: Util.h:237
Drawable d[32]
This file implements generic utility functions and a serialization interface.
void FitCVEllipse(const vector< PointDouble > &points, CvBox2D &ellipse_box)
Definition: Util.cpp:117
int min(int a, int b)
std::vector< int > val
The indices for each dimension are stored in val (last being the most significant) ...
Definition: Util.h:239
double ALVAR_EXPORT Limit(double val, double min_val, double max_val)
Limits a number to between two values.
Definition: Util.cpp:241
double ALVAR_EXPORT angle(CvPoint *A, CvPoint *B, CvPoint *C, CvPoint *D, int isDirectionDependent)
Computes the angle between lines AB and CD.
Definition: Util.cpp:72


ar_track_alvar
Author(s): Scott Niekum
autogenerated on Mon Jun 10 2019 12:47:04