test_offline.cpp
Go to the documentation of this file.
00001 #include <vector>
00002 #include <opencv2/core/core.hpp>
00003 #include <opencv2/features2d/features2d.hpp>
00004 #include <opencv2/nonfree/features2d.hpp>
00005 #include <opencv2/imgproc/imgproc.hpp>
00006 //#include <opencv/cxcore.h>
00007 #include <opencv2/highgui/highgui.hpp>
00008 #include <iostream>
00009 #include <sstream>
00010 #include <algorithm>
00011 
00012 using namespace cv;
00013 using namespace std;
00014 typedef vector<float> Descriptor;
00015 static const bool DRAW_KEYPOINTS = false;
00016 /*
00017  * SSD
00018  * @short Computes the squareroot of squared differences
00019  * @param a First descriptor
00020  * @param b second descriptor
00021  * @return value of squareroot of squared differences
00022  */
00023 double SSD(Descriptor& a, Descriptor& b)
00024 {
00025   double diff = 0;
00026 
00027   for (unsigned int i = 0; i < a.size(); ++i) {
00028     float delta = a[i] - b[i];
00029     diff += delta*delta;
00030   }
00031 
00032   return diff;
00033 }
00034 
00035 /*
00036  * RatioTest
00037  * @short Computes the  ratio test described in Lowe 2004
00038  * @param a Descriptor from the first image to compare
00039  * @param bList List of descriptors from the second image
00040  * @param threshold Threshold value for ratioTest comparison
00041  *
00042  * @return index of the best match, -1 if no match ratio is less than threshold
00043  */
00044 int ratioTest(Descriptor& a, vector<Descriptor>& bList, double threshold)
00045 {
00046   double bestScore = 1000000;
00047   double secondBest = 1000000;
00048   int bestIndex = -1;
00049 
00050   for (unsigned int b = 0; b < bList.size(); ++b) {
00051     double score = 0;
00052     score = SSD(a, bList[b]);
00053 
00054     if (score < bestScore) {
00055       secondBest = bestScore;
00056       bestScore = score;
00057       bestIndex = b;
00058     } else if (score < secondBest) {
00059       secondBest = score;
00060     }
00061     if ( bestScore / secondBest > threshold) {
00062       bestIndex = -1;
00063     }
00064 
00065   }
00066 
00067   return bestIndex;
00068 }
00069 
00070 /*
00071  * FindMatches
00072  * @short Finds matching points on two images based on the set of descriptors
00073  * extracted from two images
00074  * @param descriptors1 Descriptors from first image
00075  * @param descriptors2 Descriptors from second image
00076  * @param matches1 Indexes of matching points in descriptors1 (returned)
00077  * @param matches2 Indexes of matching points in descriptors2 (returned)
00078  * @param dType Descriptor type
00079  * @param mType Matching distance metric type
00080  */
00081 void findMatches(vector<Descriptor>& descriptors1,
00082                  vector<Descriptor>& descriptors2,
00083                  vector<int>& matches1, vector<int>& matches2)
00084 {
00085   double threshold = 0.01;
00086 
00087   for (unsigned int a = 0; a < descriptors1.size(); ++a)
00088   {
00089     const int bestIndex = ratioTest(descriptors1[a], descriptors2,
00090                                     threshold);
00091     if (bestIndex != -1) {
00092       matches1.push_back(a);
00093       matches2.push_back(bestIndex);
00094     }
00095   }
00096 }
00105 void improvedFindMatches(vector<Descriptor>& descriptors1,
00106                         vector<Descriptor>& descriptors2,
00107                         vector<int>& matches1, vector<int>& matches2)
00108 {
00109     // Ratio threshold for accepting a descriptor
00110     const double threshold = 0.7;
00111 
00112     // Determine matches using the Ratio Test method from Lowe 2004
00113     for (unsigned int a = 0; a < descriptors1.size(); ++a) {
00114         const int bestIndex = ratioTest(descriptors1[a], descriptors2,
00115                                         threshold);
00116         if (bestIndex != -1) {
00117             matches1.push_back(a);
00118             matches2.push_back(bestIndex);
00119         }
00120     }
00121 
00122     // Check that the matches are unique going the other direction
00123     for (unsigned int x = 0; x < matches2.size();) {
00124         const int bestIndex = ratioTest(descriptors2[matches2[x]],
00125                                         descriptors1, threshold);
00126         if (bestIndex != matches1[x]) {
00127             matches1.erase(matches1.begin()+x);
00128             matches2.erase(matches2.begin()+x);
00129         } else {
00130             x++;
00131         }
00132     }
00133 
00134 }
00135 
00136 int main(int argc, char** argv)
00137 {
00138   int count = 1;
00139   if (argc > 1)
00140     count = atoi(argv[1]);
00141   namedWindow("obj_reg");
00142 
00143   vector<KeyPoint> prev_keypoints;
00144   vector<KeyPoint> cur_keypoints;
00145   vector<KeyPoint> cur_sift_keypoints;
00146   vector<KeyPoint> prev_sift_keypoints;
00147   vector<Point2f> cur_points;
00148   vector<Descriptor> prev_descriptors;
00149   vector<Descriptor> cur_descriptors;
00150   vector<Descriptor> prev_sift_descriptors;
00151   vector<Descriptor> cur_sift_descriptors;
00152 
00153   prev_keypoints.clear();
00154   cur_keypoints.clear();
00155   cur_sift_keypoints.clear();
00156   cur_points.clear();
00157   prev_descriptors.clear();
00158   cur_descriptors.clear();
00159   prev_sift_descriptors.clear();
00160   cur_sift_descriptors.clear();
00161 
00162   SURF surf(800, 4, 2, true);
00163   SIFT sift(800, 4, 2, true); //TODO: Fix these parameters
00164   for (int i = 0; i < count; i++)
00165   {
00166     stringstream filepath;
00167     filepath << "/home/thermans/data/mars_lab_aff_pics/balls0/" << i << ".png";
00168     Mat frame;
00169     frame = imread(filepath.str());
00170     Mat bw_frame(frame.rows, frame.cols, CV_8UC1);
00171 
00172     cvtColor(frame, bw_frame, CV_RGB2GRAY);
00173     cur_keypoints.clear();
00174     cur_points.clear();
00175     cur_descriptors.clear();
00176 
00177     vector<float> raw_descriptors;
00178     Mat raw_sift_descriptors;
00179 
00180     try
00181     {
00182       // goodFeaturesToTrack(bw_frame, cur_points, 750, 0.001, 0.1);
00183       // for (unsigned int j = 0; j < cur_points.size(); ++j)
00184       // {
00185       //   cur_keypoints.push_back(KeyPoint(cur_points[j], 16.0));
00186       // }
00187       surf(bw_frame, Mat(), cur_keypoints, raw_descriptors, false);
00188       //sift(bw_frame, Mat(), cur_sift_keypoints, raw_sift_descriptors, false);
00189       for (unsigned int j = 0; j < raw_descriptors.size(); j += 128)
00190       {
00191         Descriptor d(raw_descriptors.begin() + j,
00192                      raw_descriptors.begin()+j+128);
00193         cur_descriptors.push_back(d);
00194       }
00195     }
00196     catch(cv::Exception e)
00197     {
00198       cerr << e.err << endl;
00199     }
00200     vector<int> matches_cur;
00201     vector<int> matches_prev;
00202     matches_cur.clear();
00203     matches_prev.clear();
00204 
00205     cout << "Displaying image " << i << endl;
00206     for (unsigned int j = 0; DRAW_KEYPOINTS && j < cur_keypoints.size(); ++j)
00207     {
00208       circle(frame, cur_keypoints[j].pt,
00209              max(pow(2.0, cur_keypoints[j].octave),2.0),
00210              Scalar(0, 255, 0), 2);
00211     }
00212     if(i > 0)
00213     {
00214       // Find nearest neighbors with previous descriptors
00215       improvedFindMatches(cur_descriptors, prev_descriptors,
00216                           matches_cur, matches_prev);
00217       cout << "matches size: " << matches_cur.size() << endl;
00218       // Draw feature tracks on the image
00219       for (unsigned int j = 0; j < matches_cur.size(); j++)
00220       {
00221         line(frame,
00222              prev_keypoints[matches_prev[j]].pt,
00223              cur_keypoints[matches_cur[j]].pt,
00224              Scalar(0,0,255), 1);
00225         circle(frame,
00226                prev_keypoints[matches_prev[j]].pt,
00227                4,Scalar(0,0,255));
00228         circle(frame,
00229                cur_keypoints[matches_cur[j]].pt,
00230                4, Scalar(255,0,0), 1);
00231       }
00232     }
00233     imshow("obj_reg", frame);
00234     cout << endl;
00235     waitKey();
00236     prev_keypoints = cur_keypoints;
00237     prev_descriptors = cur_descriptors;
00238   }
00239   return 0;
00240 }


cpl_visual_features
Author(s): Tucker Hermans
autogenerated on Wed Nov 27 2013 11:52:36