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
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
00018
00019
00020
00021
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
00037
00038
00039
00040
00041
00042
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
00072
00073
00074
00075
00076
00077
00078
00079
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
00110 const double threshold = 0.7;
00111
00112
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
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);
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
00183
00184
00185
00186
00187 surf(bw_frame, Mat(), cur_keypoints, raw_descriptors, false);
00188
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
00215 improvedFindMatches(cur_descriptors, prev_descriptors,
00216 matches_cur, matches_prev);
00217 cout << "matches size: " << matches_cur.size() << endl;
00218
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 }