Measuring the repeatability of a detector


Detailed Description

Functions to load a repeatability dataset, and compute the repeatability of a list of detected points.

The dataset

The dataset consists of a number of registered images. The images are stored in frames/frame_X.pgm where X is an integer counting from zero. The frames must all be the same size. The warps are stored in waprs/warp_Y_Z.warp. The file warp_Y_Z.warp contains one line for every pixel in image Y (pixels arranged in raster-scan order). The line is the position that the pixel warps to in image Z. If location of -1, -1 indicates that this pixel does not appear in image Z.


Functions

vector< ImageRef > generate_disc (int radius)
Image< bool > paint_circles (const vector< ImageRef > &corners, const vector< ImageRef > &circle, ImageRef size)
float compute_repeatability (const vector< vector< Image< array< float, 2 > > > > &warps, const vector< vector< ImageRef > > &corners, int r, ImageRef size)
double compute_repeatability_exact (const vector< vector< Image< array< float, 2 > > > > &warps, const vector< vector< ImageRef > > &corners, double r)
void compute_repeatability_all (const vector< Image< byte > > &images, const vector< vector< Image< array< float, 2 > > > > &warps, const DetectN &detector, const vector< int > &cpf, double fuzz)
void compute_repeatability_noise (const vector< Image< byte > > &images, const vector< vector< Image< array< float, 2 > > > > &warps, const DetectN &detector, int cpf, float n, double fuzz)
void mmain (int argc, char **argv)


Function Documentation

vector<ImageRef> generate_disc ( int  radius  ) 

Generate a disc of ImageRefs.

Parameters:
radius Radius of the disc
Returns:
the disc of ImageRefs

Definition at line 131 of file learn_detector.cc.

Referenced by compute_repeatability().

00132 {
00133     vector<ImageRef> ret;
00134     ImageRef p;
00135 
00136     for(p.y = -radius; p.y <= radius; p.y++)
00137         for(p.x = -radius; p.x <= radius; p.x++)
00138             if((int)p.mag_squared() <= radius)
00139                 ret.push_back(p);
00140     return ret;
00141 }

Image<bool> paint_circles ( const vector< ImageRef > &  corners,
const vector< ImageRef > &  circle,
ImageRef  size 
)

Paint shapes (a vector<ImageRef>) safely in to an image This is used to paint discs at corner locations in order to perform rapid proximity checking.

Parameters:
corners Locations to paint shapes
circle Shape to paint
size Image size to be painted in to
Returns:
Image with shapes painted in to it.

Definition at line 153 of file learn_detector.cc.

Referenced by compute_repeatability().

00154 {   
00155     Image<bool> im(size, 0);
00156 
00157 
00158     for(unsigned int i=0; i < corners.size(); i++)
00159         for(unsigned int j=0; j < circle.size(); j++)
00160             if(im.in_image(corners[i] + circle[j]))
00161                 im[corners[i] + circle[j]] = 1;
00162 
00163     return im;
00164 }

float compute_repeatability ( const vector< vector< Image< array< float, 2 > > > > &  warps,
const vector< vector< ImageRef > > &  corners,
int  r,
ImageRef  size 
)

Computes repeatability the quick way, by caching, but has small rounding errors.

This function paints a disc of true around each detected corner in to an image. If a corner warps to a pixel which has the value true then it is a repeat.

Parameters:
warps Every warping where warps[i][j] specifies warp from image i to image j.
corners Detected corners
r A corner must be as close as this to be considered repeated
size Size of the region for cacheing. All images must be this size.
Returns:
The repeatability.

Definition at line 176 of file learn_detector.cc.

References generate_disc(), ir_rounded(), and paint_circles().

Referenced by learn_detector().

00177 {
00178     unsigned int n = corners.size();
00179 
00180     vector<ImageRef> disc = generate_disc(r);
00181 
00182     vector<Image<bool> >  detected;
00183     for(unsigned int i=0; i < n; i++)
00184         detected.push_back(paint_circles(corners[i], disc, size));
00185     
00186     int corners_tested = 0;
00187     int good_corners = 0;
00188 
00189     for(unsigned int i=0; i < n; i++)
00190         for(unsigned int j=0; j < n; j++)
00191         {
00192             if(i==j)
00193                 continue;
00194             
00195             for(unsigned int k=0; k < corners[i].size(); k++)
00196             {   
00197                 ImageRef dest = ir_rounded(warps[i][j][corners[i][k]]);
00198 
00199                 if(dest.x != -1)
00200                 {
00201                     corners_tested++;
00202                     if(detected[j][dest])
00203                         good_corners++;
00204                 }
00205             }
00206         }
00207     
00208     return 1.0 * good_corners / (DBL_EPSILON + corners_tested);
00209 }

double compute_repeatability_exact ( const vector< vector< Image< array< float, 2 > > > > &  warps,
const vector< vector< ImageRef > > &  corners,
double  r 
)

Computes repeatability the slow way to avoid rounding errors, by comparing the warped corner position to every detected corner.

A warp to x=-1, y=? is considered to be outside the image, so it is not counted.

Parameters:
warps Every warping where warps[i][j] specifies warp from image i to image j.
corners Detected corners
r A corner must be as close as this to be considered repeated
Returns:
The repeatability. No corners means zero repeatability.

Definition at line 76 of file test_repeatability.cc.

Referenced by compute_repeatability_all(), and compute_repeatability_noise().

