Storing PCA components and One Way descriptors in one yml file.
authorIlya Lysenkov <no@email>
Wed, 2 Jun 2010 05:19:09 +0000 (05:19 +0000)
committerIlya Lysenkov <no@email>
Wed, 2 Jun 2010 05:19:09 +0000 (05:19 +0000)
modules/features2d/include/opencv2/features2d/features2d.hpp
modules/features2d/src/descriptors.cpp
modules/features2d/src/oneway.cpp
samples/c/one_way_sample.cpp
samples/c/one_way_train_images.txt [new file with mode: 0644]

index 861712e..c54b5f6 100644 (file)
@@ -1024,6 +1024,12 @@ public:
                          const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
                          int pca_dim_high = 100, int pca_dim_low = 100);
 
+
+    OneWayDescriptorBase(CvSize patch_size, int pose_count, const string &pca_filename, const string &train_path = string(), const string &images_list = string(),
+                         int pyr_levels = 1,
+                         int pca_dim_high = 100, int pca_dim_low = 100);
+
+
     ~OneWayDescriptorBase();
 
     // Allocate: allocates memory for a given number of descriptors
@@ -1111,6 +1117,15 @@ public:
     // - filename: output filename
     void SavePCADescriptors(const char* filename);
 
+    // SavePCADescriptors: saves PCA descriptors to a file storage
+    // - fs: output file storage
+    void SavePCADescriptors(CvFileStorage* fs);
+
+    // GeneratePCA: calculate and save PCA components and descriptors
+    // - img_path: path to training PCA images directory
+    // - images_list: filename with filenames of training PCA images
+    void GeneratePCA(const char* img_path, const char* images_list);
+
     // SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
     void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
 
@@ -1129,6 +1144,8 @@ public:
 
     void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
 
+    // GetPCAFilename: get default PCA filename
+    static string GetPCAFilename () { return "pca.yml"; }
 
 protected:
     CvSize m_patch_size; // patch size
@@ -1151,7 +1168,6 @@ protected:
     int m_pca_dim_low;
 
     int m_pyr_levels;
-
 };
 
 class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase
@@ -1168,6 +1184,11 @@ public:
     OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path, const char* pca_config,
                            const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1);
 
+
+    OneWayDescriptorObject(CvSize patch_size, int pose_count, const string &pca_filename,
+                           const string &train_path = string (), const string &images_list = string (), int pyr_levels = 1);
+
+
     ~OneWayDescriptorObject();
 
     // Allocate: allocates memory for a given number of features
@@ -1690,19 +1711,20 @@ public:
 
         Params( int _poseCount = POSE_COUNT,
                 Size _patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT),
+                string _pcaFilename = string (),
                 string _trainPath = string(),
-                string _pcaConfig = string(), string _pcaHrConfig = string(),
-                string _pcaDescConfig = string(),
+                string _trainImagesList = string(),
                 float _minScale = GET_MIN_SCALE(), float _maxScale = GET_MAX_SCALE(),
                 float _stepScale = GET_STEP_SCALE() ) :
-        poseCount(_poseCount), patchSize(_patchSize), trainPath(_trainPath),
-        pcaConfig(_pcaConfig), pcaHrConfig(_pcaHrConfig), pcaDescConfig(_pcaDescConfig),
+        poseCount(_poseCount), patchSize(_patchSize), pcaFilename(_pcaFilename),
+        trainPath(_trainPath), trainImagesList(_trainImagesList),
         minScale(_minScale), maxScale(_maxScale), stepScale(_stepScale) {}
 
         int poseCount;
         Size patchSize;
+        string pcaFilename;
         string trainPath;
-        string pcaConfig, pcaHrConfig, pcaDescConfig;
+        string trainImagesList;
 
         float minScale, maxScale, stepScale;
     };
index 6e8e5b5..c723a45 100644 (file)
@@ -203,9 +203,8 @@ void OneWayDescriptorMatch::initialize( const Params& _params)
 void OneWayDescriptorMatch::add( const Mat& image, vector<KeyPoint>& keypoints )
 {
     if( base.empty() )
-        base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.trainPath.c_str(),
-                                           params.pcaConfig.c_str(), params.pcaHrConfig.c_str(),
-                                           params.pcaDescConfig.c_str());
+        base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename,
+                                           params.trainPath, params.trainImagesList);
 
     size_t trainFeatureCount = keypoints.size();
 
