sift.cpp
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <iostream>
00025 #include <vector>
00026
00027 #include <classifiers/sift.h>
00028
00029 #include <utils/time/clock.h>
00030 #include <utils/time/tracker.h>
00031
00032
00033 extern "C" {
00034 #include <sift/sift.h>
00035 #include <sift/imgfeatures.h>
00036 #include <sift/kdtree.h>
00037 #include <sift/utils.h>
00038 #include <sift/xform.h>
00039 }
00040
00041 #include <core/exception.h>
00042 #include <core/exceptions/software.h>
00043 #include <fvutils/color/colorspaces.h>
00044 #include <fvutils/color/conversions.h>
00045
00046 #include <opencv/cv.h>
00047 #include <opencv/cxcore.h>
00048 #include <opencv/highgui.h>
00049
00050 using namespace fawkes;
00051
00052 namespace firevision {
00053 #if 0
00054 }
00055 #endif
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 SiftClassifier::SiftClassifier( const char * object_file,
00079 unsigned int pixel_width, unsigned int pixel_height,
00080 int kdtree_bbf_max_nn_chks, float nn_sq_dist_ratio_thr, int flags)
00081 : Classifier("SiftClassifier")
00082 {
00083 __kdtree_bbf_max_nn_chks = kdtree_bbf_max_nn_chks;
00084 __nn_sq_dist_ratio_thr = nn_sq_dist_ratio_thr;
00085 __flags = flags;
00086
00087
00088
00089 __tt = new TimeTracker();
00090 __loop_count = 0;
00091 __ttc_objconv = __tt->add_class("ObjectConvert");
00092 __ttc_objfeat = __tt->add_class("ObjectFeatures");
00093 __ttc_imgconv = __tt->add_class("ImageConvert");
00094 __ttc_imgfeat = __tt->add_class("ImageFeatures");
00095 __ttc_matchin = __tt->add_class("Matching");
00096 __ttc_roimerg = __tt->add_class("MergeROIs");
00097
00098
00099
00100 __tt->ping_start(__ttc_objconv);
00101
00102 __obj_img = cvLoadImage( object_file, 1 );
00103 if ( ! __obj_img ) {
00104 throw Exception("Could not load object file");
00105 }
00106
00107 __tt->ping_end(__ttc_objconv);
00108
00109
00110
00111 __tt->ping_start(__ttc_objfeat);
00112
00113 __obj_num_features = 0;
00114 __obj_num_features = sift_features( __obj_img, &__obj_features );
00115 if ( ! __obj_num_features > 0 ) {
00116 throw Exception("Could not compute object features");
00117 }
00118 std::cout << "SiftClassifier(classify): computed '" << __obj_num_features << "' features from object" << std::endl;
00119
00120
00121 __tt->ping_end(__ttc_objfeat);
00122
00123
00124
00125 __image = cvCreateImage(cvSize(pixel_width, pixel_height), IPL_DEPTH_8U, 3);
00126
00127 }
00128
00129
00130
00131 SiftClassifier::~SiftClassifier()
00132 {
00133
00134 cvReleaseImage(&__obj_img);
00135 cvReleaseImage(&__image);
00136 }
00137
00138
00139 std::list< ROI > *
00140 SiftClassifier::classify()
00141 {
00142
00143 __tt->ping_start(0);
00144
00145
00146
00147 std::list< ROI > *rv = new std::list< ROI >();
00148
00149 struct feature * feat;
00150 struct feature** nbrs;
00151 struct kd_node* kd_root;
00152 CvPoint pt1, pt2;
00153
00154
00155 CvPoint ftpt;
00156 std::vector< CvPoint > ftlist;
00157
00158 int x_min = _width;
00159 int y_min = _height;
00160 int x_max = 0;
00161 int y_max = 0;
00162
00163 double d0, d1;
00164 int k, m = 0;
00165
00166
00167 __tt->ping_start(__ttc_imgconv);
00168
00169
00170 convert(YUV422_PLANAR, BGR, _src, (unsigned char *)__image->imageData, _width, _height);
00171
00172 __tt->ping_end(__ttc_imgconv);
00173
00174
00175
00176 __tt->ping_start(__ttc_imgfeat);
00177
00178
00179 int num_img_ft = sift_features( __image, &__img_features );
00180 kd_root = kdtree_build( __img_features, num_img_ft );
00181
00182 __tt->ping_end(__ttc_imgfeat);
00183
00184
00185 if( ! kd_root ) {
00186 std::cerr << "SiftClassifier(classify): KD-Root NULL!" << std::endl;
00187 }
00188
00189
00190 __tt->ping_start(__ttc_matchin);
00191
00192 std::cout << "SiftClassifier(classify): matching ..." << std::endl;
00193 for( int i = 0; i < __obj_num_features; ++i ) {
00194
00195 feat = __obj_features + i;
00196 k = kdtree_bbf_knn( kd_root, feat, 2, &nbrs, __kdtree_bbf_max_nn_chks );
00197 if( k == 2 )
00198 {
00199 d0 = descr_dist_sq( feat, nbrs[0] );
00200 d1 = descr_dist_sq( feat, nbrs[1] );
00201 if( d0 < d1 * __nn_sq_dist_ratio_thr )
00202 {
00203 pt1 = cvPoint( cvRound( feat->x ), cvRound( feat->y ) );
00204 pt2 = cvPoint( cvRound( nbrs[0]->x ), cvRound( nbrs[0]->y ) );
00205 m++;
00206 __obj_features[i].fwd_match = nbrs[0];
00207
00208 ftpt = cvPoint( cvRound( nbrs[0]->x), cvRound( nbrs[0]->y ) );
00209 ftlist.push_back(ftpt);
00210
00211 ROI r( pt2.x-5, pt2.y-5, 11, 11, _width, _height);
00212 rv->push_back(r);
00213 }
00214 }
00215 free( nbrs );
00216 }
00217 std::cout << "SiftClassifier(classify): found '" << m << "' matches" << std::endl;
00218 kdtree_release( kd_root );
00219
00220 __tt->ping_end(__ttc_matchin);
00221
00222
00223
00224 __tt->ping_start(__ttc_roimerg);
00225
00226 std::cout << "SiftClassifier(classify): computing ROI" << std::endl;
00227
00228 for ( std::vector< CvPoint >::size_type i = 0; i < ftlist.size(); ++i) {
00229 if( ftlist[i].x < x_min )
00230 x_min = ftlist[i].x;
00231 if( ftlist[i].y < y_min )
00232 y_min = ftlist[i].y;
00233 if( ftlist[i].x > x_max )
00234 x_max = ftlist[i].x;
00235 if( ftlist[i].y > y_max )
00236 y_max = ftlist[i].y;
00237 }
00238 if( m != 0 ) {
00239 ROI r(x_min, y_min, x_max-x_min, y_max-y_min, _width, _height);
00240 rv->push_back(r);
00241 }
00242
00243 __tt->ping_end(__ttc_roimerg);
00244
00245
00246
00247 __tt->ping_end(0);
00248
00249
00250
00251 __tt->print_to_stdout();
00252
00253
00254 std::cout << "SiftClassifier(classify): done ... returning '" << rv->size() << "' ROIs." << std::endl;
00255 return rv;
00256 }
00257
00258 }