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


cob_people_detection
Author(s): Richard Bormann , Thomas Zwölfer
autogenerated on Mon May 6 2019 02:32:06