Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
ExampleTrackerBaseInterface.cpp

See TestData/affine in cvs for generating test images. , GradientGaussAsymmetric

/*
This file is part of the BIAS library (Basic ImageAlgorithmS).
Copyright (C) 2003-2009 (see file CONTACT for details)
Multimediale Systeme der Informationsverarbeitung
Institut fuer Informatik
Christian-Albrechts-Universitaet Kiel
BIAS is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
BIAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with BIAS; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/** @example ExampleTrackerBaseInterface.cpp
@relates TrackerBaseSimple, GradientGaussAsymmetric
@ingroup g_examples
@brief See TestData/affine in cvs for generating test images.
*/
#include <Matcher2D/TrackerBaseSimple.hh>
#include <Base/Image/Image.hh>
#include <Base/ImageUtils/ImageDraw.hh>
#include <Base/Image/ImageIO.hh>
#include <Base/Image/ImageConvert.hh>
#include <Base/Geometry/HomgPoint2D.hh>
#include <Base/Debug/TimeMeasure.hh>
#include <Filter/GradientSobel3x3.hh>
#include <Filter/GradientGauss.hh>
#include <Filter/GradientGaussAsymmetric.hh>
#include <Filter/Binomial.hh>
#include <iostream>
#include <iomanip>
using namespace BIAS;
using namespace std;
// always track using float image, since it is a lot faster
#define StorageType float
// loads an image and converts to single channel float image
int LoadImage(const string& name, Image<StorageType>& im)
{
ImageBase baseim;
// load image
if (ImageIO::Load(name, baseim)!=0){
BIASERR("error loading image "<<name);
return -1;
}
// convert to float
BIASERR("error converting image "<<name);
return -2;
}
// convert to grey if necessary
if (im.GetChannelCount()!=1){
if (ImageConvert::ToGrey(im, im)!=0){
BIASERR("error converting image to grey "<<name);
return -3;
}
}
im.SetMetaData(*baseim.GetMetaData());
return 0;
}
// draws the tracking result and saves to name.tracked
const string& name)
{
unsigned uip[2], radius=1;
unsigned char color[]={255,0,0};
float cov_scale=1e5;
bool draw_cov=true;
// convert to unsigned char
BIASERR("error converting image to unsigned char "<<name);
BIASABORT;
}
// convert to rgb if necessary
if (ImageConvert::ToRGB(dim, dim)!=0){
BIASERR("error converting image to RGB "<<name);
BIASABORT;
}
}
uip[0]=(unsigned int)rint(p[0]);
uip[1]=(unsigned int)rint(p[1]);
CircleCenterFilled(dim, uip[0], uip[1], radius, color);
if (draw_cov){
double center[2], a[2], b[2], eva, evb;
center[0]=p[0];
center[1]=p[1];
cov.EigenvalueDecomposition(eva, na, evb, nb);
cout << eva<<", "<<evb<<"\n";
a[0]=na[0]*eva*cov_scale;
a[1]=na[1]*eva*cov_scale;
b[0]=nb[0]*evb*cov_scale;
b[1]=nb[1]*evb*cov_scale;
Ellipse(dim, center, a, b, color);
}
//ImageIO::Save(name, dim);
ImageIO::Save(name, dim);
cout << "wrote "<<name<<endl;
}
// the main function
int main(int argc, char*argv[])
{
// choose tracker type
//TrackerBaseWeighted<StorageType> tracker;
//TrackerBaseAffine<StorageType> tracker;
// read parameters from command line
int argind = 1;
if (argc-argind<4 || argind<1)
{
cerr << argv[0] << " : <x-coo> <y-coo> <image> <image> ..."<< endl;
return -1;
}
// get the point to track from command line
p[0][2] = p[1][2] = 1.0;
p[0][0] = atof(argv[argind]);
p[0][1] = atof(argv[argind+1]);
cout << "attempt to track point " << p[0] << endl;
// load first image
if (LoadImage(argv[argind+2], im[0]) != 0)
{
BIASERR("error loading image " << argv[argind+2]);
return -1;
}
int oldim = 0;
int newim = 1;
// loop through the images
for (int counter = argind+3; counter < argc-1; counter++)
{
// load image
if (LoadImage(argv[counter], im[newim]) != 0)
{
BIASERR("Failed to load image " << argv[counter]);
return -1;
}
// initialize tracker
Matrix3x3<FM_FLOAT> lowpass(1, 2, 1,
2, 4, 2,
1, 2, 1);
Matrix3x3<FM_FLOAT> gradx(-1, 0, 1,
-2, 0, 2,
-1, 0, 1);
Matrix3x3<FM_FLOAT> grady(-1, -2, -1,
0, 0, 0,
1, 2, 1);
FilterMask fmLowpass((Matrix<float>)lowpass);
FilterMask fmGradX((Matrix<float>)gradx);
FilterMask fmGradY((Matrix<float>)grady);
tracker.Init(im[oldim], im[newim],
fmLowpass, fmGradX, fmGradY);
// do the tracking!
KLT_TYPE error, residuumMAD, residuumMSD;
int iter;
int result = tracker.Track(p[oldim], p[oldim], p[newim],
error, iter, residuumMAD,
residuumMSD, cov);
cout << setw(3)
<< counter-3 << ": "
<< "result: " << result << ", "
<< p[oldim] << " -> " << p[newim] << ", "
<< "residuumMAD: " << residuumMAD << ", "
<< "residuumMSD: " << residuumMSD << endl;
// draw and save result
ostringstream name;
name << "track-"<<setw(4)<<setfill('0')<<counter-argind<<".mip";
Draw(im[newim], p[newim], cov, name.str());
swap(newim, oldim);
}
return 0;
}