features.cpp
Go to the documentation of this file.
00001 /*
00002  *  features.cpp
00003  *  online_patch
00004  *
00005  *  Created by Victor  Eruhimov on 4/23/09.
00006  *  Copyright 2009 Argus Corp. All rights reserved.
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);//, 0, 3, 1);
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 /*void GetHoleFeatures(IplImage* src, vector<feature_t>& features, float hole_contrast)
00079 {
00080     vector<outlet_feature_t> outlet_features;
00081     find_outlet_features_fast(src, outlet_features, hole_contrast, 0, 0);
00082     for(size_t i = 0; i < outlet_features.size(); i++)
00083     {
00084         features.push_back(feature_t(feature_center(outlet_features[i]), outlet_features[i].bbox.width));
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;//1.2f;
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 //    ApplyGamma(train_image_background);
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         //printf("Background features count: %d\n",background_feature_count);
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 //    printf("Found %d train points...\n", train_feature_count);
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 //        cvMul(flt0, flt0, flt);
00309 //        cvMul(flt, flt0, flt);
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 //        cvDrawContours(edges1, contour, cvScalar(255), cvScalar(255), 0, 1);
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 


outlet_pose_estimation
Author(s): Patrick Mihelich
autogenerated on Thu Nov 28 2013 11:46:23