Commit a702e5b2 authored by Ilya Lysenkov's avatar Ilya Lysenkov

Storing PCA components and One Way descriptors in one yml file.

parent 08c377cb
......@@ -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;
};
......
......@@ -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();
......
This diff is collapsed.
......@@ -15,20 +15,16 @@
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");
......@@ -39,18 +35,6 @@ int main(int argc, char** argv)
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,27 +42,16 @@ 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...");
printf("Training one way descriptors... \n");
// create descriptors
OneWayDescriptorBase descriptors(patch_size, pose_count, ".", pca_low_filename, pca_high_filename, pca_desc_filename);
OneWayDescriptorBase descriptors(patch_size, pose_count, OneWayDescriptorBase::GetPCAFilename(), path_name,
images_list);
descriptors.CreateDescriptorsFromImage(img1, keypoints1);
printf("done\n");
......@@ -87,12 +60,11 @@ int main(int argc, char** argv)
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;
......@@ -111,21 +83,23 @@ int main(int argc, char** argv)
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));
......@@ -134,137 +108,3 @@ IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1,
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);
}
one_way_train_0000.jpg
one_way_train_0001.jpg
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment