one_way_descriptor.cpp
Go to the documentation of this file.
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 


outlet_pose_estimation
Author(s): Patrick Mihelich
autogenerated on Thu Nov 28 2013 11:46:23