00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 static const float pi = 3.1415926;
00012
00013 #include <stdio.h>
00014
00015 #include <outlet_pose_estimation/detail/one_way_descriptor.h>
00016
00017 #include <highgui.h>
00018
00019 static inline CvPoint rect_center(CvRect rect)
00020 {
00021 return cvPoint(rect.x + rect.width/2, rect.y + rect.height/2);
00022 }
00023
00024 void homography_transform(IplImage* frontal, IplImage* result, CvMat* homography)
00025 {
00026 cvWarpPerspective(frontal, result, homography);
00027 }
00028
00029 CvAffinePose perturbate_pose(CvAffinePose pose, float noise)
00030 {
00031
00032 float noise_mult_factor = 1 + (0.5f - float(rand())/RAND_MAX)*noise;
00033 float noise_add_factor = noise_mult_factor - 1;
00034
00035 CvAffinePose pose_pert = pose;
00036 pose_pert.phi += noise_add_factor;
00037 pose_pert.theta += noise_mult_factor;
00038 pose_pert.lambda1 *= noise_mult_factor;
00039 pose_pert.lambda2 *= noise_mult_factor;
00040
00041 return pose_pert;
00042 }
00043
00044 void generate_mean_patch(IplImage* frontal, IplImage* result, CvAffinePose pose, int pose_count, float noise)
00045 {
00046 IplImage* sum = cvCreateImage(cvSize(result->width, result->height), IPL_DEPTH_32F, 1);
00047 IplImage* workspace = cvCloneImage(result);
00048 IplImage* workspace_float = cvCloneImage(sum);
00049
00050 cvSetZero(sum);
00051 for(int i = 0; i < pose_count; i++)
00052 {
00053 CvAffinePose pose_pert = perturbate_pose(pose, noise);
00054
00055 AffineTransformPatch(frontal, workspace, pose_pert);
00056 cvConvertScale(workspace, workspace_float);
00057 cvAdd(sum, workspace_float, sum);
00058 }
00059
00060 cvConvertScale(sum, result, 1.0f/pose_count);
00061
00062 cvReleaseImage(&workspace);
00063 cvReleaseImage(&sum);
00064 cvReleaseImage(&workspace_float);
00065 }
00066
00067 void generate_mean_patch_fast(IplImage* frontal, IplImage* result, CvAffinePose pose,
00068 CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, const CvOneWayDescriptor* pca_descriptors)
00069 {
00070 for(int i = 0; i < pca_hr_eigenvectors->cols; i++)
00071 {
00072
00073 }
00074 }
00075
00076
00077 CvOneWayDescriptor::CvOneWayDescriptor()
00078 {
00079 m_pose_count = 0;
00080 m_samples = 0;
00081 m_input_patch = 0;
00082 m_train_patch = 0;
00083 m_pca_coeffs = 0;
00084 m_affine_poses = 0;
00085 m_transforms = 0;
00086 m_pca_dim_low = 100;
00087 m_pca_dim_high = 100;
00088 }
00089
00090 CvOneWayDescriptor::~CvOneWayDescriptor()
00091 {
00092 if(m_pose_count)
00093 {
00094 for(int i = 0; i < m_pose_count; i++)
00095 {
00096 cvReleaseImage(&m_samples[i]);
00097 cvReleaseMat(&m_pca_coeffs[i]);
00098 }
00099 cvReleaseImage(&m_input_patch);
00100 cvReleaseImage(&m_train_patch);
00101 delete []m_samples;
00102 delete []m_pca_coeffs;
00103
00104 if(!m_transforms)
00105 {
00106 delete []m_affine_poses;
00107 }
00108 }
00109 }
00110
00111 void CvOneWayDescriptor::Allocate(int pose_count, CvSize size, int nChannels)
00112 {
00113 m_pose_count = pose_count;
00114 m_samples = new IplImage* [m_pose_count];
00115 m_pca_coeffs = new CvMat* [m_pose_count];
00116 m_patch_size = cvSize(size.width/2, size.height/2);
00117
00118 if(!m_transforms)
00119 {
00120 m_affine_poses = new CvAffinePose[m_pose_count];
00121 }
00122
00123 int length = m_pca_dim_low;
00124 for(int i = 0; i < m_pose_count; i++)
00125 {
00126 m_samples[i] = cvCreateImage(cvSize(size.width/2, size.height/2), IPL_DEPTH_32F, nChannels);
00127 m_pca_coeffs[i] = cvCreateMat(1, length, CV_32FC1);
00128 }
00129
00130 m_input_patch = cvCreateImage(GetPatchSize(), IPL_DEPTH_8U, 1);
00131 m_train_patch = cvCreateImage(GetInputPatchSize(), IPL_DEPTH_8U, 1);
00132 }
00133
00134 void cvmSet2DPoint(CvMat* matrix, int row, int col, CvPoint2D32f point)
00135 {
00136 cvmSet(matrix, row, col, point.x);
00137 cvmSet(matrix, row, col + 1, point.y);
00138 }
00139
00140 void cvmSet3DPoint(CvMat* matrix, int row, int col, CvPoint3D32f point)
00141 {
00142 cvmSet(matrix, row, col, point.x);
00143 cvmSet(matrix, row, col + 1, point.y);
00144 cvmSet(matrix, row, col + 2, point.z);
00145 }
00146
00147 CvAffinePose GenRandomAffinePose()
00148 {
00149 const float scale_min = 0.8f;
00150 const float scale_max = 1.2f;
00151 CvAffinePose pose;
00152 pose.theta = float(rand())/RAND_MAX*120 - 60;
00153 pose.phi = float(rand())/RAND_MAX*360;
00154 pose.lambda1 = scale_min + float(rand())/RAND_MAX*(scale_max - scale_min);
00155 pose.lambda2 = scale_min + float(rand())/RAND_MAX*(scale_max - scale_min);
00156
00157 return pose;
00158 }
00159
00160 void GenerateAffineTransformFromPose(CvSize size, CvAffinePose pose, CvMat* transform)
00161 {
00162 CvMat* temp = cvCreateMat(3, 3, CV_32FC1);
00163 CvMat* final = cvCreateMat(3, 3, CV_32FC1);
00164 cvmSet(temp, 2, 0, 0.0f);
00165 cvmSet(temp, 2, 1, 0.0f);
00166 cvmSet(temp, 2, 2, 1.0f);
00167
00168 CvMat rotation;
00169 cvGetSubRect(temp, &rotation, cvRect(0, 0, 3, 2));
00170
00171 cv2DRotationMatrix(cvPoint2D32f(size.width/2, size.height/2), pose.phi, 1.0, &rotation);
00172 cvCopy(temp, final);
00173
00174 cvmSet(temp, 0, 0, pose.lambda1);
00175 cvmSet(temp, 0, 1, 0.0f);
00176 cvmSet(temp, 1, 0, 0.0f);
00177 cvmSet(temp, 1, 1, pose.lambda2);
00178 cvmSet(temp, 0, 2, size.width/2*(1 - pose.lambda1));
00179 cvmSet(temp, 1, 2, size.height/2*(1 - pose.lambda2));
00180 cvMatMul(temp, final, final);
00181
00182 cv2DRotationMatrix(cvPoint2D32f(size.width/2, size.height/2), pose.theta - pose.phi, 1.0, &rotation);
00183 cvMatMul(temp, final, final);
00184
00185 cvGetSubRect(final, &rotation, cvRect(0, 0, 3, 2));
00186 cvCopy(&rotation, transform);
00187
00188 cvReleaseMat(&temp);
00189 cvReleaseMat(&final);
00190 }
00191
00192 void AffineTransformPatch(IplImage* src, IplImage* dst, CvAffinePose pose)
00193 {
00194 CvRect src_large_roi = cvGetImageROI(src);
00195
00196 IplImage* temp = cvCreateImage(cvSize(src_large_roi.width, src_large_roi.height), IPL_DEPTH_32F, src->nChannels);
00197 cvSetZero(temp);
00198 IplImage* temp2 = cvCloneImage(temp);
00199 CvMat* rotation_phi = cvCreateMat(2, 3, CV_32FC1);
00200
00201 CvSize new_size = cvSize(temp->width*pose.lambda1, temp->height*pose.lambda2);
00202 IplImage* temp3 = cvCreateImage(new_size, IPL_DEPTH_32F, src->nChannels);
00203
00204 cvConvertScale(src, temp);
00205 cvResetImageROI(temp);
00206
00207
00208 cv2DRotationMatrix(cvPoint2D32f(temp->width/2, temp->height/2), pose.phi, 1.0, rotation_phi);
00209 cvWarpAffine(temp, temp2, rotation_phi);
00210
00211 cvSetZero(temp);
00212
00213 cvResize(temp2, temp3);
00214
00215 cv2DRotationMatrix(cvPoint2D32f(temp3->width/2, temp3->height/2), pose.theta - pose.phi, 1.0, rotation_phi);
00216 cvWarpAffine(temp3, temp, rotation_phi);
00217
00218 cvSetImageROI(temp, cvRect(temp->width/2 - src_large_roi.width/4, temp->height/2 - src_large_roi.height/4,
00219 src_large_roi.width/2, src_large_roi.height/2));
00220 cvConvertScale(temp, dst);
00221 cvReleaseMat(&rotation_phi);
00222
00223 cvReleaseImage(&temp3);
00224 cvReleaseImage(&temp2);
00225 cvReleaseImage(&temp);
00226 }
00227
00228 void CvOneWayDescriptor::GenerateSamples(int pose_count, IplImage* frontal, int norm)
00229 {
00230
00231
00232
00233
00234
00235
00236 CvRect roi = cvGetImageROI(frontal);
00237 IplImage* patch_8u = cvCreateImage(cvSize(roi.width/2, roi.height/2), frontal->depth, frontal->nChannels);
00238 for(int i = 0; i < pose_count; i++)
00239 {
00240 if(!m_transforms)
00241 {
00242 m_affine_poses[i] = GenRandomAffinePose();
00243 }
00244
00245 generate_mean_patch(frontal, patch_8u, m_affine_poses[i], num_mean_components, noise_intensity);
00246
00247 float scale = 1.0f;
00248 if(norm)
00249 {
00250 float sum = cvSum(patch_8u).val[0];
00251 scale = 1/sum;
00252 }
00253 cvConvertScale(patch_8u, m_samples[i], scale);
00254
00255 #if 0
00256 double maxval;
00257 cvMinMaxLoc(m_samples[i], 0, &maxval);
00258 IplImage* test = cvCreateImage(cvSize(roi.width/2, roi.height/2), IPL_DEPTH_8U, 1);
00259 cvConvertScale(m_samples[i], test, 255.0/maxval);
00260 cvNamedWindow("1", 1);
00261 cvShowImage("1", test);
00262 cvWaitKey(0);
00263 #endif
00264 }
00265 cvReleaseImage(&patch_8u);
00266 }
00267
00268 void CvOneWayDescriptor::GenerateSamplesFast(IplImage* frontal, CvMat* pca_hr_avg,
00269 CvMat* pca_hr_eigenvectors, CvOneWayDescriptor* pca_descriptors)
00270 {
00271 CvRect roi = cvGetImageROI(frontal);
00272 if(roi.width != GetInputPatchSize().width || roi.height != GetInputPatchSize().height)
00273 {
00274 cvResize(frontal, m_train_patch);
00275 frontal = m_train_patch;
00276 }
00277
00278 CvMat* pca_coeffs = cvCreateMat(1, pca_hr_eigenvectors->cols, CV_32FC1);
00279 double maxval;
00280 cvMinMaxLoc(frontal, 0, &maxval);
00281 CvMat* frontal_data = ConvertImageToMatrix(frontal);
00282
00283 float sum = cvSum(frontal_data).val[0];
00284 cvConvertScale(frontal_data, frontal_data, 1.0f/sum);
00285 cvProjectPCA(frontal_data, pca_hr_avg, pca_hr_eigenvectors, pca_coeffs);
00286 for(int i = 0; i < m_pose_count; i++)
00287 {
00288 cvSetZero(m_samples[i]);
00289 for(int j = 0; j < m_pca_dim_high; j++)
00290 {
00291 float coeff = cvmGet(pca_coeffs, 0, j);
00292 IplImage* patch = pca_descriptors[j + 1].GetPatch(i);
00293 cvAddWeighted(m_samples[i], 1.0, patch, coeff, 0, m_samples[i]);
00294
00295 #if 0
00296 printf("coeff%d = %f\n", j, coeff);
00297 IplImage* test = cvCreateImage(cvSize(12, 12), IPL_DEPTH_8U, 1);
00298 double maxval;
00299 cvMinMaxLoc(patch, 0, &maxval);
00300 cvConvertScale(patch, test, 255.0/maxval);
00301 cvNamedWindow("1", 1);
00302 cvShowImage("1", test);
00303 cvWaitKey(0);
00304 #endif
00305 }
00306
00307 cvAdd(pca_descriptors[0].GetPatch(i), m_samples[i], m_samples[i]);
00308 float sum = cvSum(m_samples[i]).val[0];
00309 cvConvertScale(m_samples[i], m_samples[i], 1.0/sum);
00310
00311 #if 0
00312 IplImage* test = cvCreateImage(cvSize(12, 12), IPL_DEPTH_8U, 1);
00313
00314
00315
00316
00317
00318
00319 cvMinMaxLoc(m_samples[i], 0, &maxval);
00320 cvConvertScale(m_samples[i], test, 255.0/maxval);
00321
00322 cvNamedWindow("1", 1);
00323 cvShowImage("1", frontal);
00324 cvNamedWindow("2", 1);
00325 cvShowImage("2", test);
00326 cvWaitKey(0);
00327 #endif
00328 }
00329
00330 cvReleaseMat(&pca_coeffs);
00331 cvReleaseMat(&frontal_data);
00332 }
00333
00334 void CvOneWayDescriptor::SetTransforms(CvAffinePose* poses, CvMat** transforms)
00335 {
00336 if(m_affine_poses)
00337 {
00338 delete []m_affine_poses;
00339 }
00340
00341 m_affine_poses = poses;
00342 m_transforms = transforms;
00343 }
00344
00345 void CvOneWayDescriptor::Initialize(int pose_count, IplImage* frontal, const char* feature_name, int norm)
00346 {
00347 m_feature_name = std::string(feature_name);
00348 CvRect roi = cvGetImageROI(frontal);
00349 m_center = rect_center(roi);
00350
00351 Allocate(pose_count, cvSize(roi.width, roi.height), frontal->nChannels);
00352
00353 GenerateSamples(pose_count, frontal, norm);
00354 }
00355
00356 void CvOneWayDescriptor::InitializeFast(int pose_count, IplImage* frontal, const char* feature_name,
00357 CvMat* pca_hr_avg, CvMat* pca_hr_eigenvectors, CvOneWayDescriptor* pca_descriptors)
00358 {
00359 if(pca_hr_avg == 0)
00360 {
00361 Initialize(pose_count, frontal, feature_name, 1);
00362 return;
00363 }
00364 m_feature_name = std::string(feature_name);
00365 CvRect roi = cvGetImageROI(frontal);
00366 m_center = rect_center(roi);
00367
00368 Allocate(pose_count, cvSize(roi.width, roi.height), frontal->nChannels);
00369
00370 GenerateSamplesFast(frontal, pca_hr_avg, pca_hr_eigenvectors, pca_descriptors);
00371 }
00372
00373 void CvOneWayDescriptor::InitializePCACoeffs(CvMat* avg, CvMat* eigenvectors)
00374 {
00375 for(int i = 0; i < m_pose_count; i++)
00376 {
00377 ProjectPCASample(m_samples[i], avg, eigenvectors, m_pca_coeffs[i]);
00378 }
00379 }
00380
00381 void CvOneWayDescriptor::ProjectPCASample(IplImage* patch, CvMat* avg, CvMat* eigenvectors, CvMat* pca_coeffs) const
00382 {
00383 CvMat* patch_mat = ConvertImageToMatrix(patch);
00384
00385
00386 CvMat* temp = cvCreateMat(1, eigenvectors->cols, CV_32FC1);
00387 cvProjectPCA(patch_mat, avg, eigenvectors, temp);
00388 CvMat temp1;
00389 cvGetSubRect(temp, &temp1, cvRect(0, 0, pca_coeffs->cols, 1));
00390 cvCopy(&temp1, pca_coeffs);
00391
00392 cvReleaseMat(&temp);
00393 cvReleaseMat(&patch_mat);
00394 }
00395
00396 void CvOneWayDescriptor::EstimatePosePCA(CvArr* patch, int& pose_idx, float& distance, CvMat* avg, CvMat* eigenvectors) const
00397 {
00398 if(avg == 0)
00399 {
00400
00401 if (!CV_IS_MAT(patch))
00402 {
00403 EstimatePose((IplImage*)patch, pose_idx, distance);
00404 }
00405 else
00406 {
00407
00408 }
00409 return;
00410 }
00411 CvRect roi;
00412 if (!CV_IS_MAT(patch))
00413 {
00414 roi = cvGetImageROI((IplImage*)patch);
00415 if(roi.width != GetPatchSize().width || roi.height != GetPatchSize().height)
00416 {
00417 cvResize(patch, m_input_patch);
00418 patch = m_input_patch;
00419 roi = cvGetImageROI((IplImage*)patch);
00420 }
00421 }
00422
00423 CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);
00424
00425 if (CV_IS_MAT(patch))
00426 {
00427 cvCopy((CvMat*)patch, pca_coeffs);
00428 }
00429 else
00430 {
00431 IplImage* patch_32f = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_32F, 1);
00432 float sum = cvSum(patch).val[0];
00433 cvConvertScale(patch, patch_32f, 1.0f/sum);
00434 ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs);
00435 cvReleaseImage(&patch_32f);
00436 }
00437
00438
00439 distance = 1e10;
00440 pose_idx = -1;
00441
00442 for(int i = 0; i < m_pose_count; i++)
00443 {
00444 float dist = cvNorm(m_pca_coeffs[i], pca_coeffs);
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473 if(dist < distance)
00474 {
00475 distance = dist;
00476 pose_idx = i;
00477 }
00478 }
00479
00480 cvReleaseMat(&pca_coeffs);
00481 }
00482
00483 void CvOneWayDescriptor::EstimatePose(IplImage* patch, int& pose_idx, float& distance) const
00484 {
00485 distance = 1e10;
00486 pose_idx = -1;
00487
00488 CvRect roi = cvGetImageROI(patch);
00489 IplImage* patch_32f = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_32F, patch->nChannels);
00490 float sum = cvSum(patch).val[0];
00491 cvConvertScale(patch, patch_32f, 1/sum);
00492
00493 for(int i = 0; i < m_pose_count; i++)
00494 {
00495 if(m_samples[i]->width != patch_32f->width || m_samples[i]->height != patch_32f->height)
00496 {
00497 continue;
00498 }
00499 float dist = cvNorm(m_samples[i], patch_32f);
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 if(dist < distance)
00512 {
00513 distance = dist;
00514 pose_idx = i;
00515 }
00516
00517 #if 0
00518 IplImage* img1 = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_8U, 1);
00519 IplImage* img2 = cvCreateImage(cvSize(roi.width, roi.height), IPL_DEPTH_8U, 1);
00520 double maxval;
00521 cvMinMaxLoc(m_samples[i], 0, &maxval);
00522 cvConvertScale(m_samples[i], img1, 255.0/maxval);
00523 cvMinMaxLoc(patch_32f, 0, &maxval);
00524 cvConvertScale(patch_32f, img2, 255.0/maxval);
00525
00526 cvNamedWindow("1", 1);
00527 cvShowImage("1", img1);
00528 cvNamedWindow("2", 1);
00529 cvShowImage("2", img2);
00530 printf("Distance = %f\n", dist);
00531 cvWaitKey(0);
00532 #endif
00533 }
00534
00535 cvReleaseImage(&patch_32f);
00536 }
00537
00538 void CvOneWayDescriptor::Save(const char* path)
00539 {
00540 for(int i = 0; i < m_pose_count; i++)
00541 {
00542 char buf[1024];
00543 sprintf(buf, "%s/patch_%04d.jpg", path, i);
00544 IplImage* patch = cvCreateImage(cvSize(m_samples[i]->width, m_samples[i]->height), IPL_DEPTH_8U, m_samples[i]->nChannels);
00545
00546 double maxval;
00547 cvMinMaxLoc(m_samples[i], 0, &maxval);
00548 cvConvertScale(m_samples[i], patch, 255/maxval);
00549
00550 cvSaveImage(buf, patch);
00551
00552 cvReleaseImage(&patch);
00553 }
00554 }
00555
00556 void CvOneWayDescriptor::Write(CvFileStorage* fs, const char* name)
00557 {
00558 CvMat* mat = cvCreateMat(m_pose_count, m_samples[0]->width*m_samples[0]->height, CV_32FC1);
00559
00560
00561 for(int i = 0; i < m_pose_count; i++)
00562 {
00563 for(int y = 0; y < m_samples[i]->height; y++)
00564 {
00565 for(int x = 0; x < m_samples[i]->width; x++)
00566 {
00567 float val = *((float*)(m_samples[i]->imageData + m_samples[i]->widthStep*y) + x);
00568 cvmSet(mat, i, y*m_samples[i]->width + x, val);
00569 }
00570 }
00571 }
00572
00573 cvWrite(fs, name, mat);
00574
00575 cvReleaseMat(&mat);
00576 }
00577
00578 int CvOneWayDescriptor::ReadByName(CvFileStorage* fs, CvFileNode* parent, const char* name)
00579 {
00580 CvMat* mat = (CvMat*)cvReadByName(fs, parent, name);
00581 if(!mat)
00582 {
00583 return 0;
00584 }
00585
00586
00587 for(int i = 0; i < m_pose_count; i++)
00588 {
00589 for(int y = 0; y < m_samples[i]->height; y++)
00590 {
00591 for(int x = 0; x < m_samples[i]->width; x++)
00592 {
00593 float val = cvmGet(mat, i, y*m_samples[i]->width + x);
00594 *((float*)(m_samples[i]->imageData + y*m_samples[i]->widthStep) + x) = val;
00595 }
00596 }
00597 }
00598
00599 cvReleaseMat(&mat);
00600 return 1;
00601 }
00602
00603 IplImage* CvOneWayDescriptor::GetPatch(int index)
00604 {
00605 return m_samples[index];
00606 }
00607
00608 CvAffinePose CvOneWayDescriptor::GetPose(int index) const
00609 {
00610 return m_affine_poses[index];
00611 }
00612
00613 void FindOneWayDescriptor(int desc_count, const CvOneWayDescriptor* descriptors, IplImage* patch, int& desc_idx, int& pose_idx, float& distance,
00614 CvMat* avg, CvMat* eigenvectors)
00615 {
00616 desc_idx = -1;
00617 pose_idx = -1;
00618 distance = 1e10;
00619
00620
00621 int m_pca_dim_low = descriptors[0].GetPCADimLow();
00622 CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);
00623 int patch_width = descriptors[0].GetPatchSize().width;
00624 int patch_height = descriptors[0].GetPatchSize().height;
00625 if (avg)
00626 {
00627 CvRect _roi = cvGetImageROI((IplImage*)patch);
00628 IplImage* test_img = cvCreateImage(cvSize(patch_width,patch_height), IPL_DEPTH_8U, 1);
00629 if(_roi.width != patch_width|| _roi.height != patch_height)
00630 {
00631
00632 cvResize(patch, test_img);
00633 _roi = cvGetImageROI(test_img);
00634 }
00635 else
00636 {
00637 cvCopy(patch,test_img);
00638 }
00639 IplImage* patch_32f = cvCreateImage(cvSize(_roi.width, _roi.height), IPL_DEPTH_32F, 1);
00640 float sum = cvSum(test_img).val[0];
00641 cvConvertScale(test_img, patch_32f, 1.0f/sum);
00642
00643
00644
00645 CvMat* patch_mat = ConvertImageToMatrix(patch_32f);
00646 CvMat* temp = cvCreateMat(1, eigenvectors->cols, CV_32FC1);
00647 cvProjectPCA(patch_mat, avg, eigenvectors, temp);
00648 CvMat temp1;
00649 cvGetSubRect(temp, &temp1, cvRect(0, 0, pca_coeffs->cols, 1));
00650 cvCopy(&temp1, pca_coeffs);
00651 cvReleaseMat(&temp);
00652 cvReleaseMat(&patch_mat);
00653
00654
00655 cvReleaseImage(&patch_32f);
00656 cvReleaseImage(&test_img);
00657 }
00658
00659
00660
00661
00662
00663 for(int i = 0; i < desc_count; i++)
00664 {
00665 int _pose_idx = -1;
00666 float _distance = 0;
00667
00668 #if 0
00669 descriptors[i].EstimatePose(patch, _pose_idx, _distance);
00670 #else
00671 if (!avg)
00672 {
00673 descriptors[i].EstimatePosePCA(patch, _pose_idx, _distance, avg, eigenvectors);
00674 }
00675 else
00676 {
00677 descriptors[i].EstimatePosePCA(pca_coeffs, _pose_idx, _distance, avg, eigenvectors);
00678 }
00679 #endif
00680
00681 if(_distance < distance)
00682 {
00683 desc_idx = i;
00684 pose_idx = _pose_idx;
00685 distance = _distance;
00686 }
00687 }
00688 cvReleaseMat(&pca_coeffs);
00689 }
00690
00691 #if defined(_KDTREE)
00692
00693 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,
00694 CvMat* avg, CvMat* eigenvectors)
00695 {
00696 desc_idx = -1;
00697 pose_idx = -1;
00698 distance = 1e10;
00699
00700
00701 CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);
00702 int patch_width = patch_size.width;
00703 int patch_height = patch_size.height;
00704
00705
00706 CvRect _roi = cvGetImageROI((IplImage*)patch);
00707 IplImage* test_img = cvCreateImage(cvSize(patch_width,patch_height), IPL_DEPTH_8U, 1);
00708 if(_roi.width != patch_width|| _roi.height != patch_height)
00709 {
00710
00711 cvResize(patch, test_img);
00712 _roi = cvGetImageROI(test_img);
00713 }
00714 else
00715 {
00716 cvCopy(patch,test_img);
00717 }
00718 IplImage* patch_32f = cvCreateImage(cvSize(_roi.width, _roi.height), IPL_DEPTH_32F, 1);
00719 float sum = cvSum(test_img).val[0];
00720 cvConvertScale(test_img, patch_32f, 1.0f/sum);
00721
00722
00723
00724 CvMat* patch_mat = ConvertImageToMatrix(patch_32f);
00725 CvMat* temp = cvCreateMat(1, eigenvectors->cols, CV_32FC1);
00726 cvProjectPCA(patch_mat, avg, eigenvectors, temp);
00727 CvMat temp1;
00728 cvGetSubRect(temp, &temp1, cvRect(0, 0, pca_coeffs->cols, 1));
00729 cvCopy(&temp1, pca_coeffs);
00730 cvReleaseMat(&temp);
00731 cvReleaseMat(&patch_mat);
00732
00733
00734 cvReleaseImage(&patch_32f);
00735 cvReleaseImage(&test_img);
00736
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754
00755
00756
00757
00758 cv::Mat m_object(1, m_pca_dim_low, CV_32F);
00759 cv::Mat m_indices(1, 1, CV_32S);
00760 cv::Mat m_dists(1, 1, CV_32F);
00761
00762 float* object_ptr = m_object.ptr<float>(0);
00763 for (int i=0;i<m_pca_dim_low;i++)
00764 {
00765 object_ptr[i] = pca_coeffs->data.fl[i];
00766 }
00767
00768 m_pca_descriptors_tree->knnSearch(m_object, m_indices, m_dists, 1, cv::flann::SearchParams(-1) );
00769
00770 desc_idx = ((int*)(m_indices.ptr<int>(0)))[0] / m_pose_count;
00771 pose_idx = ((int*)(m_indices.ptr<int>(0)))[0] % m_pose_count;
00772 distance = ((float*)(m_dists.ptr<float>(0)))[0];
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801
00802 cvReleaseMat(&pca_coeffs);
00803 }
00804 #endif
00805
00806 void FindOneWayDescriptor(int desc_count, const CvOneWayDescriptor* descriptors, IplImage* patch, int n,
00807 std::vector<int>& desc_idxs, std::vector<int>& pose_idxs, std::vector<float>& distances,
00808 CvMat* avg, CvMat* eigenvectors)
00809 {
00810 for (int i=0;i<n;i++)
00811 {
00812 desc_idxs[i] = -1;
00813 pose_idxs[i] = -1;
00814 distances[i] = 1e10;
00815 }
00816
00817
00818 int m_pca_dim_low = descriptors[0].GetPCADimLow();
00819 CvMat* pca_coeffs = cvCreateMat(1, m_pca_dim_low, CV_32FC1);
00820 int patch_width = descriptors[0].GetPatchSize().width;
00821 int patch_height = descriptors[0].GetPatchSize().height;
00822 if (avg)
00823 {
00824 CvRect _roi = cvGetImageROI((IplImage*)patch);
00825 IplImage* test_img = cvCreateImage(cvSize(patch_width,patch_height), IPL_DEPTH_8U, 1);
00826 if(_roi.width != patch_width|| _roi.height != patch_height)
00827 {
00828
00829 cvResize(patch, test_img);
00830 _roi = cvGetImageROI(test_img);
00831 }
00832 else
00833 {
00834 cvCopy(patch,test_img);
00835 }
00836 IplImage* patch_32f = cvCreateImage(cvSize(_roi.width, _roi.height), IPL_DEPTH_32F, 1);
00837 float sum = cvSum(test_img).val[0];
00838 cvConvertScale(test_img, patch_32f, 1.0f/sum);
00839
00840
00841
00842 CvMat* patch_mat = ConvertImageToMatrix(patch_32f);
00843 CvMat* temp = cvCreateMat(1, eigenvectors->cols, CV_32FC1);
00844 cvProjectPCA(patch_mat, avg, eigenvectors, temp);
00845 CvMat temp1;
00846 cvGetSubRect(temp, &temp1, cvRect(0, 0, pca_coeffs->cols, 1));
00847 cvCopy(&temp1, pca_coeffs);
00848 cvReleaseMat(&temp);
00849 cvReleaseMat(&patch_mat);
00850
00851
00852 cvReleaseImage(&patch_32f);
00853 cvReleaseImage(&test_img);
00854 }
00855
00856
00857
00858
00859 for(int i = 0; i < desc_count; i++)
00860 {
00861 int _pose_idx = -1;
00862 float _distance = 0;
00863
00864 #if 0
00865 descriptors[i].EstimatePose(patch, _pose_idx, _distance);
00866 #else
00867 if (!avg)
00868 {
00869 descriptors[i].EstimatePosePCA(patch, _pose_idx, _distance, avg, eigenvectors);
00870 }
00871 else
00872 {
00873 descriptors[i].EstimatePosePCA(pca_coeffs, _pose_idx, _distance, avg, eigenvectors);
00874 }
00875 #endif
00876
00877 for (int j=0;j<n;j++)
00878 {
00879 if(_distance < distances[j])
00880 {
00881 for (int k=(n-1);k > j;k--)
00882 {
00883 desc_idxs[k] = desc_idxs[k-1];
00884 pose_idxs[k] = pose_idxs[k-1];
00885 distances[k] = distances[k-1];
00886 }
00887 desc_idxs[j] = i;
00888 pose_idxs[j] = _pose_idx;
00889 distances[j] = _distance;
00890 break;
00891 }
00892 }
00893 }
00894 cvReleaseMat(&pca_coeffs);
00895 }
00896
00897 void FindOneWayDescriptorEx(int desc_count, const CvOneWayDescriptor* descriptors, IplImage* patch,
00898 float scale_min, float scale_max, float scale_step,
00899 int& desc_idx, int& pose_idx, float& distance, float& scale,
00900 CvMat* avg, CvMat* eigenvectors)
00901 {
00902 CvSize patch_size = descriptors[0].GetPatchSize();
00903 IplImage* input_patch;
00904 CvRect roi;
00905
00906 input_patch= cvCreateImage(patch_size, IPL_DEPTH_8U, 1);
00907 roi = cvGetImageROI((IplImage*)patch);
00908
00909 int _desc_idx, _pose_idx;
00910 float _distance;
00911 distance = 1e10;
00912 for(float cur_scale = scale_min; cur_scale < scale_max; cur_scale *= scale_step)
00913 {
00914
00915
00916 CvRect roi_scaled = resize_rect(roi, cur_scale);
00917 cvSetImageROI(patch, roi_scaled);
00918 cvResize(patch, input_patch);
00919
00920
00921 #if 0
00922 if(roi.x > 244 && roi.y < 200)
00923 {
00924 cvNamedWindow("1", 1);
00925 cvShowImage("1", input_patch);
00926 cvWaitKey(0);
00927 }
00928 #endif
00929
00930 FindOneWayDescriptor(desc_count, descriptors, input_patch, _desc_idx, _pose_idx, _distance, avg, eigenvectors);
00931 if(_distance < distance)
00932 {
00933 distance = _distance;
00934 desc_idx = _desc_idx;
00935 pose_idx = _pose_idx;
00936 scale = cur_scale;
00937 }
00938 }
00939
00940
00941 cvSetImageROI((IplImage*)patch, roi);
00942 cvReleaseImage(&input_patch);
00943
00944 }
00945
00946 void FindOneWayDescriptorEx(int desc_count, const CvOneWayDescriptor* descriptors, IplImage* patch,
00947 float scale_min, float scale_max, float scale_step,
00948 int n, std::vector<int>& desc_idxs, std::vector<int>& pose_idxs,
00949 std::vector<float>& distances, std::vector<float>& scales,
00950 CvMat* avg, CvMat* eigenvectors)
00951 {
00952 CvSize patch_size = descriptors[0].GetPatchSize();
00953 IplImage* input_patch;
00954 CvRect roi;
00955
00956 input_patch= cvCreateImage(patch_size, IPL_DEPTH_8U, 1);
00957 roi = cvGetImageROI((IplImage*)patch);
00958
00959
00960 std::vector<int> _desc_idxs;
00961 _desc_idxs.resize(n);
00962 std::vector<int> _pose_idxs;
00963 _pose_idxs.resize(n);
00964 std::vector<float> _distances;
00965 _distances.resize(n);
00966
00967
00968 for (int i=0;i<n;i++)
00969 {
00970 distances[i] = 1e10;
00971 }
00972
00973 for(float cur_scale = scale_min; cur_scale < scale_max; cur_scale *= scale_step)
00974 {
00975
00976 CvRect roi_scaled = resize_rect(roi, cur_scale);
00977 cvSetImageROI(patch, roi_scaled);
00978 cvResize(patch, input_patch);
00979
00980
00981
00982 FindOneWayDescriptor(desc_count, descriptors, input_patch, n,_desc_idxs, _pose_idxs, _distances, avg, eigenvectors);
00983 for (int i=0;i<n;i++)
00984 {
00985 if(_distances[i] < distances[i])
00986 {
00987 distances[i] = _distances[i];
00988 desc_idxs[i] = _desc_idxs[i];
00989 pose_idxs[i] = _pose_idxs[i];
00990 scales[i] = cur_scale;
00991 }
00992 }
00993 }
00994
00995
00996
00997 cvSetImageROI((IplImage*)patch, roi);
00998 cvReleaseImage(&input_patch);
00999 }
01000
01001 #if defined(_KDTREE)
01002 void FindOneWayDescriptorEx(cv::flann::Index* m_pca_descriptors_tree, CvSize patch_size, int m_pca_dim_low,
01003 int m_pose_count, IplImage* patch,
01004 float scale_min, float scale_max, float scale_step,
01005 int& desc_idx, int& pose_idx, float& distance, float& scale,
01006 CvMat* avg, CvMat* eigenvectors)
01007 {
01008 IplImage* input_patch;
01009 CvRect roi;
01010
01011 input_patch= cvCreateImage(patch_size, IPL_DEPTH_8U, 1);
01012 roi = cvGetImageROI((IplImage*)patch);
01013
01014 int _desc_idx, _pose_idx;
01015 float _distance;
01016 distance = 1e10;
01017 for(float cur_scale = scale_min; cur_scale < scale_max; cur_scale *= scale_step)
01018 {
01019
01020
01021 CvRect roi_scaled = resize_rect(roi, cur_scale);
01022 cvSetImageROI(patch, roi_scaled);
01023 cvResize(patch, input_patch);
01024
01025 FindOneWayDescriptor(m_pca_descriptors_tree, patch_size, m_pca_dim_low, m_pose_count, input_patch, _desc_idx, _pose_idx, _distance, avg, eigenvectors);
01026 if(_distance < distance)
01027 {
01028 distance = _distance;
01029 desc_idx = _desc_idx;
01030 pose_idx = _pose_idx;
01031 scale = cur_scale;
01032 }
01033 }
01034
01035
01036 cvSetImageROI((IplImage*)patch, roi);
01037 cvReleaseImage(&input_patch);
01038
01039 }
01040 #endif
01041
01042 const char* CvOneWayDescriptor::GetFeatureName() const
01043 {
01044 return m_feature_name.c_str();
01045 }
01046
01047 CvPoint CvOneWayDescriptor::GetCenter() const
01048 {
01049 return m_center;
01050 }
01051
01052 int CvOneWayDescriptor::GetPCADimLow() const
01053 {
01054 return m_pca_dim_low;
01055 }
01056
01057 int CvOneWayDescriptor::GetPCADimHigh() const
01058 {
01059 return m_pca_dim_high;
01060 }
01061
01062