Storing PCA components and One Way descriptors in one yml file.
This commit is contained in:
parent
08c377cb48
commit
a702e5b2dc
@ -1024,6 +1024,12 @@ public:
|
|||||||
const char* pca_hr_config = 0, const char* pca_desc_config = 0, int pyr_levels = 1,
|
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);
|
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();
|
~OneWayDescriptorBase();
|
||||||
|
|
||||||
// Allocate: allocates memory for a given number of descriptors
|
// Allocate: allocates memory for a given number of descriptors
|
||||||
@ -1111,6 +1117,15 @@ public:
|
|||||||
// - filename: output filename
|
// - filename: output filename
|
||||||
void SavePCADescriptors(const char* 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)
|
// SetPCAHigh: sets the high resolution pca matrices (copied to internal structures)
|
||||||
void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
|
void SetPCAHigh(CvMat* avg, CvMat* eigenvectors);
|
||||||
|
|
||||||
@ -1129,6 +1144,8 @@ public:
|
|||||||
|
|
||||||
void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
|
void ConvertDescriptorsArrayToTree(); // Converting pca_descriptors array to KD tree
|
||||||
|
|
||||||
|
// GetPCAFilename: get default PCA filename
|
||||||
|
static string GetPCAFilename () { return "pca.yml"; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
CvSize m_patch_size; // patch size
|
CvSize m_patch_size; // patch size
|
||||||
@ -1151,7 +1168,6 @@ protected:
|
|||||||
int m_pca_dim_low;
|
int m_pca_dim_low;
|
||||||
|
|
||||||
int m_pyr_levels;
|
int m_pyr_levels;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class CV_EXPORTS OneWayDescriptorObject : public OneWayDescriptorBase
|
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,
|
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);
|
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();
|
~OneWayDescriptorObject();
|
||||||
|
|
||||||
// Allocate: allocates memory for a given number of features
|
// Allocate: allocates memory for a given number of features
|
||||||
@ -1690,19 +1711,20 @@ public:
|
|||||||
|
|
||||||
Params( int _poseCount = POSE_COUNT,
|
Params( int _poseCount = POSE_COUNT,
|
||||||
Size _patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT),
|
Size _patchSize = Size(PATCH_WIDTH, PATCH_HEIGHT),
|
||||||
|
string _pcaFilename = string (),
|
||||||
string _trainPath = string(),
|
string _trainPath = string(),
|
||||||
string _pcaConfig = string(), string _pcaHrConfig = string(),
|
string _trainImagesList = string(),
|
||||||
string _pcaDescConfig = string(),
|
|
||||||
float _minScale = GET_MIN_SCALE(), float _maxScale = GET_MAX_SCALE(),
|
float _minScale = GET_MIN_SCALE(), float _maxScale = GET_MAX_SCALE(),
|
||||||
float _stepScale = GET_STEP_SCALE() ) :
|
float _stepScale = GET_STEP_SCALE() ) :
|
||||||
poseCount(_poseCount), patchSize(_patchSize), trainPath(_trainPath),
|
poseCount(_poseCount), patchSize(_patchSize), pcaFilename(_pcaFilename),
|
||||||
pcaConfig(_pcaConfig), pcaHrConfig(_pcaHrConfig), pcaDescConfig(_pcaDescConfig),
|
trainPath(_trainPath), trainImagesList(_trainImagesList),
|
||||||
minScale(_minScale), maxScale(_maxScale), stepScale(_stepScale) {}
|
minScale(_minScale), maxScale(_maxScale), stepScale(_stepScale) {}
|
||||||
|
|
||||||
int poseCount;
|
int poseCount;
|
||||||
Size patchSize;
|
Size patchSize;
|
||||||
|
string pcaFilename;
|
||||||
string trainPath;
|
string trainPath;
|
||||||
string pcaConfig, pcaHrConfig, pcaDescConfig;
|
string trainImagesList;
|
||||||
|
|
||||||
float minScale, maxScale, stepScale;
|
float minScale, maxScale, stepScale;
|
||||||
};
|
};
|
||||||
|
@ -203,9 +203,8 @@ void OneWayDescriptorMatch::initialize( const Params& _params)
|
|||||||
void OneWayDescriptorMatch::add( const Mat& image, vector<KeyPoint>& keypoints )
|
void OneWayDescriptorMatch::add( const Mat& image, vector<KeyPoint>& keypoints )
|
||||||
{
|
{
|
||||||
if( base.empty() )
|
if( base.empty() )
|
||||||
base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.trainPath.c_str(),
|
base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename,
|
||||||
params.pcaConfig.c_str(), params.pcaHrConfig.c_str(),
|
params.trainPath, params.trainImagesList);
|
||||||
params.pcaDescConfig.c_str());
|
|
||||||
|
|
||||||
size_t trainFeatureCount = keypoints.size();
|
size_t trainFeatureCount = keypoints.size();
|
||||||
|
|
||||||
@ -225,9 +224,8 @@ void OneWayDescriptorMatch::add( const Mat& image, vector<KeyPoint>& keypoints )
|
|||||||
void OneWayDescriptorMatch::add( KeyPointCollection& keypoints )
|
void OneWayDescriptorMatch::add( KeyPointCollection& keypoints )
|
||||||
{
|
{
|
||||||
if( base.empty() )
|
if( base.empty() )
|
||||||
base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.trainPath.c_str(),
|
base = new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename,
|
||||||
params.pcaConfig.c_str(), params.pcaHrConfig.c_str(),
|
params.trainPath, params.trainImagesList);
|
||||||
params.pcaDescConfig.c_str());
|
|
||||||
|
|
||||||
size_t trainFeatureCount = keypoints.calcKeypointCount();
|
size_t trainFeatureCount = keypoints.calcKeypointCount();
|
||||||
|
|
||||||
|
@ -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 eigenvector2image(CvMat* eigenvector, IplImage* img);
|
||||||
|
|
||||||
void FindOneWayDescriptor(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch, int& desc_idx, int& pose_idx, float& distance,
|
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");
|
// 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()
|
OneWayDescriptorBase::~OneWayDescriptorBase()
|
||||||
{
|
{
|
||||||
cvReleaseMat(&m_pca_avg);
|
cvReleaseMat(&m_pca_avg);
|
||||||
@ -1554,20 +1603,170 @@ namespace cv{
|
|||||||
|
|
||||||
return 1;
|
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)
|
void OneWayDescriptorBase::SavePCADescriptors(const char* filename)
|
||||||
{
|
{
|
||||||
CvMemStorage* storage = cvCreateMemStorage();
|
CvMemStorage* storage = cvCreateMemStorage();
|
||||||
CvFileStorage* fs = cvOpenFileStorage(filename, storage, CV_STORAGE_WRITE);
|
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);
|
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 width", m_patch_size.width);
|
||||||
cvWriteInt(fs, "patch height", m_patch_size.height);
|
cvWriteInt(fs, "patch height", m_patch_size.height);
|
||||||
|
|
||||||
// pack the affine transforms into a single CvMat and write them
|
// pack the affine transforms into a single CvMat and write them
|
||||||
CvMat* poses = cvCreateMat(m_pose_count, 4, CV_32FC1);
|
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, 0, m_poses[i].phi);
|
||||||
cvmSet(poses, i, 1, m_poses[i].theta);
|
cvmSet(poses, i, 1, m_poses[i].theta);
|
||||||
@ -1576,18 +1775,16 @@ namespace cv{
|
|||||||
}
|
}
|
||||||
cvWrite(fs, "affine poses", poses);
|
cvWrite(fs, "affine poses", poses);
|
||||||
cvReleaseMat(&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];
|
char buf[1024];
|
||||||
sprintf(buf, "descriptor for pca component %d", i);
|
sprintf(buf, "descriptor for pca component %d", i);
|
||||||
m_pca_descriptors[i].Write(fs, buf);
|
m_pca_descriptors[i].Write(fs, buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
cvReleaseMemStorage(&storage);
|
|
||||||
cvReleaseFileStorage(&fs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void OneWayDescriptorBase::Allocate(int train_feature_count)
|
void OneWayDescriptorBase::Allocate(int train_feature_count)
|
||||||
{
|
{
|
||||||
m_train_feature_count = train_feature_count;
|
m_train_feature_count = train_feature_count;
|
||||||
@ -1728,6 +1925,14 @@ namespace cv{
|
|||||||
m_part_id = 0;
|
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()
|
OneWayDescriptorObject::~OneWayDescriptorObject()
|
||||||
{
|
{
|
||||||
delete []m_part_id;
|
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();
|
CvMemStorage* storage = cvCreateMemStorage();
|
||||||
CvFileStorage* fs = cvOpenFileStorage(filename, storage, CV_STORAGE_READ);
|
CvFileStorage* fs = cvOpenFileStorage(filename, storage, CV_STORAGE_READ);
|
||||||
if(!fs)
|
if (!fs)
|
||||||
{
|
{
|
||||||
printf("Cannot open file %s! Exiting!", filename);
|
printf("Cannot open file %s! Exiting!", filename);
|
||||||
cvReleaseMemStorage(&storage);
|
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);
|
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);
|
CvMat* _eigenvectors = (CvMat*)cvRead(fs, node);
|
||||||
|
|
||||||
*avg = cvCloneMat(_avg);
|
*avg = cvCloneMat(_avg);
|
||||||
*eigenvectors = cvCloneMat(_eigenvectors);
|
*eigenvectors = cvCloneMat(_eigenvectors);
|
||||||
|
|
||||||
cvReleaseMat(&_avg);
|
cvReleaseMat(&_avg);
|
||||||
cvReleaseMat(&_eigenvectors);
|
cvReleaseMat(&_eigenvectors);
|
||||||
cvReleaseFileStorage(&fs);
|
cvReleaseFileStorage(&fs);
|
||||||
|
@ -15,42 +15,26 @@
|
|||||||
|
|
||||||
using namespace cv;
|
using namespace cv;
|
||||||
|
|
||||||
IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1,
|
IplImage* DrawCorrespondences(IplImage* img1, const vector<KeyPoint>& features1, IplImage* img2,
|
||||||
IplImage* img2, const vector<KeyPoint>& features2, const vector<int>& desc_idx);
|
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);
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
const char pca_high_filename[] = "pca_hr.yml";
|
const char images_list[] = "one_way_train_images.txt";
|
||||||
const char pca_low_filename[] = "pca_lr.yml";
|
|
||||||
const char pca_desc_filename[] = "pca_descriptors.yml";
|
|
||||||
const CvSize patch_size = cvSize(24, 24);
|
const CvSize patch_size = cvSize(24, 24);
|
||||||
const int pose_count = 50;
|
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("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");
|
printf("For example: ./one_way_sample ../../../opencv/samples/c scene_l.bmp scene_r.bmp\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string path_name = argv[1];
|
std::string path_name = argv[1];
|
||||||
std::string img1_name = path_name + "/" + std::string(argv[2]);
|
std::string img1_name = path_name + "/" + std::string(argv[2]);
|
||||||
std::string img2_name = path_name + "/" + std::string(argv[3]);
|
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");
|
printf("Reading the images...\n");
|
||||||
IplImage* img1 = cvLoadImage(img1_name.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
|
IplImage* img1 = cvLoadImage(img1_name.c_str(), CV_LOAD_IMAGE_GRAYSCALE);
|
||||||
IplImage* img2 = cvLoadImage(img2_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
|
// extract keypoints from the first image
|
||||||
SURF surf_extractor(5.0e3);
|
SURF surf_extractor(5.0e3);
|
||||||
vector<KeyPoint> keypoints1;
|
vector<KeyPoint> keypoints1;
|
||||||
#if 1
|
|
||||||
Mat _img1(img1);
|
// printf("Extracting keypoints\n");
|
||||||
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");
|
|
||||||
surf_extractor(img1, Mat(), keypoints1);
|
surf_extractor(img1, Mat(), keypoints1);
|
||||||
#endif
|
|
||||||
|
|
||||||
printf("Extracted %d keypoints...\n", (int)keypoints1.size());
|
printf("Extracted %d keypoints...\n", (int)keypoints1.size());
|
||||||
|
|
||||||
printf("Training one way descriptors...");
|
printf("Training one way descriptors... \n");
|
||||||
// create descriptors
|
// 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);
|
descriptors.CreateDescriptorsFromImage(img1, keypoints1);
|
||||||
printf("done\n");
|
printf("done\n");
|
||||||
|
|
||||||
// extract keypoints from the second image
|
// extract keypoints from the second image
|
||||||
vector<KeyPoint> keypoints2;
|
vector<KeyPoint> keypoints2;
|
||||||
surf_extractor(img2, Mat(), keypoints2);
|
surf_extractor(img2, Mat(), keypoints2);
|
||||||
printf("Extracted %d keypoints from the second image...\n", (int)keypoints2.size());
|
printf("Extracted %d keypoints from the second image...\n", (int)keypoints2.size());
|
||||||
|
|
||||||
|
|
||||||
printf("Finding nearest neighbors...");
|
printf("Finding nearest neighbors...");
|
||||||
// find NN for each of keypoints2 in keypoints1
|
// find NN for each of keypoints2 in keypoints1
|
||||||
vector<int> desc_idx;
|
vector<int> desc_idx;
|
||||||
desc_idx.resize(keypoints2.size());
|
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;
|
int pose_idx = 0;
|
||||||
float distance = 0;
|
float distance = 0;
|
||||||
descriptors.FindDescriptor(img2, keypoints2[i].pt, desc_idx[i], pose_idx, distance);
|
descriptors.FindDescriptor(img2, keypoints2[i].pt, desc_idx[i], pose_idx, distance);
|
||||||
}
|
}
|
||||||
printf("done\n");
|
printf("done\n");
|
||||||
|
|
||||||
IplImage* img_corr = DrawCorrespondences(img1, keypoints1, img2, keypoints2, desc_idx);
|
IplImage* img_corr = DrawCorrespondences(img1, keypoints1, img2, keypoints2, desc_idx);
|
||||||
|
|
||||||
cvNamedWindow("correspondences", 1);
|
cvNamedWindow("correspondences", 1);
|
||||||
cvShowImage("correspondences", img_corr);
|
cvShowImage("correspondences", img_corr);
|
||||||
cvWaitKey(0);
|
cvWaitKey(0);
|
||||||
|
|
||||||
cvReleaseImage(&img1);
|
cvReleaseImage(&img1);
|
||||||
cvReleaseImage(&img2);
|
cvReleaseImage(&img2);
|
||||||
cvReleaseImage(&img_corr);
|
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));
|
cvSetImageROI(img_corr, cvRect(0, 0, img1->width, img1->height));
|
||||||
cvCvtColor(img1, img_corr, CV_GRAY2RGB);
|
cvCvtColor(img1, img_corr, CV_GRAY2RGB);
|
||||||
cvSetImageROI(img_corr, cvRect(img1->width, 0, img2->width, img2->height));
|
cvSetImageROI(img_corr, cvRect(img1->width, 0, img2->width, img2->height));
|
||||||
cvCvtColor(img2, img_corr, CV_GRAY2RGB);
|
cvCvtColor(img2, img_corr, CV_GRAY2RGB);
|
||||||
cvResetImageROI(img_corr);
|
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));
|
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);
|
CvPoint pt = cvPoint(features2[i].pt.x + img1->width, features2[i].pt.y);
|
||||||
cvCircle(img_corr, pt, 3, CV_RGB(255, 0, 0));
|
cvCircle(img_corr, pt, 3, CV_RGB(255, 0, 0));
|
||||||
cvLine(img_corr, features1[desc_idx[i]].pt, pt, CV_RGB(0, 255, 0));
|
cvLine(img_corr, features1[desc_idx[i]].pt, pt, CV_RGB(0, 255, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
return img_corr;
|
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);
|
|
||||||
}
|
|
||||||
|
2
samples/c/one_way_train_images.txt
Normal file
2
samples/c/one_way_train_images.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
one_way_train_0000.jpg
|
||||||
|
one_way_train_0001.jpg
|
Loading…
x
Reference in New Issue
Block a user