$search
00001 /* 00002 * one_way_descriptor.cpp 00003 * 00004 * 00005 * Created by Victor Eruhimov on 4/19/09. 00006 * Copyright 2009 Argus Corp. All rights reserved. 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 // perturbate the matrix 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;//roi.width*roi.height; 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 /* if(m_transforms) 00231 { 00232 GenerateSamplesWithTransforms(pose_count, frontal); 00233 return; 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 //AffineTransformPatch(frontal, patch_8u, m_affine_poses[i]); 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 /* IplImage* temp1 = cvCreateImage(cvSize(12, 12), IPL_DEPTH_32F, 1); 00314 eigenvector2image(pca_hr_avg, temp1); 00315 IplImage* test = cvCreateImage(cvSize(12, 12), IPL_DEPTH_8U, 1); 00316 cvAdd(m_samples[i], temp1, temp1); 00317 cvMinMaxLoc(temp1, 0, &maxval); 00318 cvConvertScale(temp1, test, 255.0/maxval);*/ 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 // CvMat eigenvectorsr; 00385 // cvGetSubRect(eigenvectors, &eigenvectorsr, cvRect(0, 0, eigenvectors->cols, pca_coeffs->cols)); 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 // do not use pca 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 // float dist = 0; 00446 // float data1, data2; 00447 // //CvMat* pose_pca_coeffs = m_pca_coeffs[i]; 00448 // for (int x=0; x < pca_coeffs->width; x++) 00449 // for (int y =0 ; y < pca_coeffs->height; y++) 00450 // { 00451 // data1 = ((float*)(pca_coeffs->data.ptr + pca_coeffs->step*x))[y]; 00452 // data2 = ((float*)(m_pca_coeffs[i]->data.ptr + m_pca_coeffs[i]->step*x))[y]; 00453 // dist+=(data1-data2)*(data1-data2); 00454 // } 00456 // for (int j = 0; j < m_pca_dim_low; j++) 00457 // { 00458 // dist += (pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j])*(pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j]); 00459 // } 00460 //#else 00461 // for (int j = 0; j <= m_pca_dim_low - 4; j += 4) 00462 // { 00463 // dist += (pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j])* 00464 // (pose_pca_coeffs->data.fl[j]- pca_coeffs->data.fl[j]); 00465 // dist += (pose_pca_coeffs->data.fl[j+1]- pca_coeffs->data.fl[j+1])* 00466 // (pose_pca_coeffs->data.fl[j+1]- pca_coeffs->data.fl[j+1]); 00467 // dist += (pose_pca_coeffs->data.fl[j+2]- pca_coeffs->data.fl[j+2])* 00468 // (pose_pca_coeffs->data.fl[j+2]- pca_coeffs->data.fl[j+2]); 00469 // dist += (pose_pca_coeffs->data.fl[j+3]- pca_coeffs->data.fl[j+3])* 00470 // (pose_pca_coeffs->data.fl[j+3]- pca_coeffs->data.fl[j+3]); 00471 // } 00472 //#endif 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 //float dist = 0.0f; 00501 //float i1,i2; 00502 00503 //for (int y = 0; y<patch_32f->height; y++) 00504 // for (int x = 0; x< patch_32f->width; x++) 00505 // { 00506 // i1 = ((float*)(m_samples[i]->imageData + m_samples[i]->widthStep*y))[x]; 00507 // i2 = ((float*)(patch_32f->imageData + patch_32f->widthStep*y))[x]; 00508 // dist+= (i1-i2)*(i1-i2); 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 // prepare data to write as a single matrix 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 //PCA_coeffs precalculating 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 //ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs); 00644 //Projecting PCA 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 //End of projecting 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 //PCA_coeffs precalculating 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 //if (avg) 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 //ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs); 00723 //Projecting PCA 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 //End of projecting 00733 00734 cvReleaseImage(&patch_32f); 00735 cvReleaseImage(&test_img); 00736 // } 00737 00738 //-------- 00739 00740 //float* target = new float[m_pca_dim_low]; 00741 //::flann::KNNResultSet res(1,pca_coeffs->data.fl,m_pca_dim_low); 00742 //::flann::SearchParams params; 00743 //params.checks = -1; 00744 00745 //int maxDepth = 1000000; 00746 //int neighbors_count = 1; 00747 //int* neighborsIdx = new int[neighbors_count]; 00748 //float* distances = new float[neighbors_count]; 00749 //if (m_pca_descriptors_tree->findNearest(pca_coeffs->data.fl,neighbors_count,maxDepth,neighborsIdx,0,distances) > 0) 00750 //{ 00751 // desc_idx = neighborsIdx[0] / m_pose_count; 00752 // pose_idx = neighborsIdx[0] % m_pose_count; 00753 // distance = distances[0]; 00754 //} 00755 //delete[] neighborsIdx; 00756 //delete[] distances; 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 // delete[] target; 00775 00776 00777 // for(int i = 0; i < desc_count; i++) 00778 // { 00779 // int _pose_idx = -1; 00780 // float _distance = 0; 00781 // 00782 //#if 0 00783 // descriptors[i].EstimatePose(patch, _pose_idx, _distance); 00784 //#else 00785 // if (!avg) 00786 // { 00787 // descriptors[i].EstimatePosePCA(patch, _pose_idx, _distance, avg, eigenvectors); 00788 // } 00789 // else 00790 // { 00791 // descriptors[i].EstimatePosePCA(pca_coeffs, _pose_idx, _distance, avg, eigenvectors); 00792 // } 00793 //#endif 00794 // 00795 // if(_distance < distance) 00796 // { 00797 // desc_idx = i; 00798 // pose_idx = _pose_idx; 00799 // distance = _distance; 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 //PCA_coeffs precalculating 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 //ProjectPCASample(patch_32f, avg, eigenvectors, pca_coeffs); 00841 //Projecting PCA 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 //End of projecting 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 // printf("Scale = %f\n", cur_scale); 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 // float min_distance = 1e10; 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 // printf("Scale = %f\n", cur_scale); 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