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 }