5
* Created by Victor Eruhimov on 3/23/10.
6
* Copyright 2010 Argus Corp. All rights reserved.
10
#include "precomp.hpp"
11
#include "opencv2/opencv_modules.hpp"
12
#ifdef HAVE_OPENCV_HIGHGUI
13
# include "opencv2/highgui.hpp"
19
inline int round(float value)
23
return int(value + 0.5f);
27
return int(value - 0.5f);
31
inline CvRect resize_rect(CvRect rect, float alpha)
33
return cvRect(rect.x + round((float)(0.5*(1 - alpha)*rect.width)), rect.y + round((float)(0.5*(1 - alpha)*rect.height)),
34
round(rect.width*alpha), round(rect.height*alpha));
37
CvMat* ConvertImageToMatrix(IplImage* patch);
44
m_rotation = cvCreateMat(1, 3, CV_32FC1);
45
m_translation = cvCreateMat(1, 3, CV_32FC1);
50
cvReleaseMat(&m_rotation);
51
cvReleaseMat(&m_translation);
54
void SetPose(CvMat* rotation, CvMat* translation)
56
cvCopy(rotation, m_rotation);
57
cvCopy(translation, m_translation);
60
CvMat* GetRotation() {return m_rotation;}
61
CvMat* GetTranslation() {return m_translation;}
68
// AffineTransformPatch: generates an affine transformed image patch.
69
// - src: source image (roi is supported)
70
// - dst: output image. ROI of dst image should be 2 times smaller than ROI of src.
71
// - pose: parameters of an affine transformation
72
void AffineTransformPatch(IplImage* src, IplImage* dst, CvAffinePose pose);
74
// GenerateAffineTransformFromPose: generates an affine transformation matrix from CvAffinePose instance
75
// - size: the size of image patch
76
// - pose: affine transformation
77
// - transform: 2x3 transformation matrix
78
void GenerateAffineTransformFromPose(CvSize size, CvAffinePose pose, CvMat* transform);
80
// Generates a random affine pose
81
CvAffinePose GenRandomAffinePose();
84
const static int num_mean_components = 500;
85
const static float noise_intensity = 0.15f;
88
static inline CvPoint rect_center(CvRect rect)
90
return cvPoint(rect.x + rect.width/2, rect.y + rect.height/2);
93
// static void homography_transform(IplImage* frontal, IplImage* result, CvMat* homography)
95
// cvWarpPerspective(frontal, result, homography);
98
static CvAffinePose perturbate_pose(CvAffinePose pose, float noise)
100
// perturbate the matrix
101
float noise_mult_factor = 1 + (0.5f - float(rand())/RAND_MAX)*noise;
102
float noise_add_factor = noise_mult_factor - 1;
104
CvAffinePose pose_pert = pose;
105
pose_pert.phi += noise_add_factor;
106
pose_pert.theta += noise_mult_factor;
107
pose_pert.lambda1 *= noise_mult_factor;
108
pose_pert.lambda2 *= noise_mult_factor;
113
static void generate_mean_patch(IplImage* frontal, IplImage* result, CvAffinePose pose, int pose_count, float noise)
115
IplImage* sum = cvCreateImage(cvSize(result->width, result->height), IPL_DEPTH_32F, 1);
116
IplImage* workspace = cvCloneImage(result);
117
IplImage* workspace_float = cvCloneImage(sum);
120
for(int i = 0; i < pose_count; i++)
122
CvAffinePose pose_pert = perturbate_pose(pose, noise);
124
AffineTransformPatch(frontal, workspace, pose_pert);
125
cvConvertScale(workspace, workspace_float);
126
cvAdd(sum, workspace_float, sum);
129
cvConvertScale(sum, result, 1.0f/pose_count);
131
cvReleaseImage(&workspace);
132
cvReleaseImage(&sum);
133
cvReleaseImage(&workspace_float);
136
// static void generate_mean_patch_fast(IplImage* /*frontal*/, IplImage* /*result*/, CvAffinePose /*pose*/,
137
// CvMat* /*pca_hr_avg*/, CvMat* /*pca_hr_eigenvectors*/, const OneWayDescriptor* /*pca_descriptors*/)
139
// /*for(int i = 0; i < pca_hr_eigenvectors->cols; i++)
145
void readPCAFeatures(const char *filename, CvMat** avg, CvMat** eigenvectors, const char *postfix = "");
146
void readPCAFeatures(const FileNode &fn, CvMat** avg, CvMat** eigenvectors, const char* postfix = "");
147
void savePCAFeatures(FileStorage &fs, const char* postfix, CvMat* avg, CvMat* eigenvectors);
148
void calcPCAFeatures(std::vector<IplImage*>& patches, FileStorage &fs, const char* postfix, CvMat** avg,
149
CvMat** eigenvectors);
150
void loadPCAFeatures(const char* path, const char* images_list, std::vector<IplImage*>& patches, CvSize patch_size);
151
void generatePCAFeatures(const char* path, const char* img_filename, FileStorage& fs, const char* postfix,
152
CvSize patch_size, CvMat** avg, CvMat** eigenvectors);
154
void eigenvector2image(CvMat* eigenvector, IplImage* img);
156
void FindOneWayDescriptor(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch, int& desc_idx, int& pose_idx, float& distance,
157
CvMat* avg = 0, CvMat* eigenvalues = 0);
159
void FindOneWayDescriptor(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch, int n,
160
std::vector<int>& desc_idxs, std::vector<int>& pose_idxs, std::vector<float>& distances,
161
CvMat* avg = 0, CvMat* eigenvalues = 0);
163
void FindOneWayDescriptor(cv::flann::Index* m_pca_descriptors_tree, CvSize patch_size, int m_pca_dim_low, int m_pose_count, IplImage* patch, int& desc_idx, int& pose_idx, float& distance,
164
CvMat* avg = 0, CvMat* eigenvalues = 0);
166
void FindOneWayDescriptorEx(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch,
167
float scale_min, float scale_max, float scale_step,
168
int& desc_idx, int& pose_idx, float& distance, float& scale,
169
CvMat* avg, CvMat* eigenvectors);
171
void FindOneWayDescriptorEx(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch,
172
float scale_min, float scale_max, float scale_step,
173
int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
174
std::vector<float>& distances, std::vector<float>& scales,
175
CvMat* avg, CvMat* eigenvectors);
177
void FindOneWayDescriptorEx(cv::flann::Index* m_pca_descriptors_tree, CvSize patch_size, int m_pca_dim_low, int m_pose_count, IplImage* patch,
178
float scale_min, float scale_max, float scale_step,
179
int& desc_idx, int& pose_idx, float& distance, float& scale,
180
CvMat* avg, CvMat* eigenvectors);
182
inline CvRect fit_rect_roi_fixedsize(CvRect rect, CvRect roi)
185
fit.x = MAX(fit.x, roi.x);
186
fit.y = MAX(fit.y, roi.y);
187
fit.x = MIN(fit.x, roi.x + roi.width - fit.width - 1);
188
fit.y = MIN(fit.y, roi.y + roi.height - fit.height - 1);
192
inline CvRect fit_rect_fixedsize(CvRect rect, IplImage* img)
194
CvRect roi = cvGetImageROI(img);
195
return fit_rect_roi_fixedsize(rect, roi);
198
OneWayDescriptor::OneWayDescriptor()
208
m_pca_dim_high = 100;
211
OneWayDescriptor::~OneWayDescriptor()
215
for(int i = 0; i < m_pose_count; i++)
217
cvReleaseImage(&m_samples[i]);
218
cvReleaseMat(&m_pca_coeffs[i]);
220
cvReleaseImage(&m_input_patch);
221
cvReleaseImage(&m_train_patch);
223
delete []m_pca_coeffs;
227
delete []m_affine_poses;
232
void OneWayDescriptor::Allocate(int pose_count, CvSize size, int nChannels)
234
m_pose_count = pose_count;
235
m_samples = new IplImage* [m_pose_count];
236
m_pca_coeffs = new CvMat* [m_pose_count];
237
m_patch_size = cvSize(size.width/2, size.height/2);
241
m_affine_poses = new CvAffinePose[m_pose_count];
244
int length = m_pca_dim_low;//roi.width*roi.height;
245
for(int i = 0; i < m_pose_count; i++)
247
m_samples[i] = cvCreateImage(cvSize(size.width/2, size.height/2), IPL_DEPTH_32F, nChannels);
248
m_pca_coeffs[i] = cvCreateMat(1, length, CV_32FC1);
251
m_input_patch = cvCreateImage(GetPatchSize(), IPL_DEPTH_8U, 1);
252
m_train_patch = cvCreateImage(GetInputPatchSize(), IPL_DEPTH_8U, 1);
255
// static void cvmSet2DPoint(CvMat* matrix, int row, int col, CvPoint2D32f point)
257
// cvmSet(matrix, row, col, point.x);
258
// cvmSet(matrix, row, col + 1, point.y);
261
// static void cvmSet3DPoint(CvMat* matrix, int row, int col, CvPoint3D32f point)
263
// cvmSet(matrix, row, col, point.x);
264
// cvmSet(matrix, row, col + 1, point.y);
265
// cvmSet(matrix, row, col + 2, point.z);
268
CvAffinePose GenRandomAffinePose()
270
const float scale_min = 0.8f;
271
const float scale_max = 1.2f;
273
pose.theta = float(rand())/RAND_MAX*120 - 60;
274
pose.phi = float(rand())/RAND_MAX*360;
275
pose.lambda1 = scale_min + float(rand())/RAND_MAX*(scale_max - scale_min);
276
pose.lambda2 = scale_min + float(rand())/RAND_MAX*(scale_max - scale_min);
281
void GenerateAffineTransformFromPose(CvSize size, CvAffinePose pose, CvMat* transform)
283
CvMat* temp = cvCreateMat(3, 3, CV_32FC1);
284
CvMat* final = cvCreateMat(3, 3, CV_32FC1);
285
cvmSet(temp, 2, 0, 0.0f);
286
cvmSet(temp, 2, 1, 0.0f);
287
cvmSet(temp, 2, 2, 1.0f);
290
cvGetSubRect(temp, &rotation, cvRect(0, 0, 3, 2));
292
cv2DRotationMatrix(cvPoint2D32f(size.width/2, size.height/2), pose.phi, 1.0, &rotation);
295
cvmSet(temp, 0, 0, pose.lambda1);
296
cvmSet(temp, 0, 1, 0.0f);
297
cvmSet(temp, 1, 0, 0.0f);
298
cvmSet(temp, 1, 1, pose.lambda2);
299
cvmSet(temp, 0, 2, size.width/2*(1 - pose.lambda1));
300
cvmSet(temp, 1, 2, size.height/2*(1 - pose.lambda2));
301
cvMatMul(temp, final, final);
303
cv2DRotationMatrix(cvPoint2D32f(size.width/2, size.height/2), pose.theta - pose.phi, 1.0, &rotation);
304
cvMatMul(temp, final, final);
306
cvGetSubRect(final, &rotation, cvRect(0, 0, 3, 2));
307
cvCopy(&rotation, transform);
310
cvReleaseMat(&final);
313
void AffineTransformPatch(IplImage* src, IplImage* dst, CvAffinePose pose)
315
CvRect src_large_roi = cvGetImageROI(src);
317
IplImage* temp = cvCreateImage(cvSize(src_large_roi.width, src_large_roi.height), IPL_DEPTH_32F, src->nChannels);
319
IplImage* temp2 = cvCloneImage(temp);
320
CvMat* rotation_phi = cvCreateMat(2, 3, CV_32FC1);
322
CvSize new_size = cvSize(cvRound(temp->width*pose.lambda1), cvRound(temp->height*pose.lambda2));
323
IplImage* temp3 = cvCreateImage(new_size, IPL_DEPTH_32F, src->nChannels);
325
cvConvertScale(src, temp);
326
cvResetImageROI(temp);
329
cv2DRotationMatrix(cvPoint2D32f(temp->width/2, temp->height/2), pose.phi, 1.0, rotation_phi);
330
cvWarpAffine(temp, temp2, rotation_phi);
334
cvResize(temp2, temp3);
336
cv2DRotationMatrix(cvPoint2D32f(temp3->width/2, temp3->height/2), pose.theta - pose.phi, 1.0, rotation_phi);
337
cvWarpAffine(temp3, temp, rotation_phi);
339
cvSetImageROI(temp, cvRect(temp->width/2 - src_large_roi.width/4, temp->height/2 - src_large_roi.height/4,
340
src_large_roi.width/2, src_large_roi.height/2));
341
cvConvertScale(temp, dst);
342
cvReleaseMat(&rotation_phi);
344
cvReleaseImage(&temp3);
345
cvReleaseImage(&temp2);
346
cvReleaseImage(&temp);
349
void OneWayDescriptor::GenerateSamples(int pose_count, IplImage* frontal, int norm)
353
GenerateSamplesWithTransforms(pose_count, frontal);
357
CvRect roi = cvGetImageROI(frontal);
358
IplImage* patch_8u = cvCreateImage(cvSize(roi.width/2, roi.height/2), frontal->depth, frontal->nChannels);
359
for(int i = 0; i < pose_count; i++)
363
m_affine_poses[i] = GenRandomAffinePose();
365
//AffineTransformPatch(frontal, patch_8u, m_affine_poses[i]);
366
generate_mean_patch(frontal, patch_8u, m_affine_poses[i], num_mean_components, noise_intensity);
371
double sum = cvSum(patch_8u).val[0];
374
cvConvertScale(patch_8u, m_samples[i], scale);
378
cvMinMaxLoc(m_samples[i], 0, &maxval);
379
IplImage* test = cvCreateImage(cvSize(roi.width/2, roi.height/2), IPL_DEPTH_8U, 1);
380
cvConvertScale(m_samples[i], test, 255.0/maxval);
381
cvNamedWindow("1", 1);
382
cvShowImage("1", test);
386
cvReleaseImage(&patch_8u);
389
void OneWayDescriptor::GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg,
390
CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors)
392
CvRect roi = cvGetImageROI(frontal);
393
if(roi.width != GetInputPatchSize().width || roi.height != GetInputPatchSize().height)
395
cvResize(frontal, m_train_patch);
396
frontal = m_train_patch;
399
CvMat* pca_coeffs = cvCreateMat(1, pca_hr_eigenvectors->cols, CV_32FC1);
401
cvMinMaxLoc(frontal, 0, &maxval);
402
CvMat* frontal_data = ConvertImageToMatrix(frontal);
404
double sum = cvSum(frontal_data).val[0];
405
cvConvertScale(frontal_data, frontal_data, 1.0f/sum);
406
cvProjectPCA(frontal_data, pca_hr_avg, pca_hr_eigenvectors, pca_coeffs);
407
for(int i = 0; i < m_pose_count; i++)
409
cvSetZero(m_samples[i]);
410
for(int j = 0; j < m_pca_dim_high; j++)
412
double coeff = cvmGet(pca_coeffs, 0, j);
413
IplImage* patch = pca_descriptors[j + 1].GetPatch(i);
414
cvAddWeighted(m_samples[i], 1.0, patch, coeff, 0, m_samples[i]);
417
printf("coeff%d = %f\n", j, coeff);
418
IplImage* test = cvCreateImage(cvSize(12, 12), IPL_DEPTH_8U, 1);
420
cvMinMaxLoc(patch, 0, &maxval);
421
cvConvertScale(patch, test, 255.0/maxval);
422
cvNamedWindow("1", 1);
423
cvShowImage("1", test);
428
cvAdd(pca_descriptors[0].GetPatch(i), m_samples[i], m_samples[i]);
429
double sm = cvSum(m_samples[i]).val[0];
430
cvConvertScale(m_samples[i], m_samples[i], 1.0/sm);
433
IplImage* test = cvCreateImage(cvSize(12, 12), IPL_DEPTH_8U, 1);
434
/* IplImage* temp1 = cvCreateImage(cvSize(12, 12), IPL_DEPTH_32F, 1);
435
eigenvector2image(pca_hr_avg, temp1);
436
IplImage* test = cvCreateImage(cvSize(12, 12), IPL_DEPTH_8U, 1);
437
cvAdd(m_samples[i], temp1, temp1);
438
cvMinMaxLoc(temp1, 0, &maxval);
439
cvConvertScale(temp1, test, 255.0/maxval);*/
440
cvMinMaxLoc(m_samples[i], 0, &maxval);
441
cvConvertScale(m_samples[i], test, 255.0/maxval);
443
cvNamedWindow("1", 1);
444
cvShowImage("1", frontal);
445
cvNamedWindow("2", 1);
446
cvShowImage("2", test);
451
cvReleaseMat(&pca_coeffs);
452
cvReleaseMat(&frontal_data);
455
void OneWayDescriptor::SetTransforms(CvAffinePose* poses, CvMat** transforms)
459
delete []m_affine_poses;
462
m_affine_poses = poses;
463
m_transforms = transforms;
466
void OneWayDescriptor::Initialize(int pose_count, IplImage* frontal, const char* feature_name, int norm)
468
m_feature_name = String(feature_name);
469
CvRect roi = cvGetImageROI(frontal);
470
m_center = rect_center(roi);
472
Allocate(pose_count, cvSize(roi.width, roi.height), frontal->nChannels);
474
GenerateSamples(pose_count, frontal, norm);
477
void OneWayDescriptor::InitializeFast(int pose_count, IplImage* frontal, const char* feature_name,
478
CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, OneWayDescriptor* pca_descriptors)
482
Initialize(pose_count, frontal, feature_name, 1);
485
m_feature_name = String(feature_name);
486
CvRect roi = cvGetImageROI(frontal);
487
m_center = rect_center(roi);
489
Allocate(pose_count, cvSize(roi.width, roi.height), frontal->nChannels);
491
GenerateSamplesFast(frontal, pca_hr_avg, pca_hr_eigenvectors, pca_descriptors);
494
void OneWayDescriptor::InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors)
496
for(int i = 0; i < m_pose_count; i++)
498
ProjectPCASample(m_samples[i], avg, eigenvectors, m_pca_coeffs[i]);
502
void OneWayDescriptor::ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const
504
CvMat* patch_mat = ConvertImageToMatrix(patch);
505
// CvMat eigenvectorsr;
506
// cvGetSubRect(eigenvectors, &eigenvectorsr, cvRect(0, 0, eigenvectors->cols, pca_coeffs->cols));
507
CvMat* temp = cvCreateMat(1, eigenvectors->cols, CV_32FC1);
508
cvProjectPCA(patch_mat, avg, eigenvectors, temp);
510
cvGetSubRect(temp, &temp1, cvRect(0, 0, pca_coeffs->cols, 1));
511
cvCopy(&temp1, pca_coeffs);
514
cvReleaseMat(&patch_mat);
517
void OneWayDescriptor::EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvectors) const
522
if (!CV_IS_MAT(patch))
524
EstimatePose((IplImage*)patch, pose_idx, distance);
533
if (!CV_IS_MAT(patch))
535
roi = cvGetImageROI((IplImage*)patch);
536
if(roi.width != GetPatchSize().width || roi.height != GetPatchSize().height)
538
cvResize(patch, m_input_patch);
539
patch = m_input_patch;
540
roi = cvGetImageROI((IplImage*)patch);
544
CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);
546
if (CV_IS_MAT(patch))
548
cvCopy((CvMat*)patch, pca_coeffs);
552
IplImage* patch_32f = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_32F, 1);
553
double sum = cvSum(patch).val[0];
554
cvConvertScale(patch, patch_32f, 1.0f/sum);
555
ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs);
556
cvReleaseImage(&patch_32f);
563
for(int i = 0; i < m_pose_count; i++)
565
double dist = cvNorm(m_pca_coeffs[i], pca_coeffs);
567
// float data1, data2;
568
// //CvMat* pose_pca_coeffs = m_pca_coeffs[i];
569
// for (int x=0; x < pca_coeffs->width; x++)
570
// for (int y =0 ; y < pca_coeffs->height; y++)
572
// data1 = ((float*)(pca_coeffs->data.ptr + pca_coeffs->step*x))[y];
573
// data2 = ((float*)(m_pca_coeffs[i]->data.ptr + m_pca_coeffs[i]->step*x))[y];
574
// dist+=(data1-data2)*(data1-data2);
577
// for (int j = 0; j < m_pca_dim_low; j++)
579
// dist += (pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j])*(pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j]);
582
// for (int j = 0; j <= m_pca_dim_low - 4; j += 4)
584
// dist += (pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j])*
585
// (pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j]);
586
// dist += (pose_pca_coeffs->data.fl[j+1]- pca_coeffs->data.fl[j+1])*
587
// (pose_pca_coeffs->data.fl[j+1]- pca_coeffs->data.fl[j+1]);
588
// dist += (pose_pca_coeffs->data.fl[j+2]- pca_coeffs->data.fl[j+2])*
589
// (pose_pca_coeffs->data.fl[j+2]- pca_coeffs->data.fl[j+2]);
590
// dist += (pose_pca_coeffs->data.fl[j+3]- pca_coeffs->data.fl[j+3])*
591
// (pose_pca_coeffs->data.fl[j+3]- pca_coeffs->data.fl[j+3]);
596
distance = (float)dist;
601
cvReleaseMat(&pca_coeffs);
604
void OneWayDescriptor::EstimatePose(IplImage* patch, int& pose_idx, float& distance) const
609
CvRect roi = cvGetImageROI(patch);
610
IplImage* patch_32f = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_32F, patch->nChannels);
611
double sum = cvSum(patch).val[0];
612
cvConvertScale(patch, patch_32f, 1/sum);
614
for(int i = 0; i < m_pose_count; i++)
616
if(m_samples[i]->width != patch_32f->width || m_samples[i]->height != patch_32f->height)
620
double dist = cvNorm(m_samples[i], patch_32f);
624
//for (int y = 0; y<patch_32f->height; y++)
625
// for (int x = 0; x< patch_32f->width; x++)
627
// i1 = ((float*)(m_samples[i]->imageData + m_samples[i]->widthStep*y))[x];
628
// i2 = ((float*)(patch_32f->imageData + patch_32f->widthStep*y))[x];
629
// dist+= (i1-i2)*(i1-i2);
634
distance = (float)dist;
639
IplImage* img1 = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_8U, 1);
640
IplImage* img2 = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_8U, 1);
642
cvMinMaxLoc(m_samples[i], 0, &maxval);
643
cvConvertScale(m_samples[i], img1, 255.0/maxval);
644
cvMinMaxLoc(patch_32f, 0, &maxval);
645
cvConvertScale(patch_32f, img2, 255.0/maxval);
647
cvNamedWindow("1", 1);
648
cvShowImage("1", img1);
649
cvNamedWindow("2", 1);
650
cvShowImage("2", img2);
651
printf("Distance = %f\n", dist);
656
cvReleaseImage(&patch_32f);
659
void OneWayDescriptor::Save(const char* path)
661
for(int i = 0; i < m_pose_count; i++)
664
sprintf(buf, "%s/patch_%04d.png", path, i);
665
IplImage* patch = cvCreateImage(cvSize(m_samples[i]->width, m_samples[i]->height), IPL_DEPTH_8U, m_samples[i]->nChannels);
668
cvMinMaxLoc(m_samples[i], 0, &maxval);
669
cvConvertScale(m_samples[i], patch, 255/maxval);
671
#ifdef HAVE_OPENCV_HIGHGUI
672
cv::imwrite(buf, cv::cvarrToMat(patch));
674
CV_Error(CV_StsNotImplemented, "OpenCV has been compiled without image I/O support");
677
cvReleaseImage(&patch);
681
void OneWayDescriptor::Write(CvFileStorage* fs, const char* name)
683
CvMat* mat = cvCreateMat(m_pose_count, m_samples[0]->width*m_samples[0]->height, CV_32FC1);
685
// prepare data to write as a single matrix
686
for(int i = 0; i < m_pose_count; i++)
688
for(int y = 0; y < m_samples[i]->height; y++)
690
for(int x = 0; x < m_samples[i]->width; x++)
692
float val = *((float*)(m_samples[i]->imageData + m_samples[i]->widthStep*y) + x);
693
cvmSet(mat, i, y*m_samples[i]->width + x, val);
698
cvWrite(fs, name, mat);
703
int OneWayDescriptor::ReadByName(const FileNode &parent, const char* name)
705
CvMat* mat = reinterpret_cast<CvMat*> (parent[name].readObj ());
712
for(int i = 0; i < m_pose_count; i++)
714
for(int y = 0; y < m_samples[i]->height; y++)
716
for(int x = 0; x < m_samples[i]->width; x++)
718
float val = (float)cvmGet(mat, i, y*m_samples[i]->width + x);
719
*((float*)(m_samples[i]->imageData + y*m_samples[i]->widthStep) + x) = val;
728
int OneWayDescriptor::ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name)
730
return ReadByName (FileNode (fs, parent), name);
733
IplImage* OneWayDescriptor::GetPatch(int index)
735
return m_samples[index];
738
CvAffinePose OneWayDescriptor::GetPose(int index) const
740
return m_affine_poses[index];
743
void FindOneWayDescriptor(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch, int& desc_idx, int& pose_idx, float& distance,
744
CvMat* avg, CvMat* eigenvectors)
750
//PCA_coeffs precalculating
751
int m_pca_dim_low = descriptors[0].GetPCADimLow();
752
CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);
753
int patch_width = descriptors[0].GetPatchSize().width;
754
int patch_height = descriptors[0].GetPatchSize().height;
757
CvRect _roi = cvGetImageROI((IplImage*)patch);
758
IplImage* test_img = cvCreateImage(cvSize(patch_width,patch_height), IPL_DEPTH_8U, 1);
759
if(_roi.width != patch_width|| _roi.height != patch_height)
762
cvResize(patch, test_img);
763
_roi = cvGetImageROI(test_img);
767
cvCopy(patch,test_img);
769
IplImage* patch_32f = cvCreateImage(cvSize(_roi.width, _roi.height), IPL_DEPTH_32F, 1);
770
double sum = cvSum(test_img).val[0];
771
cvConvertScale(test_img, patch_32f, 1.0f/sum);
773
//ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs);
775
CvMat* patch_mat = ConvertImageToMatrix(patch_32f);
776
CvMat* temp = cvCreateMat(1, eigenvectors->cols, CV_32FC1);
777
cvProjectPCA(patch_mat, avg, eigenvectors, temp);
779
cvGetSubRect(temp, &temp1, cvRect(0, 0, pca_coeffs->cols, 1));
780
cvCopy(&temp1, pca_coeffs);
782
cvReleaseMat(&patch_mat);
785
cvReleaseImage(&patch_32f);
786
cvReleaseImage(&test_img);
793
for(int i = 0; i < desc_count; i++)
799
descriptors[i].EstimatePose(patch, _pose_idx, _distance);
803
descriptors[i].EstimatePosePCA(patch, _pose_idx, _distance, avg, eigenvectors);
807
descriptors[i].EstimatePosePCA(pca_coeffs, _pose_idx, _distance, avg, eigenvectors);
811
if(_distance < distance)
814
pose_idx = _pose_idx;
815
distance = _distance;
818
cvReleaseMat(&pca_coeffs);
823
void FindOneWayDescriptor(cv::flann::Index* m_pca_descriptors_tree, CvSize patch_size, int m_pca_dim_low, int m_pose_count, IplImage* patch, int& desc_idx, int& pose_idx, float& distance,
824
CvMat* avg, CvMat* eigenvectors)
830
//PCA_coeffs precalculating
831
CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);
832
int patch_width = patch_size.width;
833
int patch_height = patch_size.height;
836
CvRect _roi = cvGetImageROI((IplImage*)patch);
837
IplImage* test_img = cvCreateImage(cvSize(patch_width,patch_height), IPL_DEPTH_8U, 1);
838
if(_roi.width != patch_width|| _roi.height != patch_height)
841
cvResize(patch, test_img);
842
_roi = cvGetImageROI(test_img);
846
cvCopy(patch,test_img);
848
IplImage* patch_32f = cvCreateImage(cvSize(_roi.width, _roi.height), IPL_DEPTH_32F, 1);
849
float sum = cvSum(test_img).val[0];
850
cvConvertScale(test_img, patch_32f, 1.0f/sum);
852
//ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs);
854
CvMat* patch_mat = ConvertImageToMatrix(patch_32f);
855
CvMat* temp = cvCreateMat(1, eigenvectors->cols, CV_32FC1);
856
cvProjectPCA(patch_mat, avg, eigenvectors, temp);
858
cvGetSubRect(temp, &temp1, cvRect(0, 0, pca_coeffs->cols, 1));
859
cvCopy(&temp1, pca_coeffs);
861
cvReleaseMat(&patch_mat);
864
cvReleaseImage(&patch_32f);
865
cvReleaseImage(&test_img);
870
//float* target = new float[m_pca_dim_low];
871
//::cvflann::KNNResultSet res(1,pca_coeffs->data.fl,m_pca_dim_low);
872
//::cvflann::SearchParams params;
873
//params.checks = -1;
875
//int maxDepth = 1000000;
876
//int neighbors_count = 1;
877
//int* neighborsIdx = new int[neighbors_count];
878
//float* distances = new float[neighbors_count];
879
//if (m_pca_descriptors_tree->findNearest(pca_coeffs->data.fl,neighbors_count,maxDepth,neighborsIdx,0,distances) > 0)
881
// desc_idx = neighborsIdx[0] / m_pose_count;
882
// pose_idx = neighborsIdx[0] % m_pose_count;
883
// distance = distances[0];
885
//delete[] neighborsIdx;
886
//delete[] distances;
888
cv::Mat m_object(1, m_pca_dim_low, CV_32F);
889
cv::Mat m_indices(1, 1, CV_32S);
890
cv::Mat m_dists(1, 1, CV_32F);
892
float* object_ptr = m_object.ptr<float>(0);
893
for (int i=0;i<m_pca_dim_low;i++)
895
object_ptr[i] = pca_coeffs->data.fl[i];
898
m_pca_descriptors_tree->knnSearch(m_object, m_indices, m_dists, 1, cv::flann::SearchParams(-1) );
900
desc_idx = ((int*)(m_indices.ptr<int>(0)))[0] / m_pose_count;
901
pose_idx = ((int*)(m_indices.ptr<int>(0)))[0] % m_pose_count;
902
distance = ((float*)(m_dists.ptr<float>(0)))[0];
907
// for(int i = 0; i < desc_count; i++)
909
// int _pose_idx = -1;
910
// float _distance = 0;
913
// descriptors[i].EstimatePose(patch, _pose_idx, _distance);
917
// descriptors[i].EstimatePosePCA(patch, _pose_idx, _distance, avg, eigenvectors);
921
// descriptors[i].EstimatePosePCA(pca_coeffs, _pose_idx, _distance, avg, eigenvectors);
925
// if(_distance < distance)
928
// pose_idx = _pose_idx;
929
// distance = _distance;
932
cvReleaseMat(&pca_coeffs);
936
void FindOneWayDescriptor(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch, int n,
937
std::vector<int>& desc_idxs, std::vector<int>& pose_idxs, std::vector<float>& distances,
938
CvMat* avg, CvMat* eigenvectors)
940
for (int i=0;i<n;i++)
947
//PCA_coeffs precalculating
948
int m_pca_dim_low = descriptors[0].GetPCADimLow();
949
CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);
950
int patch_width = descriptors[0].GetPatchSize().width;
951
int patch_height = descriptors[0].GetPatchSize().height;
954
CvRect _roi = cvGetImageROI((IplImage*)patch);
955
IplImage* test_img = cvCreateImage(cvSize(patch_width,patch_height), IPL_DEPTH_8U, 1);
956
if(_roi.width != patch_width|| _roi.height != patch_height)
959
cvResize(patch, test_img);
960
_roi = cvGetImageROI(test_img);
964
cvCopy(patch,test_img);
966
IplImage* patch_32f = cvCreateImage(cvSize(_roi.width, _roi.height), IPL_DEPTH_32F, 1);
967
double sum = cvSum(test_img).val[0];
968
cvConvertScale(test_img, patch_32f, 1.0f/sum);
970
//ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs);
972
CvMat* patch_mat = ConvertImageToMatrix(patch_32f);
973
CvMat* temp = cvCreateMat(1, eigenvectors->cols, CV_32FC1);
974
cvProjectPCA(patch_mat, avg, eigenvectors, temp);
976
cvGetSubRect(temp, &temp1, cvRect(0, 0, pca_coeffs->cols, 1));
977
cvCopy(&temp1, pca_coeffs);
979
cvReleaseMat(&patch_mat);
982
cvReleaseImage(&patch_32f);
983
cvReleaseImage(&test_img);
989
for(int i = 0; i < desc_count; i++)
995
descriptors[i].EstimatePose(patch, _pose_idx, _distance);
999
descriptors[i].EstimatePosePCA(patch, _pose_idx, _distance, avg, eigenvectors);
1003
descriptors[i].EstimatePosePCA(pca_coeffs, _pose_idx, _distance, avg, eigenvectors);
1007
for (int j=0;j<n;j++)
1009
if(_distance < distances[j])
1011
for (int k=(n-1);k > j;k--)
1013
desc_idxs[k] = desc_idxs[k-1];
1014
pose_idxs[k] = pose_idxs[k-1];
1015
distances[k] = distances[k-1];
1018
pose_idxs[j] = _pose_idx;
1019
distances[j] = _distance;
1024
cvReleaseMat(&pca_coeffs);
1027
void FindOneWayDescriptorEx(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch,
1028
float scale_min, float scale_max, float scale_step,
1029
int& desc_idx, int& pose_idx, float& distance, float& scale,
1030
CvMat* avg, CvMat* eigenvectors)
1032
CvSize patch_size = descriptors[0].GetPatchSize();
1033
IplImage* input_patch;
1036
input_patch= cvCreateImage(patch_size, IPL_DEPTH_8U, 1);
1037
roi = cvGetImageROI((IplImage*)patch);
1039
int _desc_idx, _pose_idx;
1042
for(float cur_scale = scale_min; cur_scale < scale_max; cur_scale *= scale_step)
1044
// printf("Scale = %f\n", cur_scale);
1046
CvRect roi_scaled = resize_rect(roi, cur_scale);
1047
cvSetImageROI(patch, roi_scaled);
1048
cvResize(patch, input_patch);
1052
if(roi.x > 244 && roi.y < 200)
1054
cvNamedWindow("1", 1);
1055
cvShowImage("1", input_patch);
1060
FindOneWayDescriptor(desc_count, descriptors, input_patch, _desc_idx, _pose_idx, _distance, avg, eigenvectors);
1061
if(_distance < distance)
1063
distance = _distance;
1064
desc_idx = _desc_idx;
1065
pose_idx = _pose_idx;
1071
cvSetImageROI((IplImage*)patch, roi);
1072
cvReleaseImage(&input_patch);
1076
void FindOneWayDescriptorEx(int desc_count, const OneWayDescriptor* descriptors, IplImage* patch,
1077
float scale_min, float scale_max, float scale_step,
1078
int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
1079
std::vector<float>& distances, std::vector<float>& scales,
1080
CvMat* avg, CvMat* eigenvectors)
1082
CvSize patch_size = descriptors[0].GetPatchSize();
1083
IplImage* input_patch;
1086
input_patch= cvCreateImage(patch_size, IPL_DEPTH_8U, 1);
1087
roi = cvGetImageROI((IplImage*)patch);
1089
// float min_distance = 1e10;
1090
std::vector<int> _desc_idxs;
1091
_desc_idxs.resize(n);
1092
std::vector<int> _pose_idxs;
1093
_pose_idxs.resize(n);
1094
std::vector<float> _distances;
1095
_distances.resize(n);
1098
for (int i=0;i<n;i++)
1100
distances[i] = 1e10;
1103
for(float cur_scale = scale_min; cur_scale < scale_max; cur_scale *= scale_step)
1106
CvRect roi_scaled = resize_rect(roi, cur_scale);
1107
cvSetImageROI(patch, roi_scaled);
1108
cvResize(patch, input_patch);
1112
FindOneWayDescriptor(desc_count, descriptors, input_patch, n,_desc_idxs, _pose_idxs, _distances, avg, eigenvectors);
1113
for (int i=0;i<n;i++)
1115
if(_distances[i] < distances[i])
1117
distances[i] = _distances[i];
1118
desc_idxs[i] = _desc_idxs[i];
1119
pose_idxs[i] = _pose_idxs[i];
1120
scales[i] = cur_scale;
1127
cvSetImageROI((IplImage*)patch, roi);
1128
cvReleaseImage(&input_patch);
1131
#if defined(_KDTREE)
1132
void FindOneWayDescriptorEx(cv::flann::Index* m_pca_descriptors_tree, CvSize patch_size, int m_pca_dim_low,
1133
int m_pose_count, IplImage* patch,
1134
float scale_min, float scale_max, float scale_step,
1135
int& desc_idx, int& pose_idx, float& distance, float& scale,
1136
CvMat* avg, CvMat* eigenvectors)
1138
IplImage* input_patch;
1141
input_patch= cvCreateImage(patch_size, IPL_DEPTH_8U, 1);
1142
roi = cvGetImageROI((IplImage*)patch);
1144
int _desc_idx, _pose_idx;
1147
for(float cur_scale = scale_min; cur_scale < scale_max; cur_scale *= scale_step)
1149
// printf("Scale = %f\n", cur_scale);
1151
CvRect roi_scaled = resize_rect(roi, cur_scale);
1152
cvSetImageROI(patch, roi_scaled);
1153
cvResize(patch, input_patch);
1155
FindOneWayDescriptor(m_pca_descriptors_tree, patch_size, m_pca_dim_low, m_pose_count, input_patch, _desc_idx, _pose_idx, _distance, avg, eigenvectors);
1156
if(_distance < distance)
1158
distance = _distance;
1159
desc_idx = _desc_idx;
1160
pose_idx = _pose_idx;
1166
cvSetImageROI((IplImage*)patch, roi);
1167
cvReleaseImage(&input_patch);
1172
const char* OneWayDescriptor::GetFeatureName() const
1174
return m_feature_name.c_str();
1177
CvPoint OneWayDescriptor::GetCenter() const
1182
int OneWayDescriptor::GetPCADimLow() const
1184
return m_pca_dim_low;
1187
int OneWayDescriptor::GetPCADimHigh() const
1189
return m_pca_dim_high;
1192
CvMat* ConvertImageToMatrix(IplImage* patch)
1194
CvRect roi = cvGetImageROI(patch);
1195
CvMat* mat = cvCreateMat(1, roi.width*roi.height, CV_32FC1);
1197
if(patch->depth == 32)
1199
for(int y = 0; y < roi.height; y++)
1201
for(int x = 0; x < roi.width; x++)
1203
mat->data.fl[y*roi.width + x] = *((float*)(patch->imageData + (y + roi.y)*patch->widthStep) + x + roi.x);
1207
else if(patch->depth == 8)
1209
for(int y = 0; y < roi.height; y++)
1211
for(int x = 0; x < roi.width; x++)
1213
mat->data.fl[y*roi.width + x] = (float)(unsigned char)patch->imageData[(y + roi.y)*patch->widthStep + x + roi.x];
1219
printf("Image depth %d is not supported\n", patch->depth);
1226
OneWayDescriptorBase::OneWayDescriptorBase(CvSize patch_size, int pose_count, const char* train_path,
1227
const char* pca_config, const char* pca_hr_config,
1228
const char* pca_desc_config, int pyr_levels,
1229
int pca_dim_high, int pca_dim_low)
1230
: m_pca_dim_high(pca_dim_high), m_pca_dim_low(pca_dim_low), scale_min (0.7f), scale_max(1.5f), scale_step (1.2f)
1232
#if defined(_KDTREE)
1233
m_pca_descriptors_matrix = 0;
1234
m_pca_descriptors_tree = 0;
1236
// m_pca_descriptors_matrix = 0;
1237
m_patch_size = patch_size;
1238
m_pose_count = pose_count;
1239
m_pyr_levels = pyr_levels;
1244
m_pca_eigenvectors = 0;
1246
m_pca_hr_eigenvectors = 0;
1247
m_pca_descriptors = 0;
1251
if(train_path == 0 || strlen(train_path) == 0)
1256
char pca_config_filename[1024];
1257
sprintf(pca_config_filename, "%s/%s", train_path, pca_config);
1258
readPCAFeatures(pca_config_filename, &m_pca_avg, &m_pca_eigenvectors);
1259
if(pca_hr_config && strlen(pca_hr_config) > 0)
1261
char pca_hr_config_filename[1024];
1262
sprintf(pca_hr_config_filename, "%s/%s", train_path, pca_hr_config);
1263
readPCAFeatures(pca_hr_config_filename, &m_pca_hr_avg, &m_pca_hr_eigenvectors);
1266
m_pca_descriptors = new OneWayDescriptor[m_pca_dim_high + 1];
1268
#if !defined(_GH_REGIONS)
1269
if(pca_desc_config && strlen(pca_desc_config) > 0)
1272
//printf("Loading the descriptors...");
1273
char pca_desc_config_filename[1024];
1274
sprintf(pca_desc_config_filename, "%s/%s", train_path, pca_desc_config);
1275
LoadPCADescriptors(pca_desc_config_filename);
1276
//printf("done.\n");
1280
printf("Initializing the descriptors...\n");
1281
InitializePoseTransforms();
1282
CreatePCADescriptors();
1283
SavePCADescriptors("pca_descriptors.yml");
1285
#endif //_GH_REGIONS
1286
// SavePCADescriptors("./pca_descriptors.yml");
1290
OneWayDescriptorBase::OneWayDescriptorBase(CvSize patch_size, int pose_count, const String &pca_filename,
1291
const String &train_path, const String &images_list, float _scale_min, float _scale_max,
1292
float _scale_step, int pyr_levels,
1293
int pca_dim_high, int pca_dim_low)
1294
: m_pca_dim_high(pca_dim_high), m_pca_dim_low(pca_dim_low), scale_min(_scale_min), scale_max(_scale_max), scale_step(_scale_step)
1296
#if defined(_KDTREE)
1297
m_pca_descriptors_matrix = 0;
1298
m_pca_descriptors_tree = 0;
1300
m_patch_size = patch_size;
1301
m_pose_count = pose_count;
1302
m_pyr_levels = pyr_levels;
1307
m_pca_eigenvectors = 0;
1309
m_pca_hr_eigenvectors = 0;
1310
m_pca_descriptors = 0;
1315
if (pca_filename.length() == 0)
1320
CvFileStorage* fs = cvOpenFileStorage(pca_filename.c_str(), NULL, CV_STORAGE_READ);
1323
cvReleaseFileStorage(&fs);
1325
readPCAFeatures(pca_filename.c_str(), &m_pca_avg, &m_pca_eigenvectors, "_lr");
1326
readPCAFeatures(pca_filename.c_str(), &m_pca_hr_avg, &m_pca_hr_eigenvectors, "_hr");
1327
m_pca_descriptors = new OneWayDescriptor[m_pca_dim_high + 1];
1328
#if !defined(_GH_REGIONS)
1329
LoadPCADescriptors(pca_filename.c_str());
1330
#endif //_GH_REGIONS
1334
GeneratePCA(train_path.c_str(), images_list.c_str());
1335
m_pca_descriptors = new OneWayDescriptor[m_pca_dim_high + 1];
1336
char pca_default_filename[1024];
1337
sprintf(pca_default_filename, "%s/%s", train_path.c_str(), GetPCAFilename().c_str());
1338
LoadPCADescriptors(pca_default_filename);
1342
void OneWayDescriptorBase::Read (const FileNode &fn)
1346
m_pose_count = fn["poseCount"];
1347
int patch_width = fn["patchWidth"];
1348
int patch_height = fn["patchHeight"];
1349
m_patch_size = cvSize (patch_width, patch_height);
1350
m_pyr_levels = fn["pyrLevels"];
1351
m_pca_dim_high = fn["pcaDimHigh"];
1352
m_pca_dim_low = fn["pcaDimLow"];
1353
scale_min = fn["minScale"];
1354
scale_max = fn["maxScale"];
1355
scale_step = fn["stepScale"];
1360
void OneWayDescriptorBase::LoadPCAall (const FileNode &fn)
1362
readPCAFeatures(fn, &m_pca_avg, &m_pca_eigenvectors, "_lr");
1363
readPCAFeatures(fn, &m_pca_hr_avg, &m_pca_hr_eigenvectors, "_hr");
1364
m_pca_descriptors = new OneWayDescriptor[m_pca_dim_high + 1];
1365
#if !defined(_GH_REGIONS)
1366
LoadPCADescriptors(fn);
1367
#endif //_GH_REGIONS
1370
OneWayDescriptorBase::~OneWayDescriptorBase()
1372
cvReleaseMat(&m_pca_avg);
1373
cvReleaseMat(&m_pca_eigenvectors);
1375
if(m_pca_hr_eigenvectors)
1377
delete[] m_pca_descriptors;
1378
cvReleaseMat(&m_pca_hr_avg);
1379
cvReleaseMat(&m_pca_hr_eigenvectors);
1384
delete []m_descriptors;
1391
for(int i = 0; i < m_pose_count; i++)
1393
cvReleaseMat(&m_transforms[i]);
1395
delete []m_transforms;
1397
#if defined(_KDTREE)
1398
if (m_pca_descriptors_matrix)
1400
cvReleaseMat(&m_pca_descriptors_matrix);
1402
if (m_pca_descriptors_tree)
1404
delete m_pca_descriptors_tree;
1409
void OneWayDescriptorBase::clear(){
1412
delete []m_descriptors;
1416
#if defined(_KDTREE)
1417
if (m_pca_descriptors_matrix)
1419
cvReleaseMat(&m_pca_descriptors_matrix);
1420
m_pca_descriptors_matrix = 0;
1422
if (m_pca_descriptors_tree)
1424
delete m_pca_descriptors_tree;
1425
m_pca_descriptors_tree = 0;
1430
void OneWayDescriptorBase::InitializePoses()
1432
m_poses = new CvAffinePose[m_pose_count];
1433
for(int i = 0; i < m_pose_count; i++)
1435
m_poses[i] = GenRandomAffinePose();
1439
void OneWayDescriptorBase::InitializeTransformsFromPoses()
1441
m_transforms = new CvMat*[m_pose_count];
1442
for(int i = 0; i < m_pose_count; i++)
1444
m_transforms[i] = cvCreateMat(2, 3, CV_32FC1);
1445
GenerateAffineTransformFromPose(cvSize(m_patch_size.width*2, m_patch_size.height*2), m_poses[i], m_transforms[i]);
1449
void OneWayDescriptorBase::InitializePoseTransforms()
1452
InitializeTransformsFromPoses();
1455
void OneWayDescriptorBase::InitializeDescriptor(int desc_idx, IplImage* train_image, const KeyPoint& keypoint, const char* feature_label)
1458
// TBD add support for octave != 0
1459
CvPoint center = keypoint.pt;
1461
CvRect roi = cvRect(center.x - m_patch_size.width/2, center.y - m_patch_size.height/2, m_patch_size.width, m_patch_size.height);
1462
cvResetImageROI(train_image);
1463
roi = fit_rect_fixedsize(roi, train_image);
1464
cvSetImageROI(train_image, roi);
1465
if(roi.width != m_patch_size.width || roi.height != m_patch_size.height)
1470
InitializeDescriptor(desc_idx, train_image, feature_label);
1471
cvResetImageROI(train_image);
1474
void OneWayDescriptorBase::InitializeDescriptor(int desc_idx, IplImage* train_image, const char* feature_label)
1476
m_descriptors[desc_idx].SetPCADimHigh(m_pca_dim_high);
1477
m_descriptors[desc_idx].SetPCADimLow(m_pca_dim_low);
1478
m_descriptors[desc_idx].SetTransforms(m_poses, m_transforms);
1480
if(!m_pca_hr_eigenvectors)
1482
m_descriptors[desc_idx].Initialize(m_pose_count, train_image, feature_label);
1486
m_descriptors[desc_idx].InitializeFast(m_pose_count, train_image, feature_label,
1487
m_pca_hr_avg, m_pca_hr_eigenvectors, m_pca_descriptors);
1492
m_descriptors[desc_idx].InitializePCACoeffs(m_pca_avg, m_pca_eigenvectors);
1496
void OneWayDescriptorBase::FindDescriptor(IplImage* src, cv::Point2f pt, int& desc_idx, int& pose_idx, float& distance) const
1498
CvRect roi = cvRect(cvRound(pt.x - m_patch_size.width/4),
1499
cvRound(pt.y - m_patch_size.height/4),
1500
m_patch_size.width/2, m_patch_size.height/2);
1501
cvSetImageROI(src, roi);
1503
FindDescriptor(src, desc_idx, pose_idx, distance);
1504
cvResetImageROI(src);
1507
void OneWayDescriptorBase::FindDescriptor(IplImage* patch, int& desc_idx, int& pose_idx, float& distance, float* _scale, float* scale_ranges) const
1510
::FindOneWayDescriptor(m_train_feature_count, m_descriptors, patch, desc_idx, pose_idx, distance, m_pca_avg, m_pca_eigenvectors);
1512
float min = scale_min;
1513
float max = scale_max;
1514
float step = scale_step;
1518
min = scale_ranges[0];
1519
max = scale_ranges[1];
1524
#if !defined(_KDTREE)
1525
cv::FindOneWayDescriptorEx(m_train_feature_count, m_descriptors, patch,
1526
min, max, step, desc_idx, pose_idx, distance, scale,
1527
m_pca_avg, m_pca_eigenvectors);
1529
cv::FindOneWayDescriptorEx(m_pca_descriptors_tree, m_descriptors[0].GetPatchSize(), m_descriptors[0].GetPCADimLow(), m_pose_count, patch,
1530
min, max, step, desc_idx, pose_idx, distance, scale,
1531
m_pca_avg, m_pca_eigenvectors);
1540
void OneWayDescriptorBase::FindDescriptor(IplImage* patch, int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
1541
std::vector<float>& distances, std::vector<float>& _scales, float* scale_ranges) const
1543
float min = scale_min;
1544
float max = scale_max;
1545
float step = scale_step;
1549
min = scale_ranges[0];
1550
max = scale_ranges[1];
1553
distances.resize(n);
1555
desc_idxs.resize(n);
1556
pose_idxs.resize(n);
1557
/*float scales = 1.0f;*/
1559
cv::FindOneWayDescriptorEx(m_train_feature_count, m_descriptors, patch,
1560
min, max, step ,n, desc_idxs, pose_idxs, distances, _scales,
1561
m_pca_avg, m_pca_eigenvectors);
1565
void OneWayDescriptorBase::SetPCAHigh(CvMat* avg, CvMat* eigenvectors)
1567
m_pca_hr_avg = cvCloneMat(avg);
1568
m_pca_hr_eigenvectors = cvCloneMat(eigenvectors);
1571
void OneWayDescriptorBase::SetPCALow(CvMat* avg, CvMat* eigenvectors)
1573
m_pca_avg = cvCloneMat(avg);
1574
m_pca_eigenvectors = cvCloneMat(eigenvectors);
1577
void OneWayDescriptorBase::AllocatePCADescriptors()
1579
m_pca_descriptors = new OneWayDescriptor[m_pca_dim_high + 1];
1580
for(int i = 0; i < m_pca_dim_high + 1; i++)
1582
m_pca_descriptors[i].SetPCADimHigh(m_pca_dim_high);
1583
m_pca_descriptors[i].SetPCADimLow(m_pca_dim_low);
1587
void OneWayDescriptorBase::CreatePCADescriptors()
1589
if(m_pca_descriptors == 0)
1591
AllocatePCADescriptors();
1593
IplImage* frontal = cvCreateImage(m_patch_size, IPL_DEPTH_32F, 1);
1595
eigenvector2image(m_pca_hr_avg, frontal);
1596
m_pca_descriptors[0].SetTransforms(m_poses, m_transforms);
1597
m_pca_descriptors[0].Initialize(m_pose_count, frontal, "", 0);
1599
for(int j = 0; j < m_pca_dim_high; j++)
1602
cvGetSubRect(m_pca_hr_eigenvectors, &eigenvector, cvRect(0, j, m_pca_hr_eigenvectors->cols, 1));
1603
eigenvector2image(&eigenvector, frontal);
1605
m_pca_descriptors[j + 1].SetTransforms(m_poses, m_transforms);
1606
m_pca_descriptors[j + 1].Initialize(m_pose_count, frontal, "", 0);
1608
printf("Created descriptor for PCA component %d\n", j);
1611
cvReleaseImage(&frontal);
1615
int OneWayDescriptorBase::LoadPCADescriptors(const char* filename)
1617
FileStorage fs = FileStorage (filename, FileStorage::READ);
1620
printf("File %s not found...\n", filename);
1624
LoadPCADescriptors (fs.root ());
1626
printf("Successfully read %d pca components\n", m_pca_dim_high);
1632
int OneWayDescriptorBase::LoadPCADescriptors(const FileNode &fn)
1634
// read affine poses
1635
// FileNode* node = cvGetFileNodeByName(fs, 0, "affine poses");
1636
CvMat* poses = reinterpret_cast<CvMat*> (fn["affine_poses"].readObj ());
1639
poses = reinterpret_cast<CvMat*> (fn["affine poses"].readObj ());
1649
m_poses = new CvAffinePose[m_pose_count];
1650
for(int i = 0; i < m_pose_count; i++)
1652
m_poses[i].phi = (float)cvmGet(poses, i, 0);
1653
m_poses[i].theta = (float)cvmGet(poses, i, 1);
1654
m_poses[i].lambda1 = (float)cvmGet(poses, i, 2);
1655
m_poses[i].lambda2 = (float)cvmGet(poses, i, 3);
1657
cvReleaseMat(&poses);
1659
// now initialize pose transforms
1660
InitializeTransformsFromPoses();
1662
m_pca_dim_high = (int) fn["pca_components_number"];
1663
if (m_pca_dim_high == 0)
1665
m_pca_dim_high = (int) fn["pca components number"];
1667
if(m_pca_descriptors)
1669
delete []m_pca_descriptors;
1671
AllocatePCADescriptors();
1672
for(int i = 0; i < m_pca_dim_high + 1; i++)
1674
m_pca_descriptors[i].Allocate(m_pose_count, m_patch_size, 1);
1675
m_pca_descriptors[i].SetTransforms(m_poses, m_transforms);
1677
sprintf(buf, "descriptor_for_pca_component_%d", i);
1679
if (! m_pca_descriptors[i].ReadByName(fn, buf))
1681
sprintf(buf, "descriptor for pca component %d", i);
1682
m_pca_descriptors[i].ReadByName(fn, buf);
1689
void savePCAFeatures(FileStorage &fs, const char* postfix, CvMat* avg, CvMat* eigenvectors)
1692
sprintf(buf, "avg_%s", postfix);
1693
fs.writeObj(buf, avg);
1694
sprintf(buf, "eigenvectors_%s", postfix);
1695
fs.writeObj(buf, eigenvectors);
1698
void calcPCAFeatures(std::vector<IplImage*>& patches, FileStorage &fs, const char* postfix, CvMat** avg,
1699
CvMat** eigenvectors)
1701
int width = patches[0]->width;
1702
int height = patches[0]->height;
1703
int length = width * height;
1704
int patch_count = (int)patches.size();
1706
CvMat* data = cvCreateMat(patch_count, length, CV_32FC1);
1707
*avg = cvCreateMat(1, length, CV_32FC1);
1708
CvMat* eigenvalues = cvCreateMat(1, length, CV_32FC1);
1709
*eigenvectors = cvCreateMat(length, length, CV_32FC1);
1711
for (int i = 0; i < patch_count; i++)
1713
float nf = (float)(1./cvSum(patches[i]).val[0]);
1714
for (int y = 0; y < height; y++)
1716
for (int x = 0; x < width; x++)
1718
*((float*)(data->data.ptr + data->step * i) + y * width + x)
1719
= (unsigned char)patches[i]->imageData[y * patches[i]->widthStep + x] * nf;
1724
//printf("Calculating PCA...");
1725
cvCalcPCA(data, *avg, eigenvalues, *eigenvectors, CV_PCA_DATA_AS_ROW);
1729
savePCAFeatures(fs, postfix, *avg, *eigenvectors);
1731
cvReleaseMat(&data);
1732
cvReleaseMat(&eigenvalues);
1735
static void extractPatches (IplImage *img, std::vector<IplImage*>& patches, CvSize patch_size)
1737
std::vector<KeyPoint> features;
1738
Ptr<FeatureDetector> surf_extractor = FeatureDetector::create("SURF");
1739
if( !surf_extractor )
1740
CV_Error(CV_StsNotImplemented, "OpenCV was built without SURF support");
1741
surf_extractor->set("hessianThreshold", 1.0);
1742
//printf("Extracting SURF features...");
1743
surf_extractor->detect(cv::cvarrToMat(img), features);
1746
for (int j = 0; j < (int)features.size(); j++)
1748
int patch_width = patch_size.width;
1749
int patch_height = patch_size.height;
1751
CvPoint center = features[j].pt;
1753
CvRect roi = cvRect(center.x - patch_width / 2, center.y - patch_height / 2, patch_width, patch_height);
1754
cvSetImageROI(img, roi);
1755
roi = cvGetImageROI(img);
1756
if (roi.width != patch_width || roi.height != patch_height)
1761
IplImage* patch = cvCreateImage(cvSize(patch_width, patch_height), IPL_DEPTH_8U, 1);
1763
patches.push_back(patch);
1764
cvResetImageROI(img);
1766
//printf("Completed file, extracted %d features\n", (int)features.size());
1770
void loadPCAFeatures(const FileNode &fn, std::vector<IplImage*>& patches, CvSize patch_size)
1772
FileNodeIterator begin = fn.begin();
1773
for (FileNodeIterator i = fn.begin(); i != fn.end(); i++)
1775
IplImage *img = reinterpret_cast<IplImage*> ((*i).readObj());
1776
extractPatches (img, patches, patch_size);
1777
cvReleaseImage(&img);
1782
void loadPCAFeatures(const char* path, const char* images_list, std::vector<IplImage*>& patches, CvSize patch_size)
1784
char images_filename[1024];
1785
sprintf(images_filename, "%s/%s", path, images_list);
1786
FILE *pFile = fopen(images_filename, "r");
1789
printf("Cannot open images list file %s\n", images_filename);
1792
while (!feof(pFile))
1794
char imagename[1024];
1795
if (fscanf(pFile, "%s", imagename) <= 0)
1800
char filename[1024];
1801
sprintf(filename, "%s/%s", path, imagename);
1803
//printf("Reading image %s...", filename);
1805
#ifdef HAVE_OPENCV_HIGHGUI
1806
Mat img2 = cv::imread(filename, IMREAD_GRAYSCALE);
1809
CV_Error(CV_StsNotImplemented, "OpenCV has been compiled without image I/O support");
1813
extractPatches (&img, patches, patch_size);
1818
void generatePCAFeatures(const char* path, const char* img_filename, FileStorage& fs, const char* postfix,
1819
CvSize patch_size, CvMat** avg, CvMat** eigenvectors)
1821
std::vector<IplImage*> patches;
1822
loadPCAFeatures(path, img_filename, patches, patch_size);
1823
calcPCAFeatures(patches, fs, postfix, avg, eigenvectors);
1827
void generatePCAFeatures(const FileNode &fn, const char* postfix,
1828
CvSize patch_size, CvMat** avg, CvMat** eigenvectors)
1830
std::vector<IplImage*> patches;
1831
loadPCAFeatures(fn, patches, patch_size);
1832
calcPCAFeatures(patches, fs, postfix, avg, eigenvectors);
1836
void OneWayDescriptorBase::GeneratePCA(const FileNode &fn, int pose_count)
1838
generatePCAFeatures(fn, "hr", m_patch_size, &m_pca_hr_avg, &m_pca_hr_eigenvectors);
1839
generatePCAFeatures(fn, "lr", cvSize(m_patch_size.width / 2, m_patch_size.height / 2),
1840
&m_pca_avg, &m_pca_eigenvectors);
1843
OneWayDescriptorBase descriptors(m_patch_size, pose_count);
1844
descriptors.SetPCAHigh(m_pca_hr_avg, m_pca_hr_eigenvectors);
1845
descriptors.SetPCALow(m_pca_avg, m_pca_eigenvectors);
1847
printf("Calculating %d PCA descriptors (you can grab a coffee, this will take a while)...\n",
1848
descriptors.GetPCADimHigh());
1849
descriptors.InitializePoseTransforms();
1850
descriptors.CreatePCADescriptors();
1851
descriptors.SavePCADescriptors(*fs);
1855
void OneWayDescriptorBase::GeneratePCA(const char* img_path, const char* images_list, int pose_count)
1857
char pca_filename[1024];
1858
sprintf(pca_filename, "%s/%s", img_path, GetPCAFilename().c_str());
1859
FileStorage fs = FileStorage(pca_filename, FileStorage::WRITE);
1861
generatePCAFeatures(img_path, images_list, fs, "hr", m_patch_size, &m_pca_hr_avg, &m_pca_hr_eigenvectors);
1862
generatePCAFeatures(img_path, images_list, fs, "lr", cvSize(m_patch_size.width / 2, m_patch_size.height / 2),
1863
&m_pca_avg, &m_pca_eigenvectors);
1865
OneWayDescriptorBase descriptors(m_patch_size, pose_count);
1866
descriptors.SetPCAHigh(m_pca_hr_avg, m_pca_hr_eigenvectors);
1867
descriptors.SetPCALow(m_pca_avg, m_pca_eigenvectors);
1869
printf("Calculating %d PCA descriptors (you can grab a coffee, this will take a while)...\n",
1870
descriptors.GetPCADimHigh());
1871
descriptors.InitializePoseTransforms();
1872
descriptors.CreatePCADescriptors();
1873
descriptors.SavePCADescriptors(*fs);
1878
void OneWayDescriptorBase::Write (FileStorage &fs) const
1880
fs << "poseCount" << m_pose_count;
1881
fs << "patchWidth" << m_patch_size.width;
1882
fs << "patchHeight" << m_patch_size.height;
1883
fs << "minScale" << scale_min;
1884
fs << "maxScale" << scale_max;
1885
fs << "stepScale" << scale_step;
1886
fs << "pyrLevels" << m_pyr_levels;
1887
fs << "pcaDimHigh" << m_pca_dim_high;
1888
fs << "pcaDimLow" << m_pca_dim_low;
1893
void OneWayDescriptorBase::SavePCAall (FileStorage &fs) const
1895
savePCAFeatures(fs, "hr", m_pca_hr_avg, m_pca_hr_eigenvectors);
1896
savePCAFeatures(fs, "lr", m_pca_avg, m_pca_eigenvectors);
1897
SavePCADescriptors(*fs);
1900
void OneWayDescriptorBase::SavePCADescriptors(const char* filename)
1902
CvMemStorage* storage = cvCreateMemStorage();
1903
CvFileStorage* fs = cvOpenFileStorage(filename, storage, CV_STORAGE_WRITE);
1905
SavePCADescriptors (fs);
1907
cvReleaseMemStorage(&storage);
1908
cvReleaseFileStorage(&fs);
1911
void OneWayDescriptorBase::SavePCADescriptors(CvFileStorage *fs) const
1913
cvWriteInt(fs, "pca_components_number", m_pca_dim_high);
1916
"The first component is the average Vector, so the total number of components is <pca components number> + 1",
1918
cvWriteInt(fs, "patch_width", m_patch_size.width);
1919
cvWriteInt(fs, "patch_height", m_patch_size.height);
1921
// pack the affine transforms into a single CvMat and write them
1922
CvMat* poses = cvCreateMat(m_pose_count, 4, CV_32FC1);
1923
for (int i = 0; i < m_pose_count; i++)
1925
cvmSet(poses, i, 0, m_poses[i].phi);
1926
cvmSet(poses, i, 1, m_poses[i].theta);
1927
cvmSet(poses, i, 2, m_poses[i].lambda1);
1928
cvmSet(poses, i, 3, m_poses[i].lambda2);
1930
cvWrite(fs, "affine_poses", poses);
1931
cvReleaseMat(&poses);
1933
for (int i = 0; i < m_pca_dim_high + 1; i++)
1936
sprintf(buf, "descriptor_for_pca_component_%d", i);
1937
m_pca_descriptors[i].Write(fs, buf);
1942
void OneWayDescriptorBase::Allocate(int train_feature_count)
1944
m_train_feature_count = train_feature_count;
1945
m_descriptors = new OneWayDescriptor[m_train_feature_count];
1946
for(int i = 0; i < m_train_feature_count; i++)
1948
m_descriptors[i].SetPCADimHigh(m_pca_dim_high);
1949
m_descriptors[i].SetPCADimLow(m_pca_dim_low);
1953
void OneWayDescriptorBase::InitializeDescriptors(IplImage* train_image, const std::vector<KeyPoint>& features,
1954
const char* feature_label, int desc_start_idx)
1956
for(int i = 0; i < (int)features.size(); i++)
1958
InitializeDescriptor(desc_start_idx + i, train_image, features[i], feature_label);
1961
cvResetImageROI(train_image);
1963
#if defined(_KDTREE)
1964
ConvertDescriptorsArrayToTree();
1968
void OneWayDescriptorBase::CreateDescriptorsFromImage(IplImage* src, const std::vector<KeyPoint>& features)
1970
m_train_feature_count = (int)features.size();
1972
m_descriptors = new OneWayDescriptor[m_train_feature_count];
1974
InitializeDescriptors(src, features);
1978
#if defined(_KDTREE)
1979
void OneWayDescriptorBase::ConvertDescriptorsArrayToTree()
1981
int n = this->GetDescriptorCount();
1984
int pca_dim_low = this->GetDescriptor(0)->GetPCADimLow();
1986
//if (!m_pca_descriptors_matrix)
1987
// m_pca_descriptors_matrix = new ::cvflann::Matrix<float>(n*m_pose_count,pca_dim_low);
1990
// if ((m_pca_descriptors_matrix->cols != pca_dim_low)&&(m_pca_descriptors_matrix->rows != n*m_pose_count))
1992
// delete m_pca_descriptors_matrix;
1993
// m_pca_descriptors_matrix = new ::cvflann::Matrix<float>(n*m_pose_count,pca_dim_low);
1997
m_pca_descriptors_matrix = cvCreateMat(n*m_pose_count,pca_dim_low,CV_32FC1);
1998
for (int i=0;i<n;i++)
2000
CvMat** pca_coeffs = m_descriptors[i].GetPCACoeffs();
2001
for (int j = 0;j<m_pose_count;j++)
2003
for (int k=0;k<pca_dim_low;k++)
2005
m_pca_descriptors_matrix->data.fl[(i*m_pose_count+j)*m_pca_dim_low + k] = pca_coeffs[j]->data.fl[k];
2009
cv::Mat pca_descriptors_mat(m_pca_descriptors_matrix,false);
2011
//::cvflann::KDTreeIndexParams params;
2013
//m_pca_descriptors_tree = new KDTree(pca_descriptors_mat);
2014
m_pca_descriptors_tree = new cv::flann::Index(pca_descriptors_mat,cv::flann::KDTreeIndexParams(1));
2015
//cvReleaseMat(&m_pca_descriptors_matrix);
2016
//m_pca_descriptors_tree->buildIndex();
2020
void OneWayDescriptorObject::Allocate(int train_feature_count, int object_feature_count)
2022
OneWayDescriptorBase::Allocate(train_feature_count);
2023
m_object_feature_count = object_feature_count;
2025
m_part_id = new int[m_object_feature_count];
2029
void OneWayDescriptorObject::InitializeObjectDescriptors(IplImage* train_image, const std::vector<KeyPoint>& features,
2030
const char* feature_label, int desc_start_idx, float scale, int is_background)
2032
InitializeDescriptors(train_image, features, feature_label, desc_start_idx);
2034
for(int i = 0; i < (int)features.size(); i++)
2036
CvPoint center = features[i].pt;
2040
// remember descriptor part id
2041
CvPoint center_scaled = cvPoint(round(center.x*scale), round(center.y*scale));
2042
m_part_id[i + desc_start_idx] = MatchPointToPart(center_scaled);
2045
cvResetImageROI(train_image);
2048
int OneWayDescriptorObject::IsDescriptorObject(int desc_idx) const
2050
return desc_idx < m_object_feature_count ? 1 : 0;
2053
int OneWayDescriptorObject::MatchPointToPart(CvPoint pt) const
2056
const int max_dist = 10;
2057
for(int i = 0; i < (int)m_train_features.size(); i++)
2059
if(norm(Point2f(pt) - m_train_features[i].pt) < max_dist)
2069
int OneWayDescriptorObject::GetDescriptorPart(int desc_idx) const
2071
// return MatchPointToPart(GetDescriptor(desc_idx)->GetCenter());
2072
return desc_idx < m_object_feature_count ? m_part_id[desc_idx] : -1;
2075
OneWayDescriptorObject::OneWayDescriptorObject(CvSize patch_size, int pose_count, const char* train_path,
2076
const char* pca_config, const char* pca_hr_config, const char* pca_desc_config, int pyr_levels) :
2077
OneWayDescriptorBase(patch_size, pose_count, train_path, pca_config, pca_hr_config, pca_desc_config, pyr_levels)
2082
OneWayDescriptorObject::OneWayDescriptorObject(CvSize patch_size, int pose_count, const String &pca_filename,
2083
const String &train_path, const String &images_list, float _scale_min, float _scale_max, float _scale_step, int pyr_levels) :
2084
OneWayDescriptorBase(patch_size, pose_count, pca_filename, train_path, images_list, _scale_min, _scale_max, _scale_step, pyr_levels)
2089
OneWayDescriptorObject::~OneWayDescriptorObject()
2095
std::vector<KeyPoint> OneWayDescriptorObject::_GetLabeledFeatures() const
2097
std::vector<KeyPoint> features;
2098
for(size_t i = 0; i < m_train_features.size(); i++)
2100
features.push_back(m_train_features[i]);
2106
void eigenvector2image(CvMat* eigenvector, IplImage* img)
2108
CvRect roi = cvGetImageROI(img);
2109
if(img->depth == 32)
2111
for(int y = 0; y < roi.height; y++)
2113
for(int x = 0; x < roi.width; x++)
2115
float val = (float)cvmGet(eigenvector, 0, roi.width*y + x);
2116
*((float*)(img->imageData + (roi.y + y)*img->widthStep) + roi.x + x) = val;
2122
for(int y = 0; y < roi.height; y++)
2124
for(int x = 0; x < roi.width; x++)
2126
float val = (float)cvmGet(eigenvector, 0, roi.width*y + x);
2127
img->imageData[(roi.y + y)*img->widthStep + roi.x + x] = (unsigned char)val;
2133
void readPCAFeatures(const char* filename, CvMat** avg, CvMat** eigenvectors, const char* postfix)
2135
FileStorage fs = FileStorage(filename, FileStorage::READ);
2136
if (!fs.isOpened ())
2138
printf("Cannot open file %s! Exiting!", filename);
2141
readPCAFeatures (fs.root (), avg, eigenvectors, postfix);
2145
void readPCAFeatures(const FileNode &fn, CvMat** avg, CvMat** eigenvectors, const char* postfix)
2147
String str = String ("avg") + postfix;
2148
CvMat* _avg = reinterpret_cast<CvMat*> (fn[str].readObj());
2151
*avg = cvCloneMat(_avg);
2152
cvReleaseMat(&_avg);
2155
str = String ("eigenvectors") + postfix;
2156
CvMat* _eigenvectors = reinterpret_cast<CvMat*> (fn[str].readObj());
2157
if (_eigenvectors != 0)
2159
*eigenvectors = cvCloneMat(_eigenvectors);
2160
cvReleaseMat(&_eigenvectors);
2164
/****************************************************************************************\
2165
* OneWayDescriptorMatcher *
2166
\****************************************************************************************/
2168
OneWayDescriptorMatcher::Params::Params( int _poseCount, Size _patchSize, String _pcaFilename,
2169
String _trainPath, String _trainImagesList,
2170
float _minScale, float _maxScale, float _stepScale ) :
2171
poseCount(_poseCount), patchSize(_patchSize), pcaFilename(_pcaFilename),
2172
trainPath(_trainPath), trainImagesList(_trainImagesList),
2173
minScale(_minScale), maxScale(_maxScale), stepScale(_stepScale)
2177
OneWayDescriptorMatcher::OneWayDescriptorMatcher( const Params& _params)
2179
initialize(_params);
2182
OneWayDescriptorMatcher::~OneWayDescriptorMatcher()
2185
void OneWayDescriptorMatcher::initialize( const Params& _params, const Ptr<OneWayDescriptorBase>& _base )
2195
void OneWayDescriptorMatcher::clear()
2197
GenericDescriptorMatcher::clear();
2204
void OneWayDescriptorMatcher::train()
2206
if( !base || prevTrainCount < (int)trainPointCollection.keypointCount() )
2209
new OneWayDescriptorObject( params.patchSize, params.poseCount, params.pcaFilename,
2210
params.trainPath, params.trainImagesList, params.minScale, params.maxScale, params.stepScale ));
2212
base->Allocate( (int)trainPointCollection.keypointCount() );
2213
prevTrainCount = (int)trainPointCollection.keypointCount();
2215
const std::vector<std::vector<KeyPoint> >& points = trainPointCollection.getKeypoints();
2217
for( size_t i = 0; i < points.size(); i++ )
2219
IplImage _image = trainPointCollection.getImage((int)i);
2220
for( size_t j = 0; j < points[i].size(); j++ )
2221
base->InitializeDescriptor( count++, &_image, points[i][j], "" );
2224
#if defined(_KDTREE)
2225
base->ConvertDescriptorsArrayToTree();
2230
bool OneWayDescriptorMatcher::isMaskSupported()
2235
void OneWayDescriptorMatcher::knnMatchImpl( InputArray _queryImage, std::vector<KeyPoint>& queryKeypoints,
2236
std::vector<std::vector<DMatch> >& matches, int knn,
2237
InputArrayOfArrays /*masks*/, bool /*compactResult*/ )
2239
Mat queryImage = _queryImage.getMat();
2242
CV_Assert( knn == 1 ); // knn > 1 unsupported because of bug in OneWayDescriptorBase for this case
2244
matches.resize( queryKeypoints.size() );
2245
IplImage _qimage = queryImage;
2246
for( size_t i = 0; i < queryKeypoints.size(); i++ )
2248
int descIdx = -1, poseIdx = -1;
2250
base->FindDescriptor( &_qimage, queryKeypoints[i].pt, descIdx, poseIdx, distance );
2251
matches[i].push_back( DMatch((int)i, descIdx, distance) );
2255
void OneWayDescriptorMatcher::radiusMatchImpl( InputArray _queryImage, std::vector<KeyPoint>& queryKeypoints,
2256
std::vector<std::vector<DMatch> >& matches, float maxDistance,
2257
InputArrayOfArrays /*masks*/, bool /*compactResult*/ )
2259
Mat queryImage = _queryImage.getMat();
2263
matches.resize( queryKeypoints.size() );
2264
IplImage _qimage = queryImage;
2265
for( size_t i = 0; i < queryKeypoints.size(); i++ )
2267
int descIdx = -1, poseIdx = -1;
2269
base->FindDescriptor( &_qimage, queryKeypoints[i].pt, descIdx, poseIdx, distance );
2270
if( distance < maxDistance )
2271
matches[i].push_back( DMatch((int)i, descIdx, distance) );
2275
void OneWayDescriptorMatcher::read( const FileNode &fn )
2278
new OneWayDescriptorObject( params.patchSize, params.poseCount, String (), String (), String (),
2279
params.minScale, params.maxScale, params.stepScale ));
2283
void OneWayDescriptorMatcher::write( FileStorage& fs ) const
2288
bool OneWayDescriptorMatcher::empty() const
2290
return !base || base->empty();
2293
Ptr<GenericDescriptorMatcher> OneWayDescriptorMatcher::clone( bool emptyTrainData ) const
2295
Ptr<OneWayDescriptorMatcher> matcher = makePtr<OneWayDescriptorMatcher>( params );
2297
if( !emptyTrainData )
2299
CV_Error( CV_StsNotImplemented, "deep clone functionality is not implemented, because "
2300
"OneWayDescriptorBase has not copy constructor or clone method ");
2303
matcher->params = params;
2304
matcher->prevTrainCount = prevTrainCount;
2305
matcher->trainPointCollection = trainPointCollection;