00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 #include <vector>
00036 #include <opencv2/core/core.hpp>
00037 #include <opencv2/imgproc/imgproc.hpp>
00038 #include <opencv2/features2d/features2d.hpp>
00039 #include <opencv2/nonfree/features2d.hpp>
00040 #include <opencv2/highgui/highgui.hpp>
00041 #include <iostream>
00042 #include <sstream>
00043 #include <algorithm>
00044 
00045 using namespace cv;
00046 using namespace std;
00047 typedef vector<float> Descriptor;
00048 static const bool DRAW_KEYPOINTS = false;
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 double SSD(Descriptor& a, Descriptor& b)
00057 {
00058   double diff = 0;
00059 
00060   for (unsigned int i = 0; i < a.size(); ++i) {
00061     float delta = a[i] - b[i];
00062     diff += delta*delta;
00063   }
00064 
00065   return diff;
00066 }
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 int ratioTest(Descriptor& a, vector<Descriptor>& bList, double threshold)
00078 {
00079   double bestScore = 1000000;
00080   double secondBest = 1000000;
00081   int bestIndex = -1;
00082 
00083   for (unsigned int b = 0; b < bList.size(); ++b) {
00084     double score = 0;
00085     score = SSD(a, bList[b]);
00086 
00087     if (score < bestScore) {
00088       secondBest = bestScore;
00089       bestScore = score;
00090       bestIndex = b;
00091     } else if (score < secondBest) {
00092       secondBest = score;
00093     }
00094     if ( bestScore / secondBest > threshold) {
00095       bestIndex = -1;
00096     }
00097 
00098   }
00099 
00100   return bestIndex;
00101 }
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 void findMatches(vector<Descriptor>& descriptors1,
00115                  vector<Descriptor>& descriptors2,
00116                  vector<int>& matches1, vector<int>& matches2)
00117 {
00118   double threshold = 0.01;
00119 
00120   for (unsigned int a = 0; a < descriptors1.size(); ++a)
00121   {
00122     const int bestIndex = ratioTest(descriptors1[a], descriptors2,
00123                                     threshold);
00124     if (bestIndex != -1) {
00125       matches1.push_back(a);
00126       matches2.push_back(bestIndex);
00127     }
00128   }
00129 }
00138 void improvedFindMatches(vector<Descriptor>& descriptors1,
00139                         vector<Descriptor>& descriptors2,
00140                         vector<int>& matches1, vector<int>& matches2)
00141 {
00142     
00143     const double threshold = 0.3;
00144 
00145     
00146     for (unsigned int a = 0; a < descriptors1.size(); ++a) {
00147         const int bestIndex = ratioTest(descriptors1[a], descriptors2,
00148                                         threshold);
00149         if (bestIndex != -1) {
00150             matches1.push_back(a);
00151             matches2.push_back(bestIndex);
00152         }
00153     }
00154 
00155     
00156     for (unsigned int x = 0; x < matches2.size();) {
00157         const int bestIndex = ratioTest(descriptors2[matches2[x]],
00158                                         descriptors1, threshold);
00159         if (bestIndex != matches1[x]) {
00160             matches1.erase(matches1.begin()+x);
00161             matches2.erase(matches2.begin()+x);
00162         } else {
00163             x++;
00164         }
00165     }
00166 
00167 }
00168 
00169 int main(int argc, char** argv)
00170 {
00171   int count = 1;
00172   if (argc > 1)
00173     count = atoi(argv[1]);
00174   namedWindow("obj_reg");
00175 
00176   vector<KeyPoint> prev_keypoints;
00177   vector<KeyPoint> cur_keypoints;
00178   vector<Descriptor> prev_descriptors;
00179   vector<Descriptor> cur_descriptors;
00180 
00181   prev_keypoints.clear();
00182   cur_keypoints.clear();
00183   prev_descriptors.clear();
00184   cur_descriptors.clear();
00185 
00186   SURF surf(800, 4, 2, true);
00187   for (int i = 182; i < count; i++)
00188   {
00189     stringstream filepath;
00190     filepath << "/home/thermans/data/pioneer-frames/from_bag1/" << i << ".png";
00191     Mat frame;
00192     frame = imread(filepath.str());
00193     cout << "Image " << filepath.str() << " has size: (" << frame.cols << ", " << frame.rows << ")" << endl;
00194     Mat bw_frame(frame.rows, frame.cols, CV_8UC1);
00195 
00196     cvtColor(frame, bw_frame, CV_RGB2GRAY);
00197     cur_keypoints.clear();
00198     cur_descriptors.clear();
00199 
00200     vector<float> raw_descriptors;
00201 
00202     try
00203     {
00204       surf(bw_frame, Mat(), cur_keypoints, raw_descriptors);
00205       for (unsigned int j = 0; j < raw_descriptors.size(); j += 128)
00206       {
00207         Descriptor d(raw_descriptors.begin() + j,
00208                      raw_descriptors.begin()+j+128);
00209         cur_descriptors.push_back(d);
00210       }
00211     }
00212     catch(cv::Exception e)
00213     {
00214       cerr << e.err << endl;
00215     }
00216     vector<int> matches_cur;
00217     vector<int> matches_prev;
00218     matches_cur.clear();
00219     matches_prev.clear();
00220 
00221     cout << "Displaying image " << i << endl;
00222     for (int j = 0; DRAW_KEYPOINTS && j < cur_keypoints.size(); ++j)
00223     {
00224       circle(frame, cur_keypoints[j].pt,
00225              max(pow(2.0, cur_keypoints[j].octave),2.0),
00226              Scalar(0, 255, 0), 2);
00227     }
00228     if(i > 0)
00229     {
00230       
00231       improvedFindMatches(cur_descriptors, prev_descriptors,
00232                           matches_cur, matches_prev);
00233       cout << "matches size: " << matches_cur.size() << endl;
00234       
00235       for (unsigned int j = 0; j < matches_cur.size(); j++)
00236       {
00237         line(frame,
00238              prev_keypoints[matches_prev[j]].pt,
00239              cur_keypoints[matches_cur[j]].pt,
00240              Scalar(0,0,255), 1);
00241       }
00242     }
00243     imshow("obj_reg", frame);
00244     cout << endl;
00245     char c = waitKey(10);
00246     prev_keypoints = cur_keypoints;
00247     prev_descriptors = cur_descriptors;
00248   }
00249   return 0;
00250 }