00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include "outlet_pose_estimation/detail/features.h"
00011 #include "outlet_pose_estimation/detail/outlet_model.h"
00012 #include <highgui.h>
00013
00014 using namespace std;
00015
00016 void GetSURFFeatures(IplImage* src, vector<feature_t>& features)
00017 {
00018 CvMemStorage* storage = cvCreateMemStorage();
00019 CvSeq* surf_points = 0;
00020 cvExtractSURF(src, 0, &surf_points, 0, storage, cvSURFParams(512));
00021
00022 features.clear();
00023 for(int i = 0; i < surf_points->total; i++)
00024 {
00025 CvSURFPoint* point = (CvSURFPoint*)cvGetSeqElem(surf_points, i);
00026 CvPoint center = cvPoint(point->pt.x, point->pt.y);
00027 features.push_back(feature_t(center, (float)point->size));
00028 }
00029
00030 cvReleaseMemStorage(&storage);
00031 }
00032
00033 void GetStarFeatures(IplImage* src, vector<feature_t>& features)
00034 {
00035 CvMemStorage* storage = cvCreateMemStorage();
00036 CvSeq* star_points = cvGetStarKeypoints(src, storage, cvStarDetectorParams(45));
00037
00038 features.clear();
00039 for(int i = 0; i < star_points->total; i++)
00040 {
00041 CvStarKeypoint* keypoint = (CvStarKeypoint*)cvGetSeqElem(star_points, i);
00042 features.push_back(feature_t(keypoint->pt, (float)keypoint->size));
00043 }
00044
00045 cvReleaseMemStorage(&storage);
00046 }
00047
00048 void GetHarrisFeatures(IplImage* src, vector<feature_t>& features)
00049 {
00050 IplImage* grey = src;
00051 if(src->nChannels > 1)
00052 {
00053 grey = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1);
00054 cvCvtColor(src, grey, CV_RGB2GRAY);
00055 }
00056
00057
00058 IplImage* eig_img = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_32F, 1);
00059 IplImage* temp_img = cvCloneImage(eig_img);
00060
00061 int corner_count = 1024;
00062 CvPoint2D32f* corners = new CvPoint2D32f[corner_count];
00063 cvGoodFeaturesToTrack(grey, eig_img, temp_img, corners, &corner_count, .5, 0);
00064
00065 for(int i = 0; i < corner_count; i++)
00066 {
00067 features.push_back(feature_t(cvPoint(corners[i].x, corners[i].y), 1.0f));
00068 }
00069
00070 if(src->nChannels > 1)
00071 {
00072 cvReleaseImage(&grey);
00073 }
00074 cvReleaseImage(&eig_img);
00075 cvReleaseImage(&temp_img);
00076 }
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 void GetHoleFeatures(IplImage* src, vector<feature_t>& features, float hole_contrast)
00089 {
00090 vector<outlet_feature_t> outlet_features;
00091 find_outlet_features_fast(src, outlet_features, hole_contrast, 0, 0);
00092 for(size_t i = 0; i < outlet_features.size(); i++)
00093 {
00094 features.push_back(feature_t(feature_center(outlet_features[i]), outlet_features[i].bbox.width));
00095 }
00096 }
00097
00098 void DrawFeatures(IplImage* img, const vector<feature_t>& features)
00099 {
00100 for(size_t i = 0; i < features.size(); i++)
00101 {
00102 cvCircle(img, features[i].pt, features[i].size, CV_RGB(255, 0, 0), 2);
00103 }
00104 }
00105
00106 void FilterFeatures(vector<feature_t>& features, float min_scale, float max_scale)
00107 {
00108 vector<feature_t> selected;
00109 for(size_t i = 0; i < features.size(); i++)
00110 {
00111 if(features[i].size >= min_scale && features[i].size <= max_scale)
00112 {
00113 selected.push_back(features[i]);
00114 }
00115 }
00116
00117 features = selected;
00118 }
00119
00120 void SelectNeighborFeatures(vector<feature_t>& features, const vector<feature_t>& voc)
00121 {
00122 const int max_dist = 10;
00123 vector<feature_t> filtered;
00124 for(int i = 0; i < (int)features.size(); i++)
00125 {
00126 for(int j = 0; j < (int)voc.size(); j++)
00127 {
00128 if(length(features[i].pt - voc[j].pt) < max_dist)
00129 {
00130 filtered.push_back(features[i]);
00131 }
00132 }
00133 }
00134
00135 features = filtered;
00136 }
00137
00138 int CalcFeatures(IplImage* image, vector<vector<feature_t> >& features, vector<IplImage*>& images)
00139 {
00140 size_t pyr_levels = features.size();
00141 images.resize(pyr_levels);
00142 IplImage* image_features = cvCloneImage(image);
00143
00144 for(size_t i = 0; i < features.size(); i++)
00145 {
00146 images[i] = image_features;
00147 GetHoleFeatures(image_features, features[i]);
00148 IplImage* temp_image = cvCreateImage(cvSize(image_features->width/2, image_features->height/2), IPL_DEPTH_8U, 1);
00149 cvPyrDown(image_features, temp_image);
00150 image_features = temp_image;
00151 }
00152 cvReleaseImage(&image_features);
00153
00154 int feature_count = 0;
00155
00156 for(size_t i = 0; i < pyr_levels; i++)
00157 {
00158 feature_count += features[i].size();
00159 }
00160
00161 cvReleaseImage(&image);
00162
00163 return feature_count;
00164 }
00165
00166 static const float template_gamma = 2.0f;
00167 int LoadFeatures(const char* filename, vector<vector<feature_t> >& features, vector<IplImage*>& images)
00168 {
00169 IplImage* image = loadImageRed(filename);
00170 ApplyGamma(image, template_gamma);
00171
00172 int feature_count = CalcFeatures(image, features, images);
00173
00174 return feature_count;
00175 }
00176
00177 IplImage* loadImageRed(const char* filename)
00178 {
00179 IplImage* temp = cvLoadImage(filename);
00180 IplImage* red = cvCreateImage(cvSize(temp->width, temp->height), IPL_DEPTH_8U, 1);
00181 cvSetImageCOI(temp, 3);
00182 cvCopy(temp, red);
00183 cvReleaseImage(&temp);
00184
00185 #if defined(_SCALE_IMAGE_2)
00186 IplImage* red2 = cvCreateImage(cvSize(red->width/2, red->height/2), IPL_DEPTH_8U, 1);
00187 cvResize(red, red2);
00188 cvReleaseImage(&red);
00189 red = red2;
00190 #endif //_SCALE_IMAGE_2
00191
00192 return red;
00193 }
00194
00195 void ReleaseImageVector(vector<IplImage*>& images)
00196 {
00197 for(size_t i = 0; i < images.size(); i++)
00198 {
00199 cvReleaseImage(&images[i]);
00200 }
00201 }
00202
00203 void LoadTrainingFeatures(CvOneWayDescriptorObject& descriptors, const char* train_image_filename_object, const char* train_image_filename_background)
00204 {
00205 #if defined(_RED)
00206 IplImage* train_image_object = loadImageRed(train_image_filename_object);
00207 IplImage* train_image_background = loadImageRed(train_image_filename_background);
00208 #else
00209 IplImage* train_image_object = cvLoadImage(train_image_filename_object, CV_LOAD_IMAGE_GRAYSCALE);
00210 IplImage* train_image_background = cvLoadImage(train_image_filename_background, CV_LOAD_IMAGE_GRAYSCALE);
00211 #endif
00212
00213 #if 1
00214 ApplyGamma(train_image_object, template_gamma);
00215
00216 #endif
00217
00218 #if 0
00219 IplImage* train_image_object_up = cvCreateImage(cvSize(train_image_object->width, train_image_object->height), IPL_DEPTH_8U, train_image_object->nChannels);
00220 cvPyrUp(train_image_object, train_image_object_up);
00221 #endif
00222
00223 vector<vector<feature_t> > object_features;
00224 object_features.resize(descriptors.GetPyrLevels());
00225 vector<IplImage*> images;
00226 int object_feature_count = LoadFeatures(train_image_filename_object, object_features, images);
00227
00228 #if 0
00229 int max_object_features = 15;
00230 object_feature_count = 0;
00231 for (int i=0;i<(int)object_features.size();i++)
00232 {
00233 while ((int)object_features[i].size() > max_object_features)
00234 {
00235 object_features[i].pop_back();
00236 }
00237 object_feature_count+=(int)object_features[i].size();
00238 }
00239 #endif
00240
00241 vector<vector<feature_t> > background_features;
00242 vector<IplImage*> background_images;
00243 background_features.resize(1);
00244 int background_feature_count = LoadFeatures(train_image_filename_background, background_features, background_images);
00245
00246 #if 1
00247
00248 int max_background_features = 20;
00249 background_feature_count = 0;
00250 for (int i=0;i<(int)background_features.size();i++)
00251 {
00252 while ((int)background_features[i].size() > max_background_features)
00253 {
00254 background_features[i].pop_back();
00255 }
00256 background_feature_count+=(int)background_features[i].size();
00257 }
00258 #endif
00259
00260 int train_feature_count = object_feature_count + background_feature_count;
00261
00262
00263 descriptors.Allocate(train_feature_count, object_feature_count);
00264
00265 int descriptor_count = 0;
00266 for(int i = 0; i < descriptors.GetPyrLevels(); i++)
00267 {
00268 char feature_label[1024];
00269 sprintf(feature_label, "%s_%d", train_image_filename_object, i);
00270 IplImage* img = images[i];
00271 descriptors.InitializeObjectDescriptors(img, object_features[i], feature_label, descriptor_count, (float)(1<<i));
00272 descriptor_count += object_features[i].size();
00273 }
00274
00275 descriptors.InitializeObjectDescriptors(background_images[0], background_features[0],
00276 train_image_filename_background, object_feature_count, 1.0f, 1);
00277 #if defined(_KDTREE)
00278 descriptors.ConvertDescriptorsArrayToTree();
00279 #endif
00280 cvReleaseImage(&train_image_object);
00281 cvReleaseImage(&train_image_background);
00282
00283 ReleaseImageVector(images);
00284 ReleaseImageVector(background_images);
00285 }
00286
00287 void ScaleFeatures(const vector<feature_t>& src, vector<feature_t>& dst, float scale)
00288 {
00289 dst.resize(src.size());
00290 for(size_t i = 0; i < src.size(); i++)
00291 {
00292 dst[i] = feature_t(cvPoint(src[i].pt.x*scale, src[i].pt.y*scale), src[i].size, src[i].class_id);
00293 }
00294 }
00295
00296 void ApplyGamma(IplImage* img, float gamma)
00297 {
00298 IplImage* flt0 = cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1);
00299 IplImage* flt = cvCreateImage(cvGetSize(img), IPL_DEPTH_32F, 1);
00300 IplImage* u8 = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
00301
00302 for(int i = 1; i <= img->nChannels; i++)
00303 {
00304 cvSetImageCOI(img, i);
00305 cvCopy(img, u8);
00306 cvConvertScale(u8, flt0);
00307
00308
00309
00310 cvPow(flt0, flt, gamma);
00311 double maxval;
00312 cvMinMaxLoc(flt, 0, &maxval);
00313
00314 cvConvertScale(flt, u8, 255.0/maxval);
00315 cvCopy(u8, img);
00316 }
00317
00318 cvSetImageCOI(img, 0);
00319
00320 cvReleaseImage(&flt0);
00321 cvReleaseImage(&flt);
00322 cvReleaseImage(&u8);
00323 }
00324
00325 void FilterFeaturesOnEdges(const IplImage* img, const vector<feature_t>& src_features, vector<feature_t>& dst_features, int max_edge_dist, int min_contour_size)
00326 {
00327 printf("entered filterfeaturesonedges\n");
00328 IplImage* gray = cvCreateImage(cvGetSize(img), 8, 1);
00329 if (img->nChannels > 1)
00330 cvCvtColor(img,gray,CV_BGR2GRAY);
00331 else
00332 cvCopy(img,gray);
00333
00334 IplImage* edges = cvCreateImage( cvGetSize(img), 8, 1 );
00335 cvCanny( gray, edges, 100, 140, 3 );
00336
00337 #if 0
00338 cvNamedWindow("1", 1);
00339 cvShowImage("1", edges);
00340 cvWaitKey(0);
00341 #endif
00342
00343 CvMemStorage* storage = cvCreateMemStorage(0);
00344 CvSeq* contours;
00345 cvFindContours(edges,storage,&contours);
00346
00347
00348 CvMemStorage* storage1 = cvCreateMemStorage(0);
00349 CvSeq* contours_filt = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvSeq*), storage1);
00350
00351 int n = 0;
00352
00353 IplImage* edges1 = cvCreateImage( cvGetSize(img), 8, 1 );
00354 cvSet(edges1,cvScalar(0));
00355
00356 for(CvSeq* contour = contours; contour; contour = contour->h_next)
00357 {
00358 CvRect rect = cvBoundingRect(contour);
00359 if ((rect.width < min_contour_size) || (rect.height < min_contour_size) )
00360 {
00361 continue;
00362 }
00363
00364 CvSeq* poly = cvApproxPoly(contour, sizeof(CvContour), storage1, CV_POLY_APPROX_DP, 1.0);
00365 for(int i = 0; i < poly->total; i++)
00366 {
00367 CvPoint pt1 = *(CvPoint*)cvGetSeqElem(poly, i);
00368 CvPoint pt2 = *(CvPoint*)cvGetSeqElem(poly, i + 1);
00369
00370 const int min_segment_size = min_contour_size;
00371 if(abs(pt1.x - pt2.x) < min_segment_size || abs(pt1.y - pt2.y) < min_segment_size) continue;
00372 cvLine(edges1, pt1, pt2, cvScalar(255));
00373 }
00374
00375 }
00376
00377 for (int i=0;i<max_edge_dist;i++)
00378 {
00379 cvDilate(edges1,edges1);
00380 }
00381
00382 #if 0
00383 cvNamedWindow("1", 1);
00384 cvShowImage("1", edges1);
00385 cvWaitKey(0);
00386 #endif
00387
00388 dst_features.clear();
00389
00390 for (int i=0;i<(int)src_features.size();i++)
00391 {
00392 if (edges1->imageData[(int)src_features[i].pt.x+(int)src_features[i].pt.y*edges1->widthStep] == 0)
00393 {
00394 dst_features.push_back(src_features[i]);
00395 }
00396 }
00397
00398 cvReleaseMemStorage(&storage);
00399 cvReleaseMemStorage(&storage1);
00400 cvReleaseImage(&edges);
00401 cvReleaseImage(&edges1);
00402 cvReleaseImage(&gray);
00403 }
00404