diff --git a/modules/features2d/include/opencv2/features2d/features2d.hpp b/modules/features2d/include/opencv2/features2d/features2d.hpp index 861712e47e..c54b5f6723 100644 --- a/modules/features2d/include/opencv2/features2d/features2d.hpp +++ b/modules/features2d/include/opencv2/features2d/features2d.hpp @@ -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; }; diff --git a/modules/features2d/src/descriptors.cpp b/modules/features2d/src/descriptors.cpp index 6e8e5b568c..c723a450eb 100644 --- a/modules/features2d/src/descriptors.cpp +++ b/modules/features2d/src/descriptors.cpp @@ -203,9 +203,8 @@ void OneWayDescriptorMatch::initialize( const Params& _params) void OneWayDescriptorMatch::add( const Mat& image, vector& 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& 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(); diff --git a/modules/features2d/src/oneway.cpp b/modules/features2d/src/oneway.cpp index eaf76ca7cc..4987243974 100644 --- a/modules/features2d/src/oneway.cpp +++ b/modules/features2d/src/oneway.cpp @@ -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& patches, FileStorage &fs, const char* postfix, CvMat** avg, + CvMat** eigenvectors); + void loadPCAFeatures(const char* path, const char* images_list, vector& 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& 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& 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 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 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 + 1", 0); + cvWriteComment( + fs, + "The first component is the average Vector, so the total number of components is + 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); diff --git a/samples/c/one_way_sample.cpp b/samples/c/one_way_sample.cpp index 010f05bb8c..e962161a7e 100644 --- a/samples/c/one_way_sample.cpp +++ b/samples/c/one_way_sample.cpp @@ -15,42 +15,26 @@ using namespace cv; -IplImage* DrawCorrespondences(IplImage* img1, const vector& features1, - IplImage* img2, const vector& features2, const vector& 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& features1, IplImage* img2, + const vector& features2, const vector& 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 keypoints1; -#if 1 - Mat _img1(img1); - vector 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 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 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& features1, IplImage* img2, const vector& features2, const vector& desc_idx) +IplImage* DrawCorrespondences(IplImage* img1, const vector& features1, IplImage* img2, + const vector& features2, const vector& 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& 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& 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 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 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 index 0000000000..eefa571d53 --- /dev/null +++ b/samples/c/one_way_train_images.txt @@ -0,0 +1,2 @@ +one_way_train_0000.jpg +one_way_train_0001.jpg