subspace_analysis_fuerte.cpp
Go to the documentation of this file.
00001 #include<cob_people_detection/subspace_analysis_fuerte.h>
00002 
00003 #include "boost/filesystem/operations.hpp"
00004 #include "boost/filesystem/convenience.hpp"
00005 #include "boost/filesystem/path.hpp"
00006 #include <boost/thread/mutex.hpp>
00007 #include<opencv/cv.h>
00008 #include <opencv/cvaux.h>
00009 #include <opencv/highgui.h>
00010 #include <opencv/ml.h>
00011 void SubspaceAnalysis::error_prompt(std::string fct, std::string desc)
00012 {
00013         std::cerr << "ERROR\n";
00014         std::cerr << "Function:......... " << fct << std::endl;
00015         std::cerr << "Description:...... " << desc << std::endl;
00016 }
00017 void SubspaceAnalysis::dump_matrix(cv::Mat& mat, std::string filename)
00018 {
00019         std::string path = "/share/goa-tz/people_detection/eval/vis/";
00020         path.append(filename.c_str());
00021         std::ofstream os(path.c_str());
00022         for (int r = 0; r < mat.rows; r++)
00023         {
00024                 for (int c = 0; c < mat.cols; c++)
00025                 {
00026                         os << mat.at<double>(r, c) << " ";
00027                 }
00028                 os << "\n";
00029         }
00030         os.close();
00031 }
00032 
00033 void SubspaceAnalysis::condense_labels(std::vector<int>& labels)
00034 {
00035         int min_val = std::numeric_limits<int>::max();
00036         for (int i = 0; i < labels.size(); i++)
00037         {
00038                 if (labels[i] < min_val)
00039                         min_val = labels[i];
00040         }
00041         if (min_val > 0)
00042         {
00043                 for (int i = 0; i < labels.size(); i++)
00044                 {
00045                         labels[i] -= min_val;
00046                 }
00047         }
00048 }
00049 void SubspaceAnalysis::mat_info(cv::Mat& mat)
00050 {
00051 
00052         for (int r = 0; r < mat.rows; r++)
00053         {
00054                 for (int c = 0; c < mat.cols; c++)
00055                 {
00056                         std::cout << mat.at<float>(r, c) << " ";
00057                 }
00058 
00059                 std::cout << "\n";
00060         }
00061         std::cout << "Matrix info:\n";
00062         std::cout << "rows= " << mat.rows << "  cols= " << mat.cols << std::endl;
00063         std::cout << "Type = " << mat.type() << std::endl;
00064         std::cout << "Channels = " << mat.channels() << std::endl;
00065 }
00066 void SubspaceAnalysis::unique_elements(cv::Mat & mat, int& unique_elements, std::vector<int>& distinct_vec)
00067 {
00068         bool unique = true;
00069         for (int i = 0; i < mat.total(); ++i)
00070         {
00071 
00072                 if (i != 0)
00073                 {
00074                         unique = true;
00075                         for (int j = 0; j < distinct_vec.size(); j++)
00076                         {
00077                                 if (mat.at<float>(i) == distinct_vec[j])
00078                                         unique = false;
00079                         }
00080                 }
00081                 if (unique == true)
00082                         distinct_vec.push_back(mat.at<float>(i));
00083         }
00084         unique_elements = distinct_vec.size();
00085 }
00086 void SubspaceAnalysis::unique_elements(std::vector<int> & vec, int& unique_elements, std::vector<int>& distinct_vec)
00087 {
00088         bool unique = true;
00089         for (int i = 0; i < vec.size(); ++i)
00090         {
00091 
00092                 if (i != 0)
00093                 {
00094                         unique = true;
00095                         for (int j = 0; j < distinct_vec.size(); j++)
00096                         {
00097                                 if (vec[i] == distinct_vec[j])
00098                                         unique = false;
00099                         }
00100                 }
00101                 if (unique == true)
00102                         distinct_vec.push_back(vec[i]);
00103         }
00104         unique_elements = distinct_vec.size();
00105 }
00106 //---------------------------------------------------------------------------------
00107 //  XFace XFaces
00108 //---------------------------------------------------------------------------------
00109 //
00110 //
00111 //
00112 void SubspaceAnalysis::XFaces::calcDFFS(cv::Mat& orig_mat, cv::Mat& recon_mat, cv::Mat& avg, std::vector<double>& DFFS)
00113 {
00114 
00115         cv::Mat temp = cv::Mat(orig_mat.rows, orig_mat.cols, orig_mat.type());
00116         orig_mat.copyTo(temp);
00117         DFFS.resize(recon_mat.rows);
00118         for (int i = 0; i < orig_mat.rows; i++)
00119         {
00120                 cv::Mat recon_row = recon_mat.row(i);
00121                 cv::Mat temp_row = temp.row(i);
00122                 cv::subtract(temp_row, avg, temp_row);
00123                 DFFS[i] = cv::norm(recon_row, temp_row, cv::NORM_L2);
00124         }
00125         return;
00126 }
00127 
00128 void SubspaceAnalysis::XFaces::mat2arr(cv::Mat& src_mat, cv::Mat& dst_mat)
00129 {
00130 
00131         dst_mat = src_mat.clone().reshape(1, 1);
00132 
00133         return;
00134 }
00135 void SubspaceAnalysis::XFaces::project(cv::Mat& src_mat, cv::Mat& proj_mat, cv::Mat& avg_mat, cv::Mat& coeff_mat)
00136 {
00137 
00138         //for(int i=0;i<src_mat.rows;i++)
00139         //{
00140         //  cv::Mat c_row=src_mat.row(i);
00141         //  cv::subtract(c_row,avg_mat,c_row);
00142         //}
00143 
00144         //calculate coefficients
00145         //
00146 
00147         cv::gemm(src_mat, proj_mat, 1.0, cv::Mat(), 0.0, coeff_mat, cv::GEMM_2_T);
00148 
00149 }
00150 
00151 void SubspaceAnalysis::XFaces::reconstruct(cv::Mat& coeffs, cv::Mat& proj_mat, cv::Mat& avg, cv::Mat& rec_im)
00152 {
00153         cv::gemm(coeffs, proj_mat, 1.0, cv::Mat(), 0.0, rec_im);
00154         for (int i = 0; i < rec_im.rows; i++)
00155         {
00156                 cv::Mat curr_row = rec_im.row(i);
00157                 cv::add(curr_row, avg.reshape(1, 1), curr_row);
00158         }
00159 }
00160 
00161 void SubspaceAnalysis::XFaces::calcDataMat(std::vector<cv::Mat>& input_data, cv::Mat& data_mat)
00162 {
00163 
00164         // convert input to data matrix,with images as rows
00165 
00166         for (int i = 0; i < input_data.size(); i++)
00167         {
00168                 cv::Mat src_mat;
00169                 src_mat = input_data[i];
00170                 src_mat = src_mat.reshape(1, 1);
00171                 //convert images to unit norm
00172                 //cv::normalize(src_mat,src_mat,1.0,0.0,cv::NORM_L1);
00173                 cv::Mat dst_row = data_mat.row(i);
00174                 src_mat.copyTo(dst_row);
00175         }
00176 
00177         //    double* src_ptr;
00178         //    double*  dst_ptr;
00179         //    cv::Mat src_mat;
00180         //    for(int i = 0;i<input_data.size();i++)
00181         //    {
00182         //      input_data[i].copyTo(src_mat);
00183         //
00184         //      src_ptr = src_mat.ptr<double>(0,0);
00185         //      //src_ptr = input_data[i].ptr<double>(0,0);
00186         //      dst_ptr = data_mat.ptr<double>(i,0);
00187         //
00188         //      for(int j=0;j<input_data[i].rows;j++)
00189         //      {
00190         //        src_ptr=src_mat.ptr<double>(j,0);
00191         //        //src_ptr=input_data[i].ptr<double>(j,0);
00192         //        for(int col=0;col<input_data[i].cols;col++)
00193         //        {
00194         //        *dst_ptr=*src_ptr;
00195         //        src_ptr++;
00196         //        dst_ptr++;
00197         //        }
00198         //      }
00199         //
00200         //    }
00201 
00202 
00203         //cv::Mat src_mat=cv::Mat(120,120,CV_64FC1);
00204         //src_mat= input_data[0].clone();
00206         //std::cout<<"src"<<src_mat.rows<<","<<src_mat.cols<<std::endl;
00207         //src_mat=src_mat.reshape(1,1);
00208         //src_mat.clone();
00209         //std::cout<<"src"<<src_mat.rows<<","<<src_mat.cols<<std::endl;
00210         //cv::Mat dst_mat;
00211         //dst_mat.push_back(src_mat);
00212 
00213         //std::cout<<"dst"<<dst_mat.rows<<","<<dst_mat.cols<<std::endl;
00214         //dst_mat=dst_mat.reshape(1,120);
00215         //dst_mat.convertTo(dst_mat,CV_8UC1);
00216         //cv::imshow("DST",dst_mat);
00217         //cv::waitKey(0);
00218 
00219         return;
00220 }
00221 
00222 void SubspaceAnalysis::XFaces::retrieve(std::vector<cv::Mat>& out_eigenvectors, cv::Mat& out_eigenvalues, cv::Mat& out_avg, cv::Mat& out_proj_model_data)
00223 {
00224 
00225         avg_arr_.copyTo(out_avg);
00226         proj_model_data_arr_.copyTo(out_proj_model_data);
00227 
00228         for (int r = 0; r < eigenvector_arr_.rows; r++)
00229         {
00230                 cv::Mat curr_row = eigenvector_arr_.row(r);
00231                 //TODO: works only for square images
00232                 curr_row.clone().reshape(1, sqrt(curr_row.cols));
00233                 curr_row.convertTo(curr_row, CV_32FC1);
00234                 curr_row.copyTo(out_eigenvectors[r]);
00235 
00236         }
00237 
00238         eigenvalue_arr_.copyTo(out_eigenvalues);
00239 
00240 }
00241 
00242 void SubspaceAnalysis::XFaces::getModel(cv::Mat& out_eigenvectors, cv::Mat& out_eigenvalues, cv::Mat& out_avg, cv::Mat& out_proj_model_data)
00243 {
00244         avg_arr_ .copyTo(out_avg);
00245         proj_model_data_arr_.copyTo(out_proj_model_data);
00246         eigenvector_arr_ .copyTo(out_eigenvectors);
00247         eigenvalue_arr_ .copyTo(out_eigenvalues);
00248 }
00249 
00250 void SubspaceAnalysis::XFaces::retrieve(std::vector<cv::Mat>& out_eigenvectors, cv::Mat& out_eigenvalues, cv::Mat& out_avg, cv::Mat& out_proj_model_data, cv::Size output_dim)
00251 {
00252 
00253         avg_arr_.copyTo(out_avg);
00254         proj_model_data_arr_.copyTo(out_proj_model_data);
00255 
00256         for (int r = 0; r < eigenvector_arr_.rows; r++)
00257         {
00258                 cv::Mat curr_row = eigenvector_arr_.row(r);
00259                 //TODO: works only for square images
00260                 curr_row.clone().reshape(1, output_dim.height);
00261                 curr_row.convertTo(curr_row, CV_32FC1);
00262                 curr_row.copyTo(out_eigenvectors[r]);
00263 
00264         }
00265 
00266         eigenvalue_arr_.copyTo(out_eigenvalues);
00267 
00268 }
00269 
00270 void SubspaceAnalysis::XFaces::projectToSubspace(cv::Mat& probe_mat, cv::Mat& coeff_arr, double& DFFS)
00271 {
00272 
00273         if (this->trained == false)
00274         {
00275                 std::cout << "XFaces --> Model not trained - aborting projectToSubspace\n";
00276                 return;
00277         }
00278 
00279         cv::Mat src_arr;
00280         mat2arr(probe_mat, src_arr);
00281 
00282         // TODO: LOOK UP IS THIS RIGHT????
00283         // reduce im mat by mean
00284         //for(int i=0;i<src_arr.rows;i++)
00285         //{
00286         //  cv::Mat im=src_arr.row(i);
00287         //  cv::subtract(im,avg_arr_,im);
00288         //}
00289 
00290         //cv::normalize(src_arr,src_arr,1.0,0.0,cv::NORM_L1);
00291         project(src_arr, eigenvector_arr_, avg_arr_, coeff_arr);
00292 
00293         cv::Mat rec_mat = cv::Mat(src_arr.rows, eigenvector_arr_.rows, CV_64FC1);
00294         reconstruct(coeff_arr, eigenvector_arr_, avg_arr_, rec_mat);
00295 
00296         std::vector<double> DFFS_vec;
00297         DFFS_vec.push_back(DFFS);
00298         calcDFFS(src_arr, rec_mat, avg_arr_, DFFS_vec);
00299         DFFS = DFFS_vec[0];
00300 
00301         //cv::Mat dummy;
00302         //rec_mat.copyTo(dummy);
00303         //dummy.convertTo(dummy,CV_8UC1);
00304         //dummy =dummy.reshape(1,dummy.rows*160);
00306         //cv::imwrite("/home/goa-tz/Desktop/reconstructed.jpg",dummy);
00307 }
00308 
00309 void SubspaceAnalysis::XFaces::calc_threshold(cv::Mat& data, std::vector<cv::Mat>& thresh)
00310 {
00311         //TODO: calculate sigma
00312         double sigma = 1.7f;
00313         thresh.resize(num_classes_);
00314         class_centers_ = cv::Mat::zeros(num_classes_, data.cols, CV_64FC1);
00315         SubspaceAnalysis::LDA lda;
00316         lda.calcClassMean(data, model_label_arr_, class_centers_, num_classes_);
00317 
00318         cv::Mat max_arr, curr_mean, curr_sample, curr_max;
00319         max_arr = cv::Mat::ones(num_classes_, data.cols, CV_64FC1);
00320         max_arr *= std::numeric_limits<double>::min();
00321 
00322         for (int i = 0; i < data.rows; i++)
00323         {
00324                 int index = (int)model_label_arr_.at<float>(i);
00325                 curr_sample = data.row(i);
00326                 curr_mean = class_centers_.row(index);
00327                 curr_max = max_arr.row(index);
00328                 cv::max(curr_max, curr_sample - curr_mean, curr_max);
00329         }
00330 
00331         for (int j = 0; j < num_classes_; j++)
00332         {
00333                 cv::Mat curr_row = max_arr.row(j);
00334                 thresh[j] = sigma * curr_row;
00335         }
00336 }
00337 void SubspaceAnalysis::XFaces::calc_threshold(cv::Mat& data, double& thresh)
00338 {
00339         //TODO implemented brute force method -> optimization
00340         // implement for case when Di>Pi
00341         //  don't use until that....
00342         std::vector<double> P(num_classes_, std::numeric_limits<double>::max());
00343         std::vector<double> D(num_classes_, std::numeric_limits<double>::min());
00344         std::vector<double> Phi(num_classes_, std::numeric_limits<double>::max());
00345 
00346         for (int i = 0; i < data.rows; i++)
00347         {
00348                 cv::Mat i_row = data.row(i);
00349                 for (int n = 0; n < data.rows; n++)
00350                 {
00351                         if (n == i)
00352                                 continue;
00353                         cv::Mat n_row = data.row(n);
00354                         double dist = cv::norm(i_row, n_row, cv::NORM_L2);
00355                         if (model_label_arr_.at<float>(n) == model_label_arr_.at<float>(i))
00356                         {
00357                                 D[model_label_arr_.at<float>(i)] = std::max(dist, D[model_label_arr_.at<float>(i)]);
00358                         }
00359                         else
00360                         {
00361                                 P[model_label_arr_.at<float>(i)] = std::min(dist, P[model_label_arr_.at<float>(i)]);
00362                         }
00363                 }
00364         }
00365 
00366         // if only one class - P =D
00367         if (num_classes_ == 1)
00368         {
00369                 P[0] = D[0];
00370         }
00371 
00372         for (int c = 0; c < num_classes_; c++)
00373         {
00374                 thresh = std::min(thresh, (P[c] + D[c]) * 0.5);
00375                 //std::cout<<"c"<<c<<": "<<D[c]<<" "<<P[c]<<std::endl;
00376         }
00377         std::cout << "THRESH for db: " << thresh << std::endl;
00378 
00379 }
00380 
00381 void SubspaceAnalysis::XFaces::classify(cv::Mat& coeff_arr, Classifier method, int& class_index)
00382 {
00383         if (this->trained == false)
00384         {
00385                 std::cout << "XFaces --> Model not trained - aborting classify\n";
00386                 return;
00387         }
00388         if (coeff_arr.rows > 1)
00389         {
00390                 std::cout << "[CLASSIFICATION] only implemented for single sample in single row" << std::endl;
00391                 return;
00392         }
00393 
00394         if (num_classes_ < 2)
00395         {
00396                 method = SubspaceAnalysis::CLASS_DIFS;
00397         }
00398 
00399         switch (method)
00400         {
00401         case SubspaceAnalysis::CLASS_DIFS:
00402         {
00403                 double minDIFS;
00404                 cv::Mat minDIFScoeffs;
00405                 int minDIFSindex;
00406                 calcDIFS(coeff_arr, minDIFSindex, minDIFS, minDIFScoeffs);
00407                 class_index = (int)model_label_arr_.at<float>(minDIFSindex);
00408 
00409                 break;
00410         }
00411                 ;
00412 
00413         case SubspaceAnalysis::CLASS_KNN:
00414         {
00415                 // train SVM when not already trained
00416                 if (!knn_trained_)
00417                 {
00418 
00419                         cv::Mat data_float;
00420                         proj_model_data_arr_.convertTo(data_float, CV_32FC1);
00421 
00422                         knn_.train(data_float, model_label_arr_);
00423                         knn_trained_ = true;
00424                 }
00425 
00426                 // predict using knn
00427                 cv::Mat sample;
00428                 coeff_arr.convertTo(sample, CV_32FC1);
00429                 //class_index=(int)svm_.predict(sample);
00430                 cv::Mat result;
00431 
00432                 class_index = (int)knn_.find_nearest(sample, 3);
00433 
00434                 break;
00435         }
00436                 ;
00437         case SubspaceAnalysis::CLASS_SVM:
00438         {
00439                 // train SVM when not already trained
00440                 if (!svm_trained_)
00441                 {
00442                         //train svm with model data
00443                         CvSVMParams params;
00444                         params.svm_type = CvSVM::C_SVC;
00445                         //params.kernel_type = CvSVM::LINEAR;
00446                         params.kernel_type = CvSVM::LINEAR;
00447                         params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 50, 1e-5);
00448 
00449                         cv::Mat data_float;
00450                         proj_model_data_arr_.convertTo(data_float, CV_32FC1);
00451 
00452                         svm_.train(data_float, model_label_arr_, cv::Mat(), cv::Mat(), params);
00453                         svm_trained_ = true;
00454                 }
00455 
00456                 // predict using svm
00457                 cv::Mat sample;
00458                 coeff_arr.convertTo(sample, CV_32FC1);
00459                 //class_index=(int)svm_.predict(sample);
00460                 class_index = (int)svm_.predict(sample);
00461 
00462                 break;
00463         }
00464                 ;
00465         case SubspaceAnalysis::CLASS_RF:
00466         {
00467                 // train SVM when not already trained
00468                 if (!rf_trained_)
00469                 {
00470                         //train svm with model data
00471                         CvRTParams params;
00472 
00473                         cv::Mat data_float;
00474                         proj_model_data_arr_.convertTo(data_float, CV_32FC1);
00475 
00476                         rf_.train(data_float, CV_ROW_SAMPLE, model_label_arr_, cv::Mat(), cv::Mat(), cv::Mat(), cv::Mat(), params);
00477                         rf_trained_ = true;
00478                 }
00479 
00480                 // predict using svm
00481                 cv::Mat sample;
00482                 coeff_arr.convertTo(sample, CV_32FC1);
00483                 //class_index=(int)svm_.predict(sample);
00484                 class_index = (int)rf_.predict(sample);
00485 
00486                 break;
00487         }
00488                 ;
00489 
00490         default:
00491         {
00492                 std::cout << "[CLASSIFICATION] method not implemented" << std::endl;
00493                 break;
00494         }
00495                 ;
00496         }
00497 
00498         if (use_unknown_thresh_)
00499         {
00500                 verifyClassification(coeff_arr, class_index);
00501         }
00502         return;
00503 
00504 }
00505 
00506 void SubspaceAnalysis::XFaces::calcDIFS(cv::Mat& probe_mat, int& minDIFSindex, double& minDIFS, cv::Mat& minDIFScoeffs)
00507 {
00508         double temp;
00509         minDIFS = std::numeric_limits<int>::max();
00510         for (int r = 0; r < proj_model_data_arr_.rows; r++)
00511         {
00512                 cv::Mat model_mat = proj_model_data_arr_.row(r);
00513                 cv::Mat diff_row;
00514                 cv::subtract(probe_mat, model_mat, diff_row);
00515                 temp = cv::norm(diff_row, cv::NORM_L2);
00516                 if (temp < minDIFS)
00517                 {
00518                         minDIFSindex = r;
00519                         minDIFScoeffs = diff_row;
00520                         minDIFS = temp;
00521                 }
00522         }
00523 
00524         return;
00525 }
00526 
00527 void SubspaceAnalysis::XFaces::releaseModel()
00528 {
00529         num_classes_ = -1;
00530         ss_dim_ = -1;
00531         svm_trained_ = false;
00532         knn_trained_ = false;
00533         eigenvector_arr_.release();
00534         eigenvalue_arr_.release();
00535         avg_arr_.release();
00536         model_data_arr_.release();
00537         proj_model_data_arr_.release();
00538         model_label_arr_.release();
00539         ;
00540 
00541         CvSVM svm_;
00542         CvKNearest knn_;
00543 
00544 }
00545 
00546 bool SubspaceAnalysis::XFaces::verifyClassification(cv::Mat& sample, int& index)
00547 {
00548 
00549         double minDIFS = std::numeric_limits<double>::max();
00550         for (int n = 0; n < proj_model_data_arr_.rows; n++)
00551         {
00552                 if (model_label_arr_.at<float>(n) == (float)index)
00553                 {
00554                         cv::Mat curr_row = proj_model_data_arr_.row(n);
00555                         double dist = cv::norm(curr_row, sample, cv::NORM_L2);
00556                         minDIFS = std::min(dist, minDIFS);
00557                 }
00558         }
00559         if (minDIFS > thresh_)
00560         {
00561                 std::cout << "NEW threshold: unknown " << minDIFS << std::endl;
00562                 index = -1;
00563                 return false;
00564         }
00565         return true;
00566 }
00567 //---------------------------------------------------------------------------------
00568 // EIGENFACES
00569 //---------------------------------------------------------------------------------
00570 //
00571 //
00572 bool SubspaceAnalysis::Eigenfaces::init(std::vector<cv::Mat>& img_vec, std::vector<int>& label_vec, int& red_dim)
00573 {
00574         svm_trained_ = false;
00575         knn_trained_ = false;
00576         thresh_ = std::numeric_limits<double>::max();
00577         SubspaceAnalysis::unique_elements(label_vec, num_classes_, unique_labels_);
00578 
00579         model_label_arr_ = cv::Mat(1, label_vec.size(), CV_32FC1);
00580         for (int i = 0; i < label_vec.size(); i++)
00581         {
00582                 model_label_arr_.at<float>(i) = static_cast<float>(label_vec[i]);
00583         }
00584 
00585         ss_dim_ = red_dim;
00586 
00587         //check if input has the same size
00588         if (img_vec.size() < ss_dim_ + 1)
00589         {
00590                 //TODO: ROS ERROR
00591                 std::cout << "EIGFACE: Invalid subspace dimension\n";
00592                 return false;
00593         }
00594 
00595         //initialize all matrices
00596         model_data_arr_ = cv::Mat(img_vec.size(), img_vec[0].total(), CV_64FC1);
00597         avg_arr_ = cv::Mat(1, img_vec[0].total(), CV_64FC1);
00598         proj_model_data_arr_ = cv::Mat(img_vec.size(), ss_dim_, CV_64FC1);
00599         eigenvector_arr_ = cv::Mat(ss_dim_, img_vec[0].total(), CV_64FC1);
00600         eigenvalue_arr_ = cv::Mat(ss_dim_, ss_dim_, CV_64FC1);
00601 
00602         calcDataMat(img_vec, model_data_arr_);
00603 
00604         //initiate PCA
00605         //
00606         pca_ = SubspaceAnalysis::PCA(model_data_arr_, ss_dim_);
00607 
00608         eigenvector_arr_ = pca_.eigenvecs;
00609         eigenvalue_arr_ = pca_.eigenvals;
00610         avg_arr_ = pca_.mean;
00611 
00612         project(model_data_arr_, eigenvector_arr_, avg_arr_, proj_model_data_arr_);
00613 
00614         return true;
00615 }
00616 
00617 void SubspaceAnalysis::Eigenfaces::meanCoeffs(cv::Mat& coeffs, std::vector<int>& label_vec, cv::Mat& mean_coeffs)
00618 {
00619 
00620         mean_coeffs = cv::Mat::zeros(num_classes_, coeffs.cols, CV_64FC1);
00621         std::vector<int> samples_per_class(num_classes_);
00622 
00623         //initialize vectors with zeros
00624         for (int i = 0; i < num_classes_; i++)
00625         {
00626                 samples_per_class[i] = 0;
00627         }
00628 
00629         int class_index;
00630         for (int i = 0; i < coeffs.rows; i++)
00631         {
00632                 cv::Mat curr_row = coeffs.row(i);
00633                 class_index = label_vec[i];
00634 
00635                 cv::Mat mean_row = mean_coeffs.row(class_index);
00636 
00637                 add(mean_row, curr_row, mean_row);
00638                 samples_per_class[class_index]++;
00639         }
00640 
00641         for (int i = 0; i < num_classes_; i++)
00642         {
00643                 cv::Mat mean_row = mean_coeffs.row(i);
00644                 mean_row.convertTo(mean_row, CV_64FC1, 1.0 / static_cast<double>(samples_per_class[i]));
00645 
00646         }
00647 }
00648 
00649 //---------------------------------------------------------------------------------
00650 // FIsherfaces
00651 //---------------------------------------------------------------------------------
00652 
00653 
00654 bool SubspaceAnalysis::Fisherfaces::init(std::vector<cv::Mat>& img_vec, std::vector<int>& label_vec)
00655 {
00656         svm_trained_ = false;
00657         knn_trained_ = false;
00658         thresh_ = std::numeric_limits<double>::max();
00659         // check if input data is valid
00660         if (img_vec.size() != label_vec.size())
00661         {
00662                 std::cout << "ERROR :  image and label vectors have to be of same length" << std::endl;
00663                 return false;
00664         }
00665 
00666         model_label_arr_ = cv::Mat(1, label_vec.size(), CV_32FC1);
00667         for (int i = 0; i < label_vec.size(); i++)
00668         {
00669                 model_label_arr_.at<float>(i) = static_cast<float>(label_vec[i]);
00670         }
00671 
00672         //initialize all matrices
00673         model_data_arr_ = cv::Mat(img_vec.size(), img_vec[0].total(), CV_64FC1);
00674         avg_arr_ = cv::Mat(1, img_vec[0].total(), CV_64FC1);
00675 
00676         //number of classes
00677         SubspaceAnalysis::unique_elements(label_vec, num_classes_, unique_labels_);
00678 
00679         if (num_classes_ < 2)
00680         {
00681                 std::cout << "FISHERFACES ERROR : More than one class is necessary" << std::endl;
00682                 return false;
00683         }
00684 
00685         //subspace dimension is num classes -1
00686         ss_dim_ = num_classes_ - 1;
00687         // pca dimension  is N- num classes
00688         int pca_dim = model_data_arr_.rows - num_classes_;
00689 
00690         calcDataMat(img_vec, model_data_arr_);
00691 
00692         // Reduce dimension to  N - c via PCA
00693         pca_ = SubspaceAnalysis::PCA(model_data_arr_, pca_dim);
00694 
00695         cv::Mat proj_model_data_arr_PCA = cv::Mat(model_data_arr_.rows, pca_dim, CV_64FC1);
00696         project(model_data_arr_, pca_.eigenvecs, pca_.mean, proj_model_data_arr_PCA);
00697 
00698         // get projection matrix pca
00699         cv::Mat P_pca = cv::Mat(pca_dim, img_vec[0].total(), CV_64FC1);
00700         P_pca = pca_.eigenvecs;
00701         avg_arr_ = pca_.mean;
00702 
00703         //perform lda
00704         lda_ = SubspaceAnalysis::LDA(proj_model_data_arr_PCA, label_vec, num_classes_, ss_dim_);
00705 
00706         // get projection matrix lda
00707         cv::Mat P_lda = cv::Mat(ss_dim_, pca_dim, CV_64FC1);
00708         P_lda = lda_.eigenvecs;
00709 
00710         // combine projection matrices
00711         cv::gemm(P_pca.t(), P_lda.t(), 1.0, cv::Mat(), 0.0, eigenvector_arr_);
00712         //cv::gemm(P_pca.t(),P_lda.t(),1.0,cv::Mat(),0.0,eigenvector_arr_);
00713 
00714         eigenvector_arr_ = eigenvector_arr_.t();
00715 
00716         // cv::Mat ss=model_data_(cv::Rect(0,0,120*120,3));
00717         // projectToSubspace(ss,proj_model_data_,DFFS);
00718         // dump_matrix(proj_model_data_,"projection1");
00719 
00720         // cv::Mat ss2=model_data_(cv::Rect(0,2,120*120,3));
00721         // projectToSubspace(ss2,proj_model_data_,DFFS);
00722         // dump_matrix(proj_model_data_,"projection2");
00723 
00724         proj_model_data_arr_ = cv::Mat(img_vec.size(), ss_dim_, CV_64FC1);
00725 
00726         project(model_data_arr_, eigenvector_arr_, avg_arr_, proj_model_data_arr_);
00727 
00728         return true;
00729 
00730 }
00731 
00732 //---------------------------------------------------------------------------------
00733 // FishEigFaces
00734 //---------------------------------------------------------------------------------
00735 
00736 SubspaceAnalysis::FishEigFaces::FishEigFaces()
00737 {
00738         fallback_ = false;
00739         svm_trained_ = false;
00740         knn_trained_ = false;
00741         use_unknown_thresh_ = true;
00742 
00743         //initialize Threshold with maximum value
00744         thresh_ = std::numeric_limits<double>::max();
00745 
00746         num_classes_ = -1;
00747 
00748 }
00749 
00750 //-----------------------------------------------------------------------------------------------
00752 //old interface - just for compability reasons  use new trainModel and
00753 //loadModel
00754 bool SubspaceAnalysis::FishEigFaces::init(std::vector<cv::Mat>& img_vec, std::vector<int>& label_vec, int& red_dim)
00755 {
00756         trainModel(img_vec, label_vec, red_dim);
00757 }
00758 bool SubspaceAnalysis::FishEigFaces::init(std::vector<cv::Mat>& img_vec, std::vector<int>& label_vec, int& red_dim, Method method)
00759 {
00760         trainModel(img_vec, label_vec, red_dim, method);
00761 }
00762 bool SubspaceAnalysis::FishEigFaces::init(std::vector<cv::Mat>& img_vec, std::vector<int>& label_vec, int& red_dim, Method method, bool fallback, bool use_unknown_thresh)
00763 {
00764         trainModel(img_vec, label_vec, red_dim, method, fallback, use_unknown_thresh);
00765 }
00766 //-----------------------------------------------------------------------------------------------
00768 
00769 
00770 bool SubspaceAnalysis::XFaces::saveModel(std::string path)
00771 {
00772 
00773         std::cout << "saving model" << std::endl;
00774 
00775         if (boost::filesystem::is_regular_file(path.c_str()))
00776         {
00777                 if (boost::filesystem::remove(path.c_str()) == false)
00778                 {
00779 
00780                         error_prompt("saveModel()", "old rdata.xml can not be removed");
00781                         return false;
00782                 }
00783         }
00784         cv::FileStorage fileStorage(path.c_str(), cv::FileStorage::WRITE);
00785         if (!fileStorage.isOpened())
00786         {
00787                 error_prompt("saveModel()", "Output path is invalid");
00788                 return false;
00789         }
00790 
00791         fileStorage << "eigenvectors" << eigenvector_arr_;
00792         // Eigenvalue matrix
00793         fileStorage << "eigenvalues" << eigenvalue_arr_;
00794 
00795         // Average image
00796         fileStorage << "average_image" << avg_arr_;
00797 
00798         // Projection coefficients of the training faces
00799         fileStorage << "projected_model_data" << proj_model_data_arr_;
00800 
00801         fileStorage << "model_data_labels" << model_label_arr_;
00802 
00803         fileStorage.release();
00804 
00805         return true;
00806 }
00807 
00808 bool SubspaceAnalysis::XFaces::loadModelFromFile(std::string path, bool use_unknown_thresh)
00809 {
00810         //if(this->trained)this->releaseModel();
00811 
00812         // secure this function with a mutex
00813 
00814         cv::FileStorage fileStorage(path.c_str(), cv::FileStorage::READ);
00815         if (!fileStorage.isOpened())
00816         {
00817                 error_prompt("loadModelFromFile()", "Invalid input file");
00818                 return false;
00819         }
00820         else
00821         {
00822                 fileStorage["eigenvectors"] >> eigenvector_arr_;
00823                 fileStorage["eigenvalues"] >> eigenvalue_arr_;
00824                 fileStorage["average_image"] >> avg_arr_;
00825                 fileStorage["projected_model_data"] >> proj_model_data_arr_;
00826                 fileStorage["model_data_labels"] >> model_label_arr_;
00827 
00828         }
00829         fileStorage.release();
00830 
00831         //TODO keep only a selection instead of whole dataset depending on labels
00832 
00833         use_unknown_thresh_ = use_unknown_thresh;
00834 
00835         SubspaceAnalysis::unique_elements(model_label_arr_, num_classes_, unique_labels_);
00836 
00837         ss_dim_ = proj_model_data_arr_.cols;
00838 
00839         if (use_unknown_thresh_)
00840         {
00841                 std::cout << "calculating threshold...";
00842                 calc_threshold(proj_model_data_arr_, thresh_);
00843                 std::cout << "done" << std::endl;
00844         }
00845         this->trained = true;
00846         std::cout << "FishEigFaces --> model loaded successfully\n";
00847         return true;
00848 
00849 }
00850 
00851 bool SubspaceAnalysis::XFaces::loadModel(cv::Mat& eigenvec_arr, cv::Mat& eigenval_arr, cv::Mat& avg_arr, cv::Mat& proj_model, std::vector<int>& label_vec, bool use_unknown_thresh)
00852 {
00853         //check if number of labels equals number of images in training set
00854         if (label_vec.size() != proj_model.rows)
00855         {
00856                 error_prompt("loadModel()", "#labels != #rows in projected model data");
00857                 return false;
00858         }
00859 
00860         //if(this->trained)this->releaseModel();
00861         eigenvector_arr_ = eigenvec_arr;
00862         eigenvalue_arr_ = eigenval_arr;
00863         proj_model_data_arr_ = proj_model;
00864         avg_arr_ = avg_arr;
00865 
00866         use_unknown_thresh_ = use_unknown_thresh;
00867 
00868         SubspaceAnalysis::unique_elements(label_vec, num_classes_, unique_labels_);
00869         SubspaceAnalysis::condense_labels(label_vec);
00870         model_label_arr_ = cv::Mat(1, label_vec.size(), CV_32FC1);
00871         for (int i = 0; i < label_vec.size(); i++)
00872         {
00873                 model_label_arr_.at<float>(i) = static_cast<float>(label_vec[i]);
00874         }
00875 
00876         ss_dim_ = proj_model_data_arr_.cols;
00877 
00878         if (use_unknown_thresh_)
00879         {
00880                 std::cout << "calculating threshold...";
00881                 calc_threshold(proj_model_data_arr_, thresh_);
00882                 std::cout << "done" << std::endl;
00883         }
00884         this->trained = true;
00885         std::cout << "FishEigFaces --> model loaded successfully\n";
00886         return true;
00887 }
00888 
00889 bool SubspaceAnalysis::FishEigFaces::trainModel(std::vector<cv::Mat>& img_vec, std::vector<int>& label_vec, int& red_dim)
00890 {
00891         trainModel(img_vec, label_vec, red_dim, SubspaceAnalysis::METH_FISHER, true, true);
00892 }
00893 bool SubspaceAnalysis::FishEigFaces::trainModel(std::vector<cv::Mat>& img_vec, std::vector<int>& label_vec, int& red_dim, Method method)
00894 {
00895         trainModel(img_vec, label_vec, red_dim, method, true, true);
00896 }
00897 bool SubspaceAnalysis::FishEigFaces::trainModel(std::vector<cv::Mat>& img_vec, std::vector<int>& label_vec, int& red_dim, Method method, bool fallback, bool use_unknown_thresh)
00898 
00899 {
00900         fallback_ = fallback;
00901         use_unknown_thresh_ = use_unknown_thresh;
00902         //initialize Threshold with maximum value
00903         //process_labels<int>(label_vec,model_label_arr_);
00904 
00905 
00906         SubspaceAnalysis::unique_elements(label_vec, num_classes_, unique_labels_);
00907         SubspaceAnalysis::condense_labels(label_vec);
00908 
00909         //input data checks
00910         //check if input has the same size
00911         ss_dim_ = red_dim;
00912         if (img_vec.size() < ss_dim_)
00913         {
00914                 error_prompt("trainModel()", "Invalid subspace dimension");
00915                 return false;
00916         }
00917         //check if number of labels equals number of images in training set
00918         if (label_vec.size() != img_vec.size())
00919         {
00920                 return false;
00921         }
00922         //check if multiple classes and fallback  to eigenfaces if fallback_==true
00923         if (num_classes_ < 2)
00924         {
00925                 if (fallback_)
00926                 {
00927                         method = SubspaceAnalysis::METH_EIGEN;
00928                         std::cout << " Automatic Fallback to Eigenfaces" << std::endl;
00929                 }
00930                 else
00931                         return false;
00932         }
00933 
00934         //initialize all matrices
00935         model_data_arr_ = cv::Mat(img_vec.size(), img_vec[0].total(), CV_64FC1);
00936         model_label_arr_ = cv::Mat(1, label_vec.size(), CV_32FC1);
00937         avg_arr_ = cv::Mat(1, img_vec[0].total(), CV_64FC1);
00938         proj_model_data_arr_ = cv::Mat(img_vec.size(), ss_dim_, CV_64FC1);
00939         eigenvector_arr_ = cv::Mat(ss_dim_, img_vec[0].total(), CV_64FC1);
00940         eigenvalue_arr_ = cv::Mat(ss_dim_, ss_dim_, CV_64FC1);
00941 
00942         for (int i = 0; i < label_vec.size(); i++)
00943         {
00944                 model_label_arr_.at<float>(i) = static_cast<float>(label_vec[i]);
00945         }
00946 
00947         calcDataMat(img_vec, model_data_arr_);
00948 
00949         int pca_dim;
00950         cv::Mat proj_model_data_arr_PCA, P_pca, P_lda;
00951         switch (method)
00952         {
00953         case SubspaceAnalysis::METH_FISHER:
00954         {
00955                 std::cout << "FISHERFACES" << std::endl;
00956                 if (num_classes_ < 2)
00957                 {
00958                         std::cout << "FISHERFACES ERROR : More than one class is necessary" << std::endl;
00959                         return false;
00960                 }
00961                 //subspace dimension is num classes -1
00962                 ss_dim_ = num_classes_ - 1;
00963                 // pca dimension  is N- num classes
00964                 pca_dim = model_data_arr_.rows - num_classes_;
00965                 // Reduce dimension to  N - c via PCA
00966                 pca_ = SubspaceAnalysis::PCA(model_data_arr_, pca_dim);
00967                 proj_model_data_arr_PCA = cv::Mat(model_data_arr_.rows, pca_dim, CV_64FC1);
00968                 project(model_data_arr_, pca_.eigenvecs, pca_.mean, proj_model_data_arr_PCA);
00969 
00970                 // get projection matrix pca
00971                 P_pca = cv::Mat(pca_dim, img_vec[0].total(), CV_64FC1);
00972                 P_pca = pca_.eigenvecs;
00973                 avg_arr_ = pca_.mean;
00974 
00975                 //perform lda
00976                 lda_ = SubspaceAnalysis::LDA(proj_model_data_arr_PCA, label_vec, num_classes_, ss_dim_);
00977 
00978                 // get projection matrix lda
00979                 P_lda = cv::Mat(ss_dim_, pca_dim, CV_64FC1);
00980                 P_lda = lda_.eigenvecs;
00981 
00982                 // combine projection matrices
00983                 cv::gemm(P_pca.t(), P_lda.t(), 1.0, cv::Mat(), 0.0, eigenvector_arr_);
00984 
00985                 eigenvector_arr_ = eigenvector_arr_.t();
00986                 break;
00987 
00988                 case SubspaceAnalysis::METH_IFLDA:
00989                 {
00990                         if (num_classes_ < 2)
00991                         {
00992                                 std::cout << "Improved FISHERFACES ERROR : More than one class is necessary" << std::endl;
00993                                 return false;
00994                         }
00995                         //subspace dimension is num classes -1
00996                         ss_dim_ = num_classes_ - 1;
00997                         // pca dimension  is N- num classes
00998                         pca_dim = model_data_arr_.rows - num_classes_;
00999                         // Reduce dimension to  N - c via PCA
01000                         pca_ = SubspaceAnalysis::PCA(model_data_arr_, pca_dim);
01001                         proj_model_data_arr_PCA = cv::Mat(model_data_arr_.rows, pca_dim, CV_64FC1);
01002                         project(model_data_arr_, pca_.eigenvecs, pca_.mean, proj_model_data_arr_PCA);
01003 
01004                         // get projection matrix pca
01005                         P_pca = cv::Mat(pca_dim, img_vec[0].total(), CV_64FC1);
01006                         P_pca = pca_.eigenvecs;
01007                         avg_arr_ = pca_.mean;
01008 
01009                         //perform lda
01010                         lda_ = SubspaceAnalysis::ILDA(proj_model_data_arr_PCA, label_vec, num_classes_, ss_dim_);
01011 
01012                         // get projection matrix lda
01013                         P_lda = cv::Mat(ss_dim_, pca_dim, CV_64FC1);
01014                         P_lda = lda_.eigenvecs;
01015 
01016                         // combine projection matrices
01017                         cv::gemm(P_pca.t(), P_lda.t(), 1.0, cv::Mat(), 0.0, eigenvector_arr_);
01018 
01019                         eigenvector_arr_ = eigenvector_arr_.t();
01020                         break;
01021                 }
01022         }
01023 
01024         case SubspaceAnalysis::METH_EIGEN:
01025         {
01026                 std::cout << "EIGENFACES" << std::endl;
01027                 //initiate PCA
01028                 pca_ = SubspaceAnalysis::PCA(model_data_arr_, ss_dim_);
01029                 eigenvector_arr_ = pca_.eigenvecs;
01030                 eigenvalue_arr_ = pca_.eigenvals;
01031                 avg_arr_ = pca_.mean;
01032                 break;
01033         }
01034         case SubspaceAnalysis::METH_OCV_FISHER:
01035         {
01036                 std::cout << "OpenCv Fisherfaces" << std::endl;
01037                 cv::Ptr < cv::FaceRecognizer > model = cv::createFisherFaceRecognizer();
01038                 model->train(img_vec, label_vec);
01039                 //initiate PCA
01040                 eigenvector_arr_ = model->getMat("eigenvectors").t();
01041                 eigenvalue_arr_ = model->getMat("eigenvalues");
01042                 avg_arr_ = model->getMat("mean");
01043                 break;
01044         }
01045 
01046         }
01047 
01048         proj_model_data_arr_ = cv::Mat(img_vec.size(), ss_dim_, CV_64FC1);
01049 
01050         project(model_data_arr_, eigenvector_arr_, avg_arr_, proj_model_data_arr_);
01051 
01052         //calc_threshold(proj_model_data_arr_,thresholds_);
01053         if (use_unknown_thresh_)
01054         {
01055                 std::cout << "calculating threshold...";
01056                 calc_threshold(proj_model_data_arr_, thresh_);
01057                 std::cout << "done" << std::endl;
01058         }
01059         this->trained = true;
01060 
01061         return true;
01062 
01063 }
01064 
01065 //---------------------------------------------------------------------------------
01066 // SSA
01067 //---------------------------------------------------------------------------------
01068 void SubspaceAnalysis::SSA::calcDataMatMean(cv::Mat& data, cv::Mat& mean_row)
01069 {
01070         for (int i = 0; i < data.rows; ++i)
01071         {
01072                 cv::Mat data_row = data.row(i);
01073                 //calculate mean
01074                 cv::add(mean_row, data_row, mean_row);
01075         }
01076         mean_row.convertTo(mean_row, CV_64F, 1.0 / static_cast<double>(data.rows));
01077 
01078 }
01079 
01080 void SubspaceAnalysis::SSA::decompose2(cv::Mat& data_mat)
01081 {
01082 
01083         cv::Mat zero_mat = cv::Mat::zeros(1, data_mat.cols, CV_64FC1);
01084         cv::PCA pca(data_mat, zero_mat, CV_PCA_DATA_AS_ROW, ss_dim_);
01085         eigenvecs = pca.eigenvectors;
01086         //svd.u.copyTo(eigenvecs);
01087         //svd.w.copyTo(eigenvals);
01088         eigenvals = pca.eigenvalues;
01089 
01090 }
01091 void SubspaceAnalysis::SSA::decompose(cv::Mat& data_mat)
01092 {
01093 
01094         data_mat.convertTo(data_mat, CV_64F, 1 / sqrt(data_mat.rows));
01095         cv::SVD svd(data_mat.t());
01096         eigenvecs = svd.u;
01097         //svd.u.copyTo(eigenvecs);
01098         eigenvecs = eigenvecs.t();
01099         //svd.w.copyTo(eigenvals);
01100         eigenvals = svd.w;
01101 
01102 }
01103 
01104 //---------------------------------------------------------------------------------
01105 // LDA
01106 //---------------------mean_arr_row--------------------------------------------
01107 SubspaceAnalysis::LDA::LDA(cv::Mat& input_data, std::vector<int>& input_labels, int& num_classes, int& ss_dim)
01108 {
01109 
01110         SubspaceAnalysis::unique_elements(input_labels, num_classes_, unique_labels_);
01111         cv::Mat data_work = input_data.clone();
01112         mean = cv::Mat::zeros(1, data_work.cols, CV_64FC1);
01113         calcDataMatMean(data_work, mean);
01114         //class labels have to be in a vector in ascending order - duplicates are
01115         //removed internally
01116         //{0,0,1,2,3,3,4,5}
01117 
01118         class_mean_arr = cv::Mat::zeros(num_classes_, input_data.cols, CV_64FC1);
01119         calcClassMean(data_work, input_labels, class_mean_arr, num_classes_);
01120 
01121         calcProjMatrix(data_work, input_labels);
01122 
01123         eigenvecs = eigenvecs(cv::Rect(0, 0, input_data.cols, ss_dim));
01124         eigenvals = eigenvals(cv::Rect(0, 0, 1, ss_dim)).t();
01125         //cv::normalize(eigenvecs,eigenvecs);
01126 
01127 }
01128 void SubspaceAnalysis::LDA::calcClassMean(cv::Mat& data_mat, cv::Mat& label_mat, cv::Mat& class_mean_arr, int& num_classes)
01129 {
01130         std::vector<int> label_vec;
01131         for (int i = 0; i < label_mat.cols; i++)
01132         {
01133                 label_vec.push_back((int)label_mat.at<float>(i));
01134         }
01135 
01136         calcClassMean(data_mat, label_vec, class_mean_arr, num_classes);
01137 
01138 }
01139 void SubspaceAnalysis::LDA::calcClassMean(cv::Mat& data_mat, std::vector<int>& label_vec, cv::Mat& class_mean_arr, int& num_classes)
01140 {
01141 
01142         std::vector<int> samples_per_class(num_classes, 0);
01143 
01144         int class_index;
01145         for (int i = 0; i < data_mat.rows; i++)
01146         {
01147                 cv::Mat data_row = data_mat.row(i);
01148                 class_index = label_vec[i];
01149                 cv::Mat mean_row = class_mean_arr.row(class_index);
01150 
01151                 add(mean_row, data_row, mean_row);
01152                 samples_per_class[class_index]++;
01153         }
01154 
01155         for (int i = 0; i < num_classes; i++)
01156         {
01157                 cv::Mat mean_arr_row = class_mean_arr.row(i);
01158                 mean_arr_row.convertTo(mean_arr_row, CV_64FC1, 1.0 / static_cast<double>(samples_per_class[i]));
01159         }
01160 
01161 }
01162 
01163 void SubspaceAnalysis::LDA::calcProjMatrix(cv::Mat& data_arr, std::vector<int>& label_vec)
01164 {
01165 
01166         cv::Mat S_intra = cv::Mat::zeros(data_arr.cols, data_arr.cols, CV_64FC1);
01167         cv::Mat S_inter = cv::Mat::zeros(data_arr.cols, data_arr.cols, CV_64FC1);
01168         int class_index;
01169 
01170         for (int i = 0; i < data_arr.rows; ++i)
01171         {
01172                 //reduce data matrix
01173                 class_index = label_vec[i];
01174                 // std::cout<<"------------------------ "<<std::endl;
01175                 // std::cout<<"data before "<<data_arr.at<double>(i,0)<<std::endl;
01176                 cv::Mat data_row = data_arr.row(i);
01177                 cv::Mat class_mean_row = class_mean_arr.row(class_index);
01178                 // std::cout<<"data row before "<<data_row.at<double>(0)<<std::endl;
01179                 // std::cout<<"mean "<<class_mean_row.at<double>(0)<<std::endl;
01180                 cv::subtract(data_row, class_mean_row, data_row);
01181                 // std::cout<<"data row after" <<data_row.at<double>(0)<<std::endl;
01182                 // std::cout<<"data after " <<data_arr.at<double>(i,0)<<std::endl;
01183         }
01184         for (int c = 0; c < num_classes_; c++)
01185         {
01186                 cv::Mat temp;
01187                 class_index = unique_labels_[c];
01188                 cv::Mat class_mean_row = class_mean_arr.row(class_index);
01189                 cv::subtract(class_mean_row, mean, temp);
01190                 cv::mulTransposed(temp, temp, true);
01191                 cv::add(S_inter, temp, S_inter);
01192 
01193         }
01194         // //Intra class scatter
01195         cv::mulTransposed(data_arr, S_intra, true);
01196 
01197         cv::Mat S_intra_inv = S_intra.inv();
01198 
01199         cv::Mat P;
01200         gemm(S_intra_inv, S_inter, 1.0, cv::Mat(), 0.0, P);
01201 
01202         decompose(P);
01203 
01204         return;
01205 
01206 }
01207 
01208 //---------------------------------------------------------------------------------
01209 // ILDA
01210 //---------------------------------------------------------------------------------
01211 //
01212 SubspaceAnalysis::ILDA::ILDA(cv::Mat& input_data, std::vector<int>& input_labels, int& num_classes, int& ss_dim)
01213 {
01214         SubspaceAnalysis::unique_elements(input_labels, num_classes_, unique_labels_);
01215         cv::Mat data_work = input_data.clone();
01216         mean = cv::Mat::zeros(1, data_work.cols, CV_64FC1);
01217         calcDataMatMean(data_work, mean);
01218         num_classes_ = num_classes;
01219         //class labels have to be in a vector in ascending order - duplicates are
01220         //removed internally
01221         //{0,0,1,2,3,3,4,5}
01222 
01223         class_mean_arr = cv::Mat::zeros(num_classes_, input_data.cols, CV_64FC1);
01224         calcClassMean(data_work, input_labels, class_mean_arr, num_classes_);
01225 
01226         calcProjMatrix(data_work, input_labels);
01227 
01228         eigenvecs = eigenvecs(cv::Rect(0, 0, input_data.cols, ss_dim));
01229         eigenvals = eigenvals(cv::Rect(0, 0, 1, ss_dim)).t();
01230         //cv::normalize(eigenvecs,eigenvecs);
01231 }
01232 void SubspaceAnalysis::ILDA::calcProjMatrix(cv::Mat& data_arr, std::vector<int>& label_vec)
01233 {
01234         //TODO:DOESNT WORK YET
01235         //reduce data matrix with class means and compute inter class scatter
01236         // inter class scatter
01237         //
01238 
01239         cv::Mat S_intra = cv::Mat::zeros(data_arr.cols, data_arr.cols, CV_64FC1);
01240         cv::Mat S_inter = cv::Mat::zeros(data_arr.cols, data_arr.cols, CV_64FC1);
01241         int class_index;
01242 
01243         for (int i = 0; i < data_arr.rows; ++i)
01244         {
01245                 //reduce data matrix
01246                 class_index = label_vec[i];
01247                 // std::cout<<"------------------------ "<<std::endl;
01248                 // std::cout<<"data before "<<data_arr.at<double>(i,0)<<std::endl;
01249                 cv::Mat data_row = data_arr.row(i);
01250                 cv::Mat class_mean_row = class_mean_arr.row(class_index);
01251                 // std::cout<<"data row before "<<data_row.at<double>(0)<<std::endl;
01252                 // std::cout<<"mean "<<class_mean_row.at<double>(0)<<std::endl;
01253                 cv::subtract(data_row, class_mean_row, data_row);
01254                 // std::cout<<"data row after" <<data_row.at<double>(0)<<std::endl;
01255                 // std::cout<<"data after " <<data_arr.at<double>(i,0)<<std::endl;
01256         }
01257         for (int c = 0; c < num_classes_; c++)
01258         {
01259                 cv::Mat temp;
01260                 class_index = unique_labels_[c];
01261                 cv::Mat class_mean_row = class_mean_arr.row(class_index);
01262                 cv::subtract(class_mean_row, mean, temp);
01263                 cv::mulTransposed(temp, temp, true);
01264                 cv::add(S_inter, temp, S_inter);
01265 
01266         }
01267         // //Intra class scatter
01268         cv::mulTransposed(data_arr, S_intra, true);
01269         cv::Mat S_intra_inv = S_intra.inv();
01270         cv::Mat sigma = cv::Mat(1, num_classes_, CV_64FC1);
01271 
01272         for (int i = 0; i < num_classes_; ++i)
01273         {
01274                 cv::Mat mu_i = class_mean_arr.row(i);
01275                 for (int j = 0; j < num_classes_; ++j)
01276                 {
01277                         cv::Mat mu_j = class_mean_arr.row(j);
01278 
01279                         cv::Mat delta_ij = ((mu_j - mu_i) * S_intra_inv * (mu_j - mu_i).t());
01280                         for (int k = 0; k < data_arr.rows; k++)
01281                         {
01282 
01283                         }
01284                         sigma.at<double>(j) = 1 / (delta_ij.at<double>(0, 0));
01285                 }
01286 
01287         }
01288 
01289         for (int j = 0; j < num_classes_; j++)
01290         {
01291                 class_index = label_vec[j];
01292                 // std::cout<<"------------------------ "<<std::endl;
01293                 // std::cout<<"data before "<<data_arr.at<double>(i,0)<<std::endl;
01294                 cv::Mat s_intra_row = S_intra.row(j);
01295                 cv::Mat s_inter_row = S_inter.row(j);
01296                 double sigma_j = sigma.at<double>(class_index);
01297                 s_intra_row *= sigma_j;
01298                 s_inter_row *= sigma_j;
01299         }
01300 
01301         S_intra_inv = S_intra.inv();
01302 
01303         cv::Mat P;
01304         gemm(S_intra_inv, S_inter, 1.0, cv::Mat(), 0.0, P);
01305 
01306         decompose(P);
01307 
01308         return;
01309 
01310 }
01311 //---------------------------------------------------------------------------------
01312 // PCA
01313 //---------------------------------------------------------------------------------
01314 //
01315 SubspaceAnalysis::PCA::PCA(cv::Mat& input_data, int& ss_dim)
01316 {
01317         ss_dim_ = ss_dim;
01318         cv::Mat data_work = input_data.clone();
01319         mean = cv::Mat::zeros(1, data_work.cols, CV_64FC1);
01320         calcDataMatMean(data_work, mean);
01321         calcProjMatrix(data_work);
01322         //truncate eigenvectors and eigenvals
01323         eigenvecs = eigenvecs(cv::Rect(0, 0, input_data.cols, ss_dim));
01324         eigenvals = eigenvals(cv::Rect(0, 0, 1, ss_dim)).t();
01325         //cv::normalize(eigenvecs,eigenvecs);
01326 
01327         //cv::Mat dummy;
01328         //eigenvecs.copyTo(dummy);
01329         //dummy.convertTo(dummy,CV_8UC1,1000);
01330         //dummy =dummy.reshape(1,dummy.rows*160);
01331         //cv::equalizeHist(dummy,dummy);
01332         //cv::imwrite("/home/goa-tz/Desktop/eigenfaces.jpg",dummy);
01333 
01334 
01335 }
01336 
01337 void SubspaceAnalysis::PCA::calcProjMatrix(cv::Mat& data)
01338 {
01339         cv::Mat data_row;
01340         for (int i = 0; i < data.rows; ++i)
01341         {
01342                 //reduce data matrix - total Scatter matrix
01343                 data_row = data.row(i);
01344                 cv::subtract(data_row, mean, data_row);
01345         }
01346 
01347         decompose(data);
01348 }
01349 


cob_people_detection
Author(s): Richard Bormann , Thomas Zwölfer
autogenerated on Fri Aug 28 2015 10:24:13