@@ -225,9 +224,8 @@ void OneWayDescriptorMatch::add( const Mat& image, vector<KeyPoint>& keypoints )
 void OneWayDescriptorMatch::add( KeyPointCollection& keypoints )
 {
     if( base.empty() )
-        base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.trainPath.c_str(),
-                                           params.pcaConfig.c_str(), params.pcaHrConfig.c_str(),
-                                           params.pcaDescConfig.c_str());
+        base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename,
+                                           params.trainPath, params.trainImagesList);
 
     size_t trainFeatureCount = keypoints.calcKeypointCount();
 
index eaf76ca..4987243 100644 (file)
@@ -139,7 +139,14 @@ namespace cv{
         }*/
     }
     
-    void readPCAFeatures(const char* filename, CvMat** avg, CvMat** eigenvectors);
+    void readPCAFeatures(const char* filename, CvMat** avg, CvMat** eigenvectors, const char *postfix = "");
+    void savePCAFeatures(FileStorage &fs, const char* postfix, CvMat* avg, CvMat* eigenvectors);
+    void calcPCAFeatures(vector<IplImage*>& patches, FileStorage &fs, const char* postfix, CvMat** avg,
+                         CvMat** eigenvectors);
+    void loadPCAFeatures(const char* path, const char* images_list, vector<IplImage*>& patches, CvSize patch_size);
+    void generatePCAFeatures(const char* path, const char* img_filename, FileStorage& fs, const char* postfix,
+                             CvSize patch_size, CvMat** avg, CvMat** eigenvectors);
+    
     void eigenvector2image(CvMat* eigenvector, IplImage* img);
 
     void FindOneWayDescriptor(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch, int& desc_idx, int& pose_idx, float& distance,
@@ -1261,7 +1268,49 @@ namespace cv{
         //    SavePCADescriptors("./pca_descriptors.yml");
         
     }
+
+    OneWayDescriptorBase::OneWayDescriptorBase(CvSize patch_size, int pose_count, const string &pca_filename,
+                                               const string &train_path, const string &images_list, int pyr_levels,
+                                               int pca_dim_high, int pca_dim_low) : m_pca_dim_high(pca_dim_high), m_pca_dim_low(pca_dim_low)
+    {
+        //  m_pca_descriptors_matrix = 0;
+        m_patch_size = patch_size;
+        m_pose_count = pose_count;
+        m_pyr_levels = pyr_levels;
+        m_poses = 0;
+        m_transforms = 0;
+
+        m_pca_avg = 0;
+        m_pca_eigenvectors = 0;
+        m_pca_hr_avg = 0;
+        m_pca_hr_eigenvectors = 0;
+        m_pca_descriptors = 0;
+
+        m_descriptors = 0;
+
+        CvFileStorage* fs = cvOpenFileStorage(pca_filename.c_str(), NULL, CV_STORAGE_READ);
+        if (fs != 0)
+        {
+            cvReleaseFileStorage(&fs);
+
+            readPCAFeatures(pca_filename.c_str(), &m_pca_avg, &m_pca_eigenvectors, "_lr");
+            readPCAFeatures(pca_filename.c_str(), &m_pca_hr_avg, &m_pca_hr_eigenvectors, "_hr");
+            m_pca_descriptors = new OneWayDescriptor[m_pca_dim_high + 1];
+#if !defined(_GH_REGIONS)
+            LoadPCADescriptors(pca_filename.c_str());
+#endif //_GH_REGIONS
+        }
+        else
+        {
+            GeneratePCA(train_path.c_str(), images_list.c_str());
+            m_pca_descriptors = new OneWayDescriptor[m_pca_dim_high + 1];
+            char pca_default_filename[1024];
+            sprintf(pca_default_filename, "%s/%s", train_path.c_str(), GetPCAFilename().c_str());
+            LoadPCADescriptors(pca_default_filename);
+        }
+    }
     
+
     OneWayDescriptorBase::~OneWayDescriptorBase()
     {
         cvReleaseMat(&m_pca_avg);
@@ -1554,20 +1603,170 @@ namespace cv{
         
         return 1;
     }
-    
+
+
+    void savePCAFeatures(FileStorage &fs, const char* postfix, CvMat* avg, CvMat* eigenvectors)
+    {
+        char buf[1024];
+        sprintf(buf, "avg_%s", postfix);
+        fs.writeObj(buf, avg);
+        sprintf(buf, "eigenvectors_%s", postfix);
+        fs.writeObj(buf, eigenvectors);
+    }
+
+    void calcPCAFeatures(vector<IplImage*>& patches, FileStorage &fs, const char* postfix, CvMat** avg,
+                         CvMat** eigenvectors)
+    {
+        int width = patches[0]->width;
+        int height = patches[0]->height;
+        int length = width * height;
+        int patch_count = (int)patches.size();
+
+        CvMat* data = cvCreateMat(patch_count, length, CV_32FC1);
+        *avg = cvCreateMat(1, length, CV_32FC1);
+        CvMat* eigenvalues = cvCreateMat(1, length, CV_32FC1);
+        *eigenvectors = cvCreateMat(length, length, CV_32FC1);
+
+        for (int i = 0; i < patch_count; i++)
+        {
+            float sum = cvSum(patches[i]).val[0];
+            for (int y = 0; y < height; y++)
+            {
+                for (int x = 0; x < width; x++)
+                {
+                    *((float*)(data->data.ptr + data->step * i) + y * width + x)
+                            = (float)(unsigned char)patches[i]->imageData[y * patches[i]->widthStep + x] / sum;
+                }
+            }
+        }
+
+        //printf("Calculating PCA...");
+        cvCalcPCA(data, *avg, eigenvalues, *eigenvectors, CV_PCA_DATA_AS_ROW);
+        //printf("done\n");
+
+        // save pca data
+        savePCAFeatures(fs, postfix, *avg, *eigenvectors);
+
+        cvReleaseMat(&data);
+        cvReleaseMat(&eigenvalues);
+    }
+
+    void loadPCAFeatures(const char* path, const char* images_list, vector<IplImage*>& patches, CvSize patch_size)
+    {
+        char images_filename[1024];
+        sprintf(images_filename, "%s/%s", path, images_list);
+        FILE *pFile = fopen(images_filename, "r");
+        if (pFile == 0)
+        {
+            printf("Cannot open images list file %s\n", images_filename);
+            return;
+        }
+        while (!feof(pFile))
+        {
+            char imagename[1024];
+            if (fscanf(pFile, "%s", imagename) <= 0)
+            {
+                break;
+            }
+
+            char filename[1024];
+            sprintf(filename, "%s/%s", path, imagename);
+
+            //printf("Reading image %s...", filename);
+            IplImage* img = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE);
+            //printf("done\n");
+
+            vector<KeyPoint> features;
+            SURF surf_extractor(1.0f);
+            //printf("Extracting SURF features...");
+            surf_extractor(img, Mat(), features);
+            //printf("done\n");
+
+            for (int j = 0; j < (int)features.size(); j++)
+            {
+                int patch_width = patch_size.width;
+                int patch_height = patch_size.height;
+
+                CvPoint center = features[j].pt;
+
+                CvRect roi = cvRect(center.x - patch_width / 2, center.y - patch_height / 2, patch_width, patch_height);
+                cvSetImageROI(img, roi);
+                roi = cvGetImageROI(img);
+                if (roi.width != patch_width || roi.height != patch_height)
+                {
+                    continue;
+                }
+
+                IplImage* patch = cvCreateImage(cvSize(patch_width, patch_height), IPL_DEPTH_8U, 1);
+                cvCopy(img, patch);
+                patches.push_back(patch);
+                cvResetImageROI(img);
+
+            }
+
+            //printf("Completed file, extracted %d features\n", (int)features.size());
+
+            cvReleaseImage(&img);
+        }
+        fclose(pFile);
+    }
+
+    void generatePCAFeatures(const char* path, const char* img_filename, FileStorage& fs, const char* postfix,
+                             CvSize patch_size, CvMat** avg, CvMat** eigenvectors)
+    {
+        vector<IplImage*> patches;
+        loadPCAFeatures(path, img_filename, patches, patch_size);
+        calcPCAFeatures(patches, fs, postfix, avg, eigenvectors);
+    }
+
+    void OneWayDescriptorBase::GeneratePCA(const char* img_path, const char* images_list)
+    {
+        char pca_filename[1024];
+        sprintf(pca_filename, "%s/%s", img_path, GetPCAFilename().c_str());
+        FileStorage fs = FileStorage(pca_filename, FileStorage::WRITE);
+
+        generatePCAFeatures(img_path, images_list, fs, "hr", m_patch_size, &m_pca_hr_avg, &m_pca_hr_eigenvectors);
+        generatePCAFeatures(img_path, images_list, fs, "lr", cvSize(m_patch_size.width / 2, m_patch_size.height / 2),
+                            &m_pca_avg, &m_pca_eigenvectors);
+
+        const int pose_count = 500;
+        OneWayDescriptorBase descriptors(m_patch_size, pose_count);
+        descriptors.SetPCAHigh(m_pca_hr_avg, m_pca_hr_eigenvectors);
+        descriptors.SetPCALow(m_pca_avg, m_pca_eigenvectors);
+
+        printf("Calculating %d PCA descriptors (you can grab a coffee, this will take a while)...\n",
+               descriptors.GetPCADimHigh());
+        descriptors.InitializePoseTransforms();
+        descriptors.CreatePCADescriptors();
+        descriptors.SavePCADescriptors(*fs);
+
+        fs.release();
+    }
+
     void OneWayDescriptorBase::SavePCADescriptors(const char* filename)
     {
         CvMemStorage* storage = cvCreateMemStorage();
         CvFileStorage* fs = cvOpenFileStorage(filename, storage, CV_STORAGE_WRITE);
-        
+
+       SavePCADescriptors (fs);        
+
+        cvReleaseMemStorage(&storage);
+        cvReleaseFileStorage(&fs);
+    }
+    
+    void OneWayDescriptorBase::SavePCADescriptors(CvFileStorage *fs)
+    {
         cvWriteInt(fs, "pca components number", m_pca_dim_high);
-        cvWriteComment(fs, "The first component is the average Vector, so the total number of components is <pca components number> + 1", 0);
+        cvWriteComment(
+                       fs,
+                       "The first component is the average Vector, so the total number of components is <pca components number> + 1",
+                       0);
         cvWriteInt(fs, "patch width", m_patch_size.width);
         cvWriteInt(fs, "patch height", m_patch_size.height);
-        
+
         // pack the affine transforms into a single CvMat and write them
         CvMat* poses = cvCreateMat(m_pose_count, 4, CV_32FC1);
-        for(int i = 0; i < m_pose_count; i++)
+        for (int i = 0; i < m_pose_count; i++)
         {
             cvmSet(poses, i, 0, m_poses[i].phi);
             cvmSet(poses, i, 1, m_poses[i].theta);
@@ -1576,18 +1775,16 @@ namespace cv{
         }
         cvWrite(fs, "affine poses", poses);
         cvReleaseMat(&poses);
-        
-        for(int i = 0; i < m_pca_dim_high + 1; i++)
+
+        for (int i = 0; i < m_pca_dim_high + 1; i++)
         {
             char buf[1024];
             sprintf(buf, "descriptor for pca component %d", i);
             m_pca_descriptors[i].Write(fs, buf);
         }
-        
-        cvReleaseMemStorage(&storage);
-        cvReleaseFileStorage(&fs);
     }
-    
+
+
     void OneWayDescriptorBase::Allocate(int train_feature_count)
     {
         m_train_feature_count = train_feature_count;
@@ -1728,6 +1925,14 @@ namespace cv{
         m_part_id = 0;
     }
     
+    OneWayDescriptorObject::OneWayDescriptorObject(CvSize patch_size, int pose_count, const string &pca_filename,
+                                                   const string &train_path, const string &images_list, int pyr_levels) :
+    OneWayDescriptorBase(patch_size, pose_count, pca_filename, train_path, images_list, pyr_levels)
+    {
+        m_part_id = 0;
+    }
+
+
     OneWayDescriptorObject::~OneWayDescriptorObject()
     {
         delete []m_part_id;
@@ -1771,24 +1976,27 @@ namespace cv{
         }
     }
     
-    void readPCAFeatures(const char* filename, CvMat** avg, CvMat** eigenvectors)
+    void readPCAFeatures(const char* filename, CvMat** avg, CvMat** eigenvectors, const char* postfix)
     {
         CvMemStorage* storage = cvCreateMemStorage();
         CvFileStorage* fs = cvOpenFileStorage(filename, storage, CV_STORAGE_READ);
-        if(!fs)
+        if (!fs)
         {
             printf("Cannot open file %s! Exiting!", filename);
             cvReleaseMemStorage(&storage);
         }
-        
-        CvFileNode* node = cvGetFileNodeByName(fs, 0, "avg");
+
+        char buf[1024];
+        sprintf(buf, "avg%s", postfix);
+        CvFileNode* node = cvGetFileNodeByName(fs, 0, buf);
         CvMat* _avg = (CvMat*)cvRead(fs, node);
-        node = cvGetFileNodeByName(fs, 0, "eigenvectors");
+        sprintf(buf, "eigenvectors%s", postfix);
+        node = cvGetFileNodeByName(fs, 0, buf);
         CvMat* _eigenvectors = (CvMat*)cvRead(fs, node);
-        
+
         *avg = cvCloneMat(_avg);
         *eigenvectors = cvCloneMat(_eigenvectors);
-        
+
         cvReleaseMat(&_avg);
         cvReleaseMat(&_eigenvectors);
         cvReleaseFileStorage(&fs);
index 010f05b..e962161 100644 (file)
 
 using namespace cv;
 
-IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1, 
-                              IplImage* img2, const vector<KeyPoint>& features2, const vector<int>& desc_idx);
-void generatePCADescriptors(const char* img_path, const char* pca_low_filename, const char* pca_high_filename, 
-                            const char* pca_desc_filename, CvSize patch_size);
+IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1, IplImage* img2,
+                              const vector<KeyPoint>& features2, const vector<int>& desc_idx);
 
 int main(int argc, char** argv)
-{    
-    const char pca_high_filename[] = "pca_hr.yml";
-    const char pca_low_filename[] = "pca_lr.yml";
-    const char pca_desc_filename[] = "pca_descriptors.yml";
+{
+    const char images_list[] = "one_way_train_images.txt";
     const CvSize patch_size = cvSize(24, 24);
     const int pose_count = 50;
-    
-    if(argc != 3 && argc != 4)
+
+    if (argc != 3 && argc != 4)
     {
         printf("Format: \n./one_way_sample [path_to_samples] [image1] [image2]\n");
         printf("For example: ./one_way_sample ../../../opencv/samples/c scene_l.bmp scene_r.bmp\n");
         return 0;
     }
-    
+
     std::string path_name = argv[1];
     std::string img1_name = path_name + "/" + std::string(argv[2]);
     std::string img2_name = path_name + "/" + std::string(argv[3]);
 
-    CvFileStorage* fs = cvOpenFileStorage("pca_hr.yml", NULL, CV_STORAGE_READ);
-    if(fs == NULL)
-    {
-        printf("PCA data is not found, starting training...\n");
-        generatePCADescriptors(path_name.c_str(), pca_low_filename, pca_high_filename, pca_desc_filename, patch_size);
-    }
-    else
-    {
-        cvReleaseFileStorage(&fs);
-    }
-    
-    
     printf("Reading the images...\n");
     IplImage* img1 = cvLoadImage(img1_name.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
     IplImage* img2 = cvLoadImage(img2_name.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
@@ -58,213 +42,69 @@ int main(int argc, char** argv)
     // extract keypoints from the first image
     SURF surf_extractor(5.0e3);
     vector<KeyPoint> keypoints1;
-#if 1
-    Mat _img1(img1);
-    vector<Point2f> corners;
-    
-    goodFeaturesToTrack(_img1, corners, 200, 0.01, 20);
-    for(size_t i = 0; i < corners.size(); i++)
-    {
-        KeyPoint p;
-        p.pt = corners[i];
-        keypoints1.push_back(p);
-    }
-#else
-//    printf("Extracting keypoints\n");
+
+    // printf("Extracting keypoints\n");
     surf_extractor(img1, Mat(), keypoints1);
-#endif
     
     printf("Extracted %d keypoints...\n", (int)keypoints1.size());
 
-    printf("Training one way descriptors...");
-    // create descriptors 
-    OneWayDescriptorBase descriptors(patch_size, pose_count, ".", pca_low_filename, pca_high_filename, pca_desc_filename);
+    printf("Training one way descriptors... \n");
+    // create descriptors
+    OneWayDescriptorBase descriptors(patch_size, pose_count, OneWayDescriptorBase::GetPCAFilename(), path_name,
+                                     images_list);
     descriptors.CreateDescriptorsFromImage(img1, keypoints1);
     printf("done\n");
-    
+
     // extract keypoints from the second image
     vector<KeyPoint> keypoints2;
     surf_extractor(img2, Mat(), keypoints2);
     printf("Extracted %d keypoints from the second image...\n", (int)keypoints2.size());
 
-    
     printf("Finding nearest neighbors...");
     // find NN for each of keypoints2 in keypoints1
     vector<int> desc_idx;
     desc_idx.resize(keypoints2.size());
-    for(size_t i = 0; i < keypoints2.size(); i++)
+    for (size_t i = 0; i < keypoints2.size(); i++)
     {
         int pose_idx = 0;
         float distance = 0;
         descriptors.FindDescriptor(img2, keypoints2[i].pt, desc_idx[i], pose_idx, distance);
     }
     printf("done\n");
-    
+
     IplImage* img_corr = DrawCorrespondences(img1, keypoints1, img2, keypoints2, desc_idx);
-    
+
     cvNamedWindow("correspondences", 1);
     cvShowImage("correspondences", img_corr);
     cvWaitKey(0);
-    
+
     cvReleaseImage(&img1);
     cvReleaseImage(&img2);
     cvReleaseImage(&img_corr);
 }
 
-IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1, IplImage* img2, const vector<KeyPoint>& features2, const vector<int>& desc_idx)
+IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1, IplImage* img2,
+                              const vector<KeyPoint>& features2, const vector<int>& desc_idx)
 {
-    IplImage* img_corr = cvCreateImage(cvSize(img1->width + img2->width, MAX(img1->height, img2->height)), IPL_DEPTH_8U, 3);
+    IplImage* img_corr = cvCreateImage(cvSize(img1->width + img2->width, MAX(img1->height, img2->height)),
+                                       IPL_DEPTH_8U, 3);
     cvSetImageROI(img_corr, cvRect(0, 0, img1->width, img1->height));
     cvCvtColor(img1, img_corr, CV_GRAY2RGB);
     cvSetImageROI(img_corr, cvRect(img1->width, 0, img2->width, img2->height));
     cvCvtColor(img2, img_corr, CV_GRAY2RGB);
     cvResetImageROI(img_corr);
-    
-    for(size_t i = 0; i < features1.size(); i++)
+
+    for (size_t i = 0; i < features1.size(); i++)
     {
         cvCircle(img_corr, features1[i].pt, 3, CV_RGB(255, 0, 0));
     }
-    
-    for(size_t i = 0; i < features2.size(); i++)
+
+    for (size_t i = 0; i < features2.size(); i++)
     {
         CvPoint pt = cvPoint(features2[i].pt.x + img1->width, features2[i].pt.y);
         cvCircle(img_corr, pt, 3, CV_RGB(255, 0, 0));
         cvLine(img_corr, features1[desc_idx[i]].pt, pt, CV_RGB(0, 255, 0));
     }
-    
-    return img_corr;
-}
-
-/*
- *  pca_features
- * 
- *
- */
-
-void savePCAFeatures(const char* filename, CvMat* avg, CvMat* eigenvectors)
-{
-    CvMemStorage* storage = cvCreateMemStorage();
-    
-    CvFileStorage* fs = cvOpenFileStorage(filename, storage, CV_STORAGE_WRITE);
-    cvWrite(fs, "avg", avg);
-    cvWrite(fs, "eigenvectors", eigenvectors);
-    cvReleaseFileStorage(&fs);   
-    
-    cvReleaseMemStorage(&storage);
-}
-
-void calcPCAFeatures(vector<IplImage*>& patches, const char* filename, CvMat** avg, CvMat** eigenvectors)
-{
-    int width = patches[0]->width;
-    int height = patches[0]->height;
-    int length = width*height;
-    int patch_count = (int)patches.size();
-    
-    CvMat* data = cvCreateMat(patch_count, length, CV_32FC1);
-    *avg = cvCreateMat(1, length, CV_32FC1);
-    CvMat* eigenvalues = cvCreateMat(1, length, CV_32FC1);
-    *eigenvectors = cvCreateMat(length, length, CV_32FC1);
-    
-    for(int i = 0; i < patch_count; i++)
-    {
-        float sum = cvSum(patches[i]).val[0];
-        for(int y = 0; y < height; y++)
-        {
-            for(int x = 0; x < width; x++)
-            {
-                *((float*)(data->data.ptr + data->step*i) + y*width + x) = (float)(unsigned char)patches[i]->imageData[y*patches[i]->widthStep + x]/sum;
-            }
-        }
-    }
-    
-    printf("Calculating PCA...");
-    cvCalcPCA(data, *avg, eigenvalues, *eigenvectors, CV_PCA_DATA_AS_ROW);
-    printf("done\n");
-    
-    // save pca data
-    savePCAFeatures(filename, *avg, *eigenvectors);
-    
-    cvReleaseMat(&data);
-    cvReleaseMat(&eigenvalues);
-}
-
-
-void loadPCAFeatures(const char* path, vector<IplImage*>& patches, CvSize patch_size)
-{
-    const int file_count = 2;
-    for(int i = 0; i < file_count; i++)
-    {
-        char buf[1024];
-        sprintf(buf, "%s/one_way_train_%04d.jpg", path, i);
-        printf("Reading image %s...", buf);
-        IplImage* img = cvLoadImage(buf, CV_LOAD_IMAGE_GRAYSCALE);
-        printf("done\n");
-        
-        vector<KeyPoint> features;
-        SURF surf_extractor(1.0f);
-        printf("Extracting SURF features...");
-        surf_extractor(img, Mat(), features);
-        printf("done\n");
-        
-        for(int j = 0; j < (int)features.size(); j++)
-        {
-            int patch_width = patch_size.width;
-            int patch_height = patch_size.height;
-            
-            CvPoint center = features[j].pt;
-            
-            CvRect roi = cvRect(center.x - patch_width/2, center.y - patch_height/2, patch_width, patch_height);
-            cvSetImageROI(img, roi);
-            roi = cvGetImageROI(img);
-            if(roi.width != patch_width || roi.height != patch_height)
-            {
-                continue;
-            }
-            
-            IplImage* patch = cvCreateImage(cvSize(patch_width, patch_height), IPL_DEPTH_8U, 1);
-            cvCopy(img, patch);
-            patches.push_back(patch);
-            cvResetImageROI(img);
-            
-        }
-        
-        printf("Completed file %d, extracted %d features\n", i, (int)features.size());
-        
-        cvReleaseImage(&img);
-    }
-}
-
-void generatePCAFeatures(const char* img_filename, const char* pca_filename, CvSize patch_size, CvMat** avg, CvMat** eigenvectors)
-{
-    vector<IplImage*> patches;
-    loadPCAFeatures(img_filename, patches, patch_size);
-    calcPCAFeatures(patches, pca_filename, avg, eigenvectors);
-}
-
-void generatePCADescriptors(const char* img_path, const char* pca_low_filename, const char* pca_high_filename, 
-                            const char* pca_desc_filename, CvSize patch_size)
-{
-    CvMat* avg_hr;
-    CvMat* eigenvectors_hr;
-    generatePCAFeatures(img_path, pca_high_filename, patch_size, &avg_hr, &eigenvectors_hr);
 
-    CvMat* avg_lr;
-    CvMat* eigenvectors_lr;
-    generatePCAFeatures(img_path, pca_low_filename, cvSize(patch_size.width/2, patch_size.height/2), 
-        &avg_lr, &eigenvectors_lr);
-    
-    const int pose_count = 500;
-    OneWayDescriptorBase descriptors(patch_size, pose_count);
-    descriptors.SetPCAHigh(avg_hr, eigenvectors_hr);
-    descriptors.SetPCALow(avg_lr, eigenvectors_lr);
-    
-    printf("Calculating %d PCA descriptors (you can grab a coffee, this will take a while)...\n", descriptors.GetPCADimHigh());
-    descriptors.InitializePoseTransforms();
-    descriptors.CreatePCADescriptors();
-    descriptors.SavePCADescriptors(pca_desc_filename);
-    
-    cvReleaseMat(&avg_hr);
-    cvReleaseMat(&eigenvectors_hr);
-    cvReleaseMat(&avg_lr);
-    cvReleaseMat(&eigenvectors_lr);
+    return img_corr;
 }
diff --git a/samples/c/one_way_train_images.txt b/samples/c/one_way_train_images.txt
new file mode 100644 (file)
index 0000000..eefa571
--- /dev/null
@@ -0,0 +1,2 @@
+one_way_train_0000.jpg
+one_way_train_0001.jpg