00077 {
00078     unsigned int n = corners.size();
00079 
00080     int repeatable_corners = 0;
00081     int repeated_corners = 0;
00082 
00083     r *= r;
00084 
00085     for(unsigned int i=0; i < n; i++)
00086         for(unsigned int j=0; j < n; j++)
00087         {
00088             if(i==j)
00089                 continue;
00090 
00091             for(unsigned int k=0; k < corners[i].size(); k++)
00092             {
00093                 const array<float, 2>& p = warps[i][j][corners[i][k]];
00094 
00095                 if(p[0] != -1) //pixel does not warp to inside image j
00096                 {
00097 
00098                     repeatable_corners++;
00099 
00100                     for(unsigned int l=0; l < corners[j].size(); l++)
00101                     {
00102                         Vector<2> d = Vec(p) - vec(corners[j][l]);
00103 
00104                         if(d*d < r)
00105                         {
00106                             repeated_corners++;
00107                             break;
00108                         }
00109                     }
00110                 }
00111             }
00112         }
00113     
00114     return 1.0 * (repeated_corners) / (repeatable_corners + DBL_EPSILON);
00115 }

void compute_repeatability_all ( const vector< Image< byte > > &  images,
const vector< vector< Image< array< float, 2 > > > > &  warps,
const DetectN detector,
const vector< int > &  cpf,
double  fuzz 
)

This wrapper function computed the repeatability for a given detector and a given container of corner densities.

The result is printed to stdout.

Parameters:
images Images to test repeatability on
warps Every warping where warps[i][j] specifies warp from image i to image j.
detector Pointer to the corner detection function.
cpf The number of corners per frame to be tested.
fuzz A corner must be as close as this to be considered repeated

Definition at line 126 of file test_repeatability.cc.

References compute_repeatability_exact().

Referenced by mmain().

00127 {
00128     
00129     for(unsigned int i=0; i < cpf.size(); i++)
00130     {
00131         //Detect corners in each if the frames
00132         vector<vector<ImageRef> > corners;
00133         double  num_corners = 0;
00134 
00135         for(unsigned int j=0; j < images.size(); j++)
00136         {
00137             vector<ImageRef> c;
00138             detector(images[j], c, cpf[i]);
00139             corners.push_back(c);
00140 
00141             num_corners += c.size();
00142         }
00143 
00144         //Compute and print the repeatability.
00145         cout << print << num_corners / images.size() << compute_repeatability_exact(warps, corners, fuzz);
00146     }
00147 }

void compute_repeatability_noise ( const vector< Image< byte > > &  images,
const vector< vector< Image< array< float, 2 > > > > &  warps,
const DetectN detector,
int  cpf,
float  n,
double  fuzz 
)

This wrapper function computed the repeatability for a given detector and a given container of corner densities for variable levels of noise, from 0 to n in steps of 1 The result is printed to stdout.

Parameters:
images Images to test repeatability on
warps Every warping where warps[i][j] specifies warp from image i to image j.
detector Pointer to the corner detection function.
cpf The number of corners per frame to be tested.
n The initial noise level
fuzz A corner must be as close as this to be considered repeated

Definition at line 161 of file test_repeatability.cc.

References compute_repeatability_exact().

Referenced by mmain().

00162 {
00163         
00164     for(float s=0; s <= n; s++)
00165     {
00166 
00167 
00168         //Detect corners in each if the frames
00169         vector<vector<ImageRef> > corners;
00170         double  num_corners = 0;
00171 
00172         for(unsigned int j=0; j < images.size(); j++)
00173         {
00174             Image<byte> ni = images[j].copy_from_me();
00175 
00176             //Add noise to the image
00177             for(Image<byte>::iterator i=ni.begin(); i != ni.end(); i++)
00178                 *i = max(0, min(255, (int)floor(*i + rand_g() * s + .5)));
00179 
00180             vector<ImageRef> c;
00181             detector(ni, c, cpf);
00182             corners.push_back(c);
00183 
00184             num_corners += c.size();
00185         }
00186 
00187         //Compute and print the repeatability.
00188         cout << print << s << compute_repeatability_exact(warps, corners, fuzz) << num_corners / images.size();
00189     }
00190 }

void mmain ( int  argc,
char **  argv 
)

This is the driver function.

It reads the command line arguments and calls functions to load the data and compute the repeatability.

Parameters:
argc Number of command line argumentsd.
argv Pointer to command line arguments.

Definition at line 199 of file test_repeatability.cc.

References compute_repeatability_all(), compute_repeatability_noise(), get_detector(), and load_data().

Referenced by main().

00200 {
00201     GUI.LoadFile("test_repeatability.cfg");
00202     GUI.parseArguments(argc, argv);
00203 
00204     vector<Image<byte> > images;
00205     vector<vector<Image<array<float, 2> > > > warps;
00206 
00207 
00208     int n = GV3::get<int>("num", 2, 1);
00209     string dir = GV3::get<string>("dir", "./", 1);
00210     string format = GV3::get<string>("type", "cambridge", 1);
00211     double fuzz = GV3::get<double>("r", 5, 1);
00212     vector<int> cpf = GV3::get<vector<int> >("cpf", "0 10 20 30 40 50 60 70 80 90 100 150 200 250 300 350 400 450 500 550 600 650 700 750 800 850 900 950 1000 1100 1200 1300 1400 1500 1600 1700 1800 1900 2000 2200", 1);
00213     int ncpf = GV3::get<int>("ncpf", 500, 1);
00214     float nmax = GV3::get<int>("nmax", 50, 1);
00215     string test = GV3::get<string>("test", "normal", 1);
00216     
00217     auto_ptr<DetectN> detector = get_detector();
00218 
00219     rpair(images, warps) = load_data(dir, n, format);
00220     
00221     if(test == "noise")
00222         compute_repeatability_noise(images, warps, *detector, ncpf, nmax, fuzz);
00223     else
00224         compute_repeatability_all(images, warps, *detector, cpf, fuzz);
00225 
00226 }


Generated on Mon Mar 2 12:47:12 2009 for FAST-ER by  doxygen 1.5.3