Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleTrackerBaseInterface.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003-2009 (see file CONTACT for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 
26 /** @example ExampleTrackerBaseInterface.cpp
27  @relates TrackerBaseSimple, GradientGaussAsymmetric
28  @ingroup g_examples
29  @brief See TestData/affine in cvs for generating test images.
30 */
31 
32 #include <Matcher2D/TrackerBaseSimple.hh>
33 #include <Base/Image/Image.hh>
34 #include <Base/ImageUtils/ImageDraw.hh>
35 #include <Base/Image/ImageIO.hh>
36 #include <Base/Image/ImageConvert.hh>
37 #include <Base/Geometry/HomgPoint2D.hh>
38 #include <Base/Debug/TimeMeasure.hh>
39 #include <Filter/GradientSobel3x3.hh>
40 #include <Filter/GradientGauss.hh>
41 #include <Filter/GradientGaussAsymmetric.hh>
42 #include <Filter/Binomial.hh>
43 
44 #include <iostream>
45 #include <iomanip>
46 
47 using namespace BIAS;
48 using namespace std;
49 
50 
51 // always track using float image, since it is a lot faster
52 #define StorageType float
53 
54 
55 // loads an image and converts to single channel float image
56 int LoadImage(const string& name, Image<StorageType>& im)
57 {
58  ImageBase baseim;
59 
60  // load image
61  if (ImageIO::Load(name, baseim)!=0){
62  BIASERR("error loading image "<<name);
63  return -1;
64  }
65  // convert to float
66  if (ImageConvert::ConvertST(baseim, im, ImageBase::ST_float)!=0){
67  BIASERR("error converting image "<<name);
68  return -2;
69  }
70  // convert to grey if necessary
71  if (im.GetChannelCount()!=1){
72  if (ImageConvert::ToGrey(im, im)!=0){
73  BIASERR("error converting image to grey "<<name);
74  return -3;
75  }
76  }
77  im.SetMetaData(*baseim.GetMetaData());
78 
79  return 0;
80 }
81 
82 // draws the tracking result and saves to name.tracked
83 void Draw(Image<StorageType>& im, HomgPoint2D& p, Matrix2x2<KLT_TYPE>& cov,
84  const string& name)
85 {
87  unsigned uip[2], radius=1;
88  unsigned char color[]={255,0,0};
89  float cov_scale=1e5;
90  bool draw_cov=true;
91 
92 
93  // convert to unsigned char
95  BIASERR("error converting image to unsigned char "<<name);
96  BIASABORT;
97  }
98 
99  // convert to rgb if necessary
100  if (dim.GetColorModel()!=ImageBase::CM_RGB){
101  if (ImageConvert::ToRGB(dim, dim)!=0){
102  BIASERR("error converting image to RGB "<<name);
103  BIASABORT;
104  }
105  }
106 
107  uip[0]=(unsigned int)rint(p[0]);
108  uip[1]=(unsigned int)rint(p[1]);
109 
111  CircleCenterFilled(dim, uip[0], uip[1], radius, color);
112 
113  if (draw_cov){
114  double center[2], a[2], b[2], eva, evb;
115  Vector2<double> na, nb;
116  center[0]=p[0];
117  center[1]=p[1];
118 
119  cov.EigenvalueDecomposition(eva, na, evb, nb);
120  cout << eva<<", "<<evb<<"\n";
121  a[0]=na[0]*eva*cov_scale;
122  a[1]=na[1]*eva*cov_scale;
123  b[0]=nb[0]*evb*cov_scale;
124  b[1]=nb[1]*evb*cov_scale;
126  Ellipse(dim, center, a, b, color);
127  }
128 
129  //ImageIO::Save(name, dim);
130  ImageIO::Save(name, dim);
131  cout << "wrote "<<name<<endl;
132 }
133 
134 // the main function
135 int main(int argc, char*argv[])
136 {
137  // choose tracker type
139  //TrackerBaseWeighted<StorageType> tracker;
140  //TrackerBaseAffine<StorageType> tracker;
141 
142  // read parameters from command line
143  int argind = 1;
144  if (argc-argind<4 || argind<1)
145  {
146  cerr << argv[0] << " : <x-coo> <y-coo> <image> <image> ..."<< endl;
147  return -1;
148  }
149 
150  // get the point to track from command line
151  HomgPoint2D p[2];
152  p[0][2] = p[1][2] = 1.0;
153  p[0][0] = atof(argv[argind]);
154  p[0][1] = atof(argv[argind+1]);
155  cout << "attempt to track point " << p[0] << endl;
156 
157  // load first image
158  Image<StorageType> im[2];
159  if (LoadImage(argv[argind+2], im[0]) != 0)
160  {
161  BIASERR("error loading image " << argv[argind+2]);
162  return -1;
163  }
164 
165  int oldim = 0;
166  int newim = 1;
167 
168  // loop through the images
169  for (int counter = argind+3; counter < argc-1; counter++)
170  {
171  // load image
172  if (LoadImage(argv[counter], im[newim]) != 0)
173  {
174  BIASERR("Failed to load image " << argv[counter]);
175  return -1;
176  }
177 
178  // initialize tracker
179  Matrix3x3<FM_FLOAT> lowpass(1, 2, 1,
180  2, 4, 2,
181  1, 2, 1);
182 
183  Matrix3x3<FM_FLOAT> gradx(-1, 0, 1,
184  -2, 0, 2,
185  -1, 0, 1);
186 
187  Matrix3x3<FM_FLOAT> grady(-1, -2, -1,
188  0, 0, 0,
189  1, 2, 1);
190 
191  FilterMask fmLowpass((Matrix<float>)lowpass);
192  FilterMask fmGradX((Matrix<float>)gradx);
193  FilterMask fmGradY((Matrix<float>)grady);
194 
195  tracker.Init(im[oldim], im[newim],
196  fmLowpass, fmGradX, fmGradY);
197 
198  // do the tracking!
199  KLT_TYPE error, residuumMAD, residuumMSD;
201  int iter;
202  int result = tracker.Track(p[oldim], p[oldim], p[newim],
203  error, iter, residuumMAD,
204  residuumMSD, cov);
205 
206  cout << setw(3)
207  << counter-3 << ": "
208  << "result: " << result << ", "
209  << p[oldim] << " -> " << p[newim] << ", "
210  << "residuumMAD: " << residuumMAD << ", "
211  << "residuumMSD: " << residuumMSD << endl;
212 
213  // draw and save result
214  ostringstream name;
215  name << "track-"<<setw(4)<<setfill('0')<<counter-argind<<".mip";
216  Draw(im[newim], p[newim], cov, name.str());
217 
218  swap(newim, oldim);
219  }
220 
221  return 0;
222 }
223 
class HomgPoint2D describes a point with 2 degrees of freedom in projective coordinates.
Definition: HomgPoint2D.hh:67
void Init(Image< StorageType > &im1, Image< StorageType > &im2, Image< StorageType > &gradx1, Image< StorageType > &grady1, Image< StorageType > &gradx2, Image< StorageType > &grady2)
Prepare for tracking with prefiltered images.
MetaData * GetMetaData()
Definition: ImageBase.hh:456
float image storage type
Definition: ImageBase.hh:118
static int CircleCenterFilled(Image< StorageType > &im, unsigned int CenterX, unsigned int CenterY, unsigned int Radius, const StorageType Value[])
draws a filled circle using Value
Definition: ImageDraw.cpp:1023
int Track(HomgPoint2D &p1, HomgPoint2D &p2, HomgPoint2D &p2tracked, KLT_TYPE &error, int &iter, KLT_TYPE &residuumMAD, KLT_TYPE &residuumMSD, Matrix< KLT_TYPE > &cov, const Matrix2x2< KLT_TYPE > &AffinePred=Matrix2x2< KLT_TYPE >(MatrixIdentity), Matrix2x2< KLT_TYPE > *AffineResult=NULL)
Calculates correspondence from image1 to image2.
static int ConvertST(const BIAS::ImageBase &source, BIAS::ImageBase &dest, ImageBase::EStorageType targetST)
Function to convert the storage type of images e.g.
static int Ellipse(Image< StorageType > &im, double center[2], double a[2], double b[2], const StorageType Value[])
draws an ellipse at center with half axes a and b
Definition: ImageDraw.cpp:1255
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
Definition: ImageBase.hh:382
color values, 3 channels, order: red,green,blue
Definition: ImageBase.hh:131
The image template class for specific storage types.
Definition: Image.hh:78
static int Save(const std::string &filename, const ImageBase &img, const enum TFileFormat FileFormat=FF_auto, const bool sync=BIAS_DEFAULT_SYNC, const int c_jpeg_quality=BIAS_DEFAULT_IMAGE_QUALITY, const bool forceNewID=BIAS_DEFAULT_FORCENEWID, const bool &writeMetaData=true)
Export image as file using extrnal libs.
Definition: ImageIO.cpp:725
is a &#39;fixed size&#39; quadratic matrix of dim.
Definition: Matrix.hh:54
int EigenvalueDecomposition(T &value1, Vector2< T > &vector1, T &value2, Vector2< T > &vector2) const
Eigenvalue decomposition.
Definition: Matrix2x2.cpp:131
enum EColorModel GetColorModel() const
Definition: ImageBase.hh:407
matrix class with arbitrary size, indexing is row major.
static int Load(const std::string &FileName, ImageBase &img)
first tries a call to Read MIP image and if that fails, tries to Import Image with all other availabl...
Definition: ImageIO.cpp:141
(8bit) unsigned char image storage type
Definition: ImageBase.hh:112
void SetMetaData(const MetaData &m)
Definition: ImageBase.hh:470
A filter mask (or a kernel) used for convolution.
Definition: FilterMask.hh:61
This is the base class for images in BIAS.
Definition: ImageBase.hh:102
static int ToRGB(const Image< StorageType > &source, Image< StorageType > &dest)
Create a RGB converted copy of source image in this.
static int ToGrey(const ImageBase &source, ImageBase &dest)
wrapper for the templated function ToGrey