people_detector.cpp
Go to the documentation of this file.
00001 
00002 
00003 #ifdef __LINUX__
00004 #include "cob_people_detection/people_detector.h"
00005 #include "cob_vision_utils/GlobalDefines.h"
00006 #else
00007 #include "cob_vision/cob_people_detection/common/include/cob_people_detection/PeopleDetector.h"
00008 #include "cob_common/cob_vision_utils/common/include/cob_vision_utils/GlobalDefines.h"
00009 #endif
00010 
00011 #include <opencv/cv.h>
00012 #include <opencv/cvaux.h>
00013 
00014 using namespace ipa_PeopleDetector;
00015 
00016 PeopleDetector::PeopleDetector(void)
00017 {
00018         m_face_cascade = 0;
00019         m_range_cascade = 0;
00020 }
00021 
00022 unsigned long PeopleDetector::Init(std::string directory)
00023 {
00024         // Load Haar-Classifier for frontal face-, eyes- and body-detection
00025         std::string faceCascadePath = directory + "haarcascades/haarcascade_frontalface_alt2.xml";
00026         // todo:
00027         std::string rangeCascadePath = directory + "haarcascades/haarcascade_range_multiview_5p_bg.xml";
00028         //std::string rangeCascadePath = directory + "haarcascades/haarcascade_range_multiview_5p_bg+.xml";     // + "haarcascades/haarcascade_range.xml";
00029         m_face_cascade = (CvHaarClassifierCascade*)cvLoad(faceCascadePath.c_str(), 0, 0, 0); //"ConfigurationFiles/haarcascades/haarcascade_frontalface_alt2.xml", 0, 0, 0 );
00030         m_range_cascade = (CvHaarClassifierCascade*)cvLoad(rangeCascadePath.c_str(), 0, 0, 0);
00031 
00032         // Create Memory
00033         m_storage = cvCreateMemStorage(0);
00034 
00035         return ipa_Utils::RET_OK;
00036 }
00037 
00038 PeopleDetector::~PeopleDetector(void)
00039 {
00040         // Release Classifiers and memory
00041         cvReleaseHaarClassifierCascade(&m_face_cascade);
00042         cvReleaseHaarClassifierCascade(&m_range_cascade);
00043         cvReleaseMemStorage(&m_storage);
00044 }
00045 
00046 unsigned long PeopleDetector::DetectColorFaces(cv::Mat& img, std::vector<cv::Rect>& faceCoordinates)
00047 {
00048         IplImage imgPtr = (IplImage)img;
00049         CvSeq* faces = cvHaarDetectObjects(&imgPtr, m_face_cascade, m_storage, m_faces_increase_search_scale, m_faces_drop_groups, CV_HAAR_DO_CANNY_PRUNING,
00050                         cvSize(m_faces_min_search_scale_x, m_faces_min_search_scale_y));
00051 
00052         cv::Size parentSize;
00053         cv::Point roiOffset;
00054         for (int i = 0; i < faces->total; i++)
00055         {
00056                 cv::Rect* face = (cv::Rect*)cvGetSeqElem(faces, i);
00057                 img.locateROI(parentSize, roiOffset);
00058                 face->x += roiOffset.x; // todo: check what happens if the original matrix is used without roi
00059                 face->y += roiOffset.y;
00060                 faceCoordinates.push_back(*face);
00061         }
00062 
00063         return ipa_Utils::RET_OK;
00064 }
00065 
00066 unsigned long PeopleDetector::InterpolateUnassignedPixels(cv::Mat& img)
00067 {
00068         CV_Assert( img.type() == CV_8UC3 )
00069                 ;
00070 
00071         cv::Mat temp = img.clone();
00072 
00073         uchar* data = img.data;
00074         uchar* data2 = temp.data;
00075         int stride = img.step;
00076         for (int repetitions = 0; repetitions < 10; repetitions++)
00077         {
00078                 // each pixel with a value can propagate its value to black pixels in the 4 pixel neighborhoud
00079                 for (int v = 1; v < img.rows - 1; v++)
00080                 {
00081                         for (int u = 1; u < img.cols - 1; u++)
00082                         {
00083                                 // only pixels with a value can propagate their value
00084                                 int index = v * stride + 3 * u;
00085                                 if (data[index] != 0)
00086                                 {
00087                                         uchar val = data[index];
00088                                         if (data2[index - 3] == 0)
00089                                                 for (int i = -3; i < 0; i++)
00090                                                         data2[index + i] = val; // left
00091                                         if (data2[index + 3] == 0)
00092                                                 for (int i = 3; i < 6; i++)
00093                                                         data2[index + i] = val; // right
00094                                         if (data2[index - stride] == 0)
00095                                                 for (int i = -stride; i < -stride + 3; i++)
00096                                                         data2[index + i] = val; // up
00097                                         if (data2[index + stride] == 0)
00098                                                 for (int i = stride; i < stride + 3; i++)
00099                                                         data2[index + i] = val; // down
00100                                 }
00101                         }
00102                 }
00103                 // copy back new data
00104                 for (int i = 0; i < img.rows * stride; i++)
00105                         data[i] = data2[i];
00106         }
00107         return ipa_Utils::RET_OK;
00108 }
00109 
00110 unsigned long PeopleDetector::DetectRangeFace(cv::Mat& img, std::vector<cv::Rect>& rangeFaceCoordinates, bool fillUnassignedDepthValues)
00111 {
00112         rangeFaceCoordinates.clear();
00113 
00114         if (fillUnassignedDepthValues)
00115                 InterpolateUnassignedPixels(img);
00116         //cv::namedWindow("depth image");
00117         //cv::imshow("depth image", img);
00118         //cv::waitKey(10);
00119         IplImage imgPtr = (IplImage)img;
00120         CvSeq* rangeFaces = cvHaarDetectObjects(&imgPtr, m_range_cascade, m_storage, m_range_increase_search_scale, m_range_drop_groups, CV_HAAR_DO_CANNY_PRUNING,
00121                         cvSize(m_range_min_search_scale_x, m_range_min_search_scale_y));
00122 
00123         for (int i = 0; i < rangeFaces->total; i++)
00124         {
00125                 cv::Rect *rangeFace = (cv::Rect*)cvGetSeqElem(rangeFaces, i);
00126                 rangeFaceCoordinates.push_back(*rangeFace);
00127         }
00128 
00129         return ipa_Utils::RET_OK;
00130 }
00131 
00132 unsigned long PeopleDetector::DetectFaces(cv::Mat& img, cv::Mat& rangeImg, std::vector<cv::Rect>& colorFaceCoordinates, std::vector<cv::Rect>& rangeFaceCoordinates,
00133                 std::set<size_t>& colorToRangeFaceDependency, bool fillUnassignedDepthValues)
00134 {
00135         colorFaceCoordinates.clear();
00136         colorToRangeFaceDependency.clear();
00137 
00138         //######################################## Option1 ########################################
00139         DetectRangeFace(rangeImg, rangeFaceCoordinates, fillUnassignedDepthValues);
00140         for (int i = 0; i < (int)rangeFaceCoordinates.size(); i++)
00141         {
00142                 cv::Rect rangeFace = rangeFaceCoordinates[i];
00143 
00144                 rangeFace.y += (int)(rangeFace.height * 0.1);
00145 
00146                 cv::Mat areaImg = img(rangeFace);
00147 
00148                 // Detect color Faces and store the corresponding range face index if images were found
00149                 size_t numberColorFacesBefore = colorFaceCoordinates.size();
00150                 DetectColorFaces(areaImg, colorFaceCoordinates);
00151                 if ((colorFaceCoordinates.size() - numberColorFacesBefore) != 0)
00152                         colorToRangeFaceDependency.insert(i);
00153         }
00154         //######################################## /Option1 ########################################
00155 
00156         //######################################## Option2 ########################################
00157         /*DetectRangeFace(rangeImg, rangeFaceCoordinates);
00158          IplImage imgPtr = (IplImage)img;
00159          IplImage* areaImg = cvCloneImage(&imgPtr);
00160          char* rowPtr = 0;
00161          for (int row=0; row<areaImg->height; row++ )
00162          {
00163          rowPtr = (char*)(areaImg->imageData + row*areaImg->widthStep);
00164          for (int col=0; col<areaImg->width; col++ )
00165          {
00166          bool inrect=false;
00167          for(int i=0; i<(int)rangeFaceCoordinates->size(); i++)
00168          {
00169          cv::Rect rangeFace = rangeFaceCoordinates[i];
00170 
00171          rangeFace.y += rangeFace.height*0.1;
00172 
00173          if((col > rangeFace.x && col < (rangeFace.x + rangeFace.width)) && (row > rangeFace.y && row < (rangeFace.y + rangeFace.height)))
00174          {
00175          inrect=true;
00176          break;
00177          }
00178          }
00179 
00180          if(!inrect)
00181          {
00182          rowPtr[col*3] = 0;
00183          rowPtr[col*3+1] = 0;
00184          rowPtr[col*3+2] = 0;
00185          }
00186          }
00187          }
00188 
00189          // Detect color Faces
00190          cv::Mat areaImgMat(areaImg);
00191          DetectColorFaces(areaImgMat, colorFaceCoordinates);
00192          areaImgMat.release();
00193          cvReleaseImage(&areaImg);*/
00194         //######################################## /Option2 ########################################
00195 
00196         return ipa_Utils::RET_OK;
00197 }
00198 
00199 unsigned long PeopleDetector::AddFace(cv::Mat& img, cv::Rect& face, std::string id, std::vector<cv::Mat>& images, std::vector<std::string>& ids)
00200 {
00201         //IplImage *resized_8U1 = cvCreateImage(cvSize(100, 100), 8, 1);
00202         cv::Mat resized_8U1(100, 100, CV_8UC1);
00203         ConvertAndResize(img, resized_8U1, face);
00204 
00205         // Save image
00206         images.push_back(resized_8U1);
00207         ids.push_back(id);
00208 
00209         return ipa_Utils::RET_OK;
00210 }
00211 
00212 unsigned long PeopleDetector::ConvertAndResize(cv::Mat& img, cv::Mat& resized, cv::Rect& face)
00213 {
00214         cv::Mat temp;
00215         cv::cvtColor(img, temp, CV_BGR2GRAY);
00216         cv::Mat roi = temp(face);
00217         cv::resize(roi, resized, resized.size());
00218 
00219         return ipa_Utils::RET_OK;
00220 }
00221 
00222 cv::Mat PeopleDetector::preprocessImage(cv::Mat& input_image)
00223 {
00224         // todo:
00225         return input_image;
00226 
00227         // do a modified census transform
00228         cv::Mat output(input_image.cols, input_image.rows, input_image.type());
00229         //cv::Mat smoothedImage = input_image.clone();
00230         //cv::GaussianBlur(smoothedImage, smoothedImage, cv::Size(3,3), 0, 0, cv::BORDER_REPLICATE);
00231 
00232         for (int v = 0; v < input_image.rows; v++)
00233         {
00234                 uchar* srcPtr = input_image.ptr(v);
00235                 //uchar* smoothPtr = smoothedImage.ptr(v);
00236                 uchar* outPtr = output.ptr(v);
00237                 for (int u = 0; u < input_image.cols; u++)
00238                 {
00239                         int ctOutcome = 0;
00240                         int offset = -1;
00241                         for (int dv = -1; dv <= 1; dv++)
00242                         {
00243                                 for (int du = -1; du <= 1; du++)
00244                                 {
00245                                         if (dv == 0 && du == 0)
00246                                                 continue;
00247                                         offset++;
00248                                         if (v + dv < 0 || v + dv >= input_image.rows || u + du < 0 || u + du >= input_image.cols)
00249                                                 continue;
00250                                         //if (*smoothPtr < *(srcPtr+dv*input_image.step+du)) ctOutcome += 1<<offset;
00251                                         if (*srcPtr < *(srcPtr + dv * input_image.step + du))
00252                                                 ctOutcome += 1 << offset;
00253                                 }
00254                         }
00255                         *outPtr = ctOutcome;
00256 
00257                         srcPtr++;
00258                         outPtr++;
00259                 }
00260         }
00261 
00262         //      cv::imshow("census transform", output);
00263         //      cv::waitKey();
00264 
00265         return output;
00266 }
00267 
00268 unsigned long PeopleDetector::PCA(int* nEigens, std::vector<cv::Mat>& eigenVectors, cv::Mat& eigenValMat, cv::Mat& avgImage, std::vector<cv::Mat>& faceImages,
00269                 cv::Mat& projectedTrainFaceMat)
00270 {
00271         CvTermCriteria calcLimit;
00272 
00273         // Set the number of eigenvalues to use
00274         (*nEigens) = faceImages.size() - 1;
00275 
00276         // Allocate memory
00277         cv::Size faceImgSize(faceImages[0].cols, faceImages[0].rows);
00278         eigenVectors.resize(*nEigens, cv::Mat(faceImgSize, CV_32FC1));
00279         eigenValMat.create(1, *nEigens, CV_32FC1);
00280         avgImage.create(faceImgSize, CV_32FC1);
00281 
00282         // Set the PCA termination criterion
00283         calcLimit = cvTermCriteria(CV_TERMCRIT_ITER, (*nEigens), 1);
00284 
00285         // Convert vector to array
00286         IplImage** faceImgArr = (IplImage**)cvAlloc((int)faceImages.size() * sizeof(IplImage*));
00287         for (int j = 0; j < (int)faceImages.size(); j++)
00288         {
00289                 // todo: preprocess
00290                 cv::Mat preprocessedImage = preprocessImage(faceImages[j]);
00291                 IplImage temp = (IplImage)preprocessedImage;
00292                 faceImgArr[j] = cvCloneImage(&temp);
00293         }
00294 
00295         // Convert vector to array
00296         IplImage** eigenVectArr = (IplImage**)cvAlloc((int)eigenVectors.size() * sizeof(IplImage*));
00297         for (int j = 0; j < (int)eigenVectors.size(); j++)
00298         {
00299                 IplImage temp = (IplImage)eigenVectors[j];
00300                 eigenVectArr[j] = cvCloneImage(&temp);
00301         }
00302 
00303         // Compute average image, eigenvalues, and eigenvectors
00304         IplImage avgImageIpl = (IplImage)avgImage;
00305         cvCalcEigenObjects((int)faceImages.size(), (void*)faceImgArr, (void*)eigenVectArr, CV_EIGOBJ_NO_CALLBACK, 0, 0, &calcLimit, &avgImageIpl, (float*)(eigenValMat.data));
00306 
00307         // todo:
00308         cv::normalize(eigenValMat, eigenValMat, 1, 0, /*CV_L1*/CV_L2); //, 0);          0=bug?
00309 
00310         // Project the training images onto the PCA subspace
00311         projectedTrainFaceMat.create(faceImages.size(), *nEigens, CV_32FC1);
00312         for (int i = 0; i < (int)faceImages.size(); i++)
00313         {
00314                 IplImage temp = (IplImage)faceImages[i];
00315                 cvEigenDecomposite(&temp, *nEigens, eigenVectArr, 0, 0, &avgImageIpl, (float*)projectedTrainFaceMat.data + i * *nEigens); //attention: if image step of projectedTrainFaceMat is not *nEigens * sizeof(float) then reading functions which access with (x,y) coordinates might fail
00316         };
00317 
00318         // Copy back
00319         int eigenVectorsCount = (int)eigenVectors.size();
00320         eigenVectors.clear();
00321         for (int i = 0; i < (int)eigenVectorsCount; i++)
00322                 eigenVectors.push_back(cv::Mat(eigenVectArr[i], true));
00323 
00324         // Clean
00325         for (int i = 0; i < (int)faceImages.size(); i++)
00326                 cvReleaseImage(&(faceImgArr[i]));
00327         for (int i = 0; i < (int)eigenVectors.size(); i++)
00328                 cvReleaseImage(&(eigenVectArr[i]));
00329         cvFree(&faceImgArr);
00330         cvFree(&eigenVectArr);
00331 
00332         return ipa_Utils::RET_OK;
00333 }
00334 
00335 unsigned long PeopleDetector::RecognizeFace(cv::Mat& colorImage, std::vector<cv::Rect>& colorFaceCoordinates, int* nEigens, std::vector<cv::Mat>& eigenVectors, cv::Mat& avgImage,
00336                 cv::Mat& faceClassAvgProjections, std::vector<int>& index, int *threshold, int *threshold_FS, cv::Mat& eigenValMat, cv::SVM* personClassifier)
00337 {
00338         float* eigenVectorWeights = 0;
00339 
00340         cv::Mat resized_8U1(100, 100, CV_8UC1); // = cvCreateImage(cvSize(100, 100), 8, 1);
00341 
00342         eigenVectorWeights = (float *)cvAlloc(*nEigens * sizeof(float));
00343 
00344         // Convert vector to array
00345         IplImage** eigenVectArr = (IplImage**)cvAlloc((int)eigenVectors.size() * sizeof(IplImage*));
00346         for (int j = 0; j < (int)eigenVectors.size(); j++)
00347         {
00348                 IplImage temp = (IplImage)eigenVectors[j];
00349                 eigenVectArr[j] = cvCloneImage(&temp);
00350         }
00351 
00352         for (int i = 0; i < (int)colorFaceCoordinates.size(); i++)
00353         {
00354                 cv::Rect face = colorFaceCoordinates[i];
00355                 ConvertAndResize(colorImage, resized_8U1, face);
00356                 // todo: preprocess
00357                 cv::Mat preprocessedImage = preprocessImage(resized_8U1);
00358 
00359                 IplImage avgImageIpl = (IplImage)avgImage;
00360 
00361                 // Project the test image onto the PCA subspace
00362                 IplImage resized_8U1Ipl = (IplImage)resized_8U1;
00363                 cvEigenDecomposite(&resized_8U1Ipl, *nEigens, eigenVectArr, 0, 0, &avgImageIpl, eigenVectorWeights);
00364 
00365                 // Calculate FaceSpace Distance
00366                 cv::Mat srcReconstruction = cv::Mat::zeros(eigenVectors[0].size(), eigenVectors[0].type());
00367                 for (int i = 0; i < (int)eigenVectors.size(); i++)
00368                         srcReconstruction += eigenVectorWeights[i] * eigenVectors[i];
00369                 cv::Mat temp;
00370 
00371                 // todo:
00372                 //              cv::Mat reconstrTemp = srcReconstruction + avgImage;
00373                 //              cv::Mat reconstr(eigenVectors[0].size(), CV_8UC1);
00374                 //              reconstrTemp.convertTo(reconstr, CV_8UC1, 1);
00375                 //              cv::imshow("reconstruction", reconstr);
00376                 //              cv::waitKey();
00377 
00378                 resized_8U1.convertTo(temp, CV_32FC1, 1.0 / 255.0);
00379                 double distance = cv::norm((temp - avgImage), srcReconstruction, cv::NORM_L2);
00380 
00381                 //######################################## Only for debugging and development ########################################
00382                 //std::cout.precision( 10 );
00383                 std::cout << "FS_Distance: " << distance << std::endl;
00384                 //######################################## /Only for debugging and development ########################################
00385 
00386                 // -2=distance to face space is too high
00387                 // -1=distance to face classes is too high
00388                 if (distance > *threshold_FS)
00389                 {
00390                         // No face
00391                         index.push_back(-2);
00392                         //index.push_back(-2); why twice? apparently makes no sense.
00393                 }
00394                 else
00395                 {
00396                         int nearest;
00397                         ClassifyFace(eigenVectorWeights, &nearest, nEigens, faceClassAvgProjections, threshold, eigenValMat, personClassifier);
00398                         if (nearest < 0)
00399                                 index.push_back(-1); // Face Unknown
00400                         else
00401                                 index.push_back(nearest); // Face known, it's number nearest
00402                 }
00403         }
00404 
00405         // Clear
00406         for (int i = 0; i < (int)eigenVectors.size(); i++)
00407                 cvReleaseImage(&(eigenVectArr[i]));
00408         cvFree(&eigenVectorWeights);
00409         cvFree(&eigenVectArr);
00410         return ipa_Utils::RET_OK;
00411 }
00412 
00413 unsigned long PeopleDetector::ClassifyFace(float *eigenVectorWeights, int *nearest, int *nEigens, cv::Mat& faceClassAvgProjections, int *threshold, cv::Mat& eigenValMat,
00414                 cv::SVM* personClassifier)
00415 {
00416         double leastDistSq = DBL_MAX;
00417         //todo:
00418         int metric = 2; // 0 = Euklid, 1 = Mahalanobis, 2 = Mahalanobis Cosine
00419 
00420 
00421         for (int i = 0; i < faceClassAvgProjections.rows; i++)
00422         {
00423                 double distance = 0;
00424                 double cos = 0;
00425                 double length_sample = 0;
00426                 double length_projection = 0;
00427                 for (int e = 0; e < *nEigens; e++)
00428                 {
00429                         if (metric < 2)
00430                         {
00431                                 float d = eigenVectorWeights[e] - ((float*)(faceClassAvgProjections.data))[i * *nEigens + e];
00432                                 if (metric == 0)
00433                                         distance += d * d; //Euklid
00434                                 else
00435                                         distance += d * d /* / *// ((float*)(eigenValMat.data))[e]; //Mahalanobis
00436                         }
00437                         else
00438                         {
00439                                 cos += eigenVectorWeights[e] * ((float*)(faceClassAvgProjections.data))[i * *nEigens + e] / ((float*)(eigenValMat.data))[e];
00440                                 length_projection += ((float*)(faceClassAvgProjections.data))[i * *nEigens + e] * ((float*)(faceClassAvgProjections.data))[i * *nEigens + e]
00441                                                 / ((float*)(eigenValMat.data))[e];
00442                                 length_sample += eigenVectorWeights[e] * eigenVectorWeights[e] / ((float*)(eigenValMat.data))[e];
00443                         }
00444                 }
00445                 if (metric < 2)
00446                         distance = sqrt(distance);
00447                 else
00448                 {
00449                         length_sample = sqrt(length_sample);
00450                         length_projection = sqrt(length_projection);
00451                         cos /= (length_projection * length_sample);
00452                         distance = -cos;
00453                 }
00454 
00455                 //######################################## Only for debugging and development ########################################
00456                 //std::cout.precision( 10 );
00457                 std::cout << "Distance_FC: " << distance << std::endl;
00458                 //######################################## /Only for debugging and development ########################################
00459 
00460                 if (distance < leastDistSq)
00461                 {
00462                         leastDistSq = distance;
00463                         if (leastDistSq > *threshold)
00464                                 *nearest = -1;
00465                         else
00466                                 *nearest = i;
00467                 }
00468         }
00469 
00470         // todo:
00471         //      if (personClassifier != 0 && *nearest != -1)
00472         //      {
00473         //              cv::Mat temp(1, *nEigens, CV_32FC1, eigenVectorWeights);
00474         //              std::cout << "class. output: " << (int)personClassifier->predict(temp) << "\n";
00475         //              *nearest = (int)personClassifier->predict(temp);
00476         //      }
00477 
00478         return ipa_Utils::RET_OK;
00479 }
00480 
00481 unsigned long PeopleDetector::CalculateFaceClasses(cv::Mat& projectedTrainFaceMat, std::vector<std::string>& id, int *nEigens, cv::Mat& faceClassAvgProjections,
00482                 std::vector<std::string>& idUnique, cv::SVM* personClassifier)
00483 {
00484         std::cout << "PeopleDetector::CalculateFaceClasses ... ";
00485 
00486         // Look for face classes
00487         idUnique.clear();
00488         for (int i = 0; i < (int)id.size(); i++)
00489         {
00490                 std::string face_class = id[i];
00491                 bool class_exists = false;
00492 
00493                 for (int j = 0; j < (int)idUnique.size(); j++)
00494                 {
00495                         if (!idUnique[j].compare(face_class))
00496                         {
00497                                 class_exists = true;
00498                         }
00499                 }
00500 
00501                 if (!class_exists)
00502                 {
00503                         idUnique.push_back(face_class);
00504                 }
00505         }
00506 
00507         //id.clear();
00508         //cv::Mat faces_tmp = projectedTrainFaceMat.clone();
00509         cv::Mat temp = cv::Mat::zeros((int)idUnique.size(), *nEigens, projectedTrainFaceMat.type());
00510         temp.convertTo(faceClassAvgProjections, projectedTrainFaceMat.type());
00511         //for (int i=0; i<((int)idUnique.size() * *nEigens); i++)
00512         //      for (int i=0; i<((int)id.size() * *nEigens); i++)
00513         //      {
00514         //              ((float*)(projectedTrainFaceMat.data))[i] = 0;
00515         //      }
00516 
00517         // Look for FaceClasses
00518         //      for(int i=0; i<(int)idUnique.size(); i++)
00519         //      {
00520         //              std::string face_class = idUnique[i];
00521         //              bool class_exists = false;
00522         //
00523         //              for(int j=0; j<(int)id.size(); j++)
00524         //              {
00525         //                      if(!id[j].compare(face_class))
00526         //                      {
00527         //                              class_exists = true;
00528         //                      }
00529         //              }
00530         //
00531         //              if(!class_exists)
00532         //              {
00533         //                      id.push_back(face_class);
00534         //              }
00535         //      }
00536 
00537         //      cv::Size newSize(id.size(), *nEigens);
00538         //      projectedTrainFaceMat.create(newSize, faces_tmp.type());
00539 
00540         // Calculate FaceClasses
00541         for (int i = 0; i < (int)idUnique.size(); i++)
00542         {
00543                 std::string face_class = idUnique[i];
00544 
00545                 for (int e = 0; e < *nEigens; e++)
00546                 {
00547                         int count = 0;
00548                         for (int j = 0; j < (int)id.size(); j++)
00549                         {
00550                                 if (!(id[j].compare(face_class)))
00551                                 {
00552                                         ((float*)(faceClassAvgProjections.data))[i * *nEigens + e] += ((float*)(projectedTrainFaceMat.data))[j * *nEigens + e];
00553                                         count++;
00554                                 }
00555                         }
00556                         ((float*)(faceClassAvgProjections.data))[i * *nEigens + e] /= (float)count;
00557                 }
00558         }
00559 
00560         // todo: machine learning technique for person identification
00561         if (personClassifier != 0)
00562         {
00563                 //std::cout << "\n";
00564                 // prepare ground truth
00565                 cv::Mat data(id.size(), *nEigens, CV_32FC1);
00566                 cv::Mat labels(id.size(), 1, CV_32SC1);
00567                 std::ofstream fout("svm.dat", std::ios::out);
00568                 for (int sample = 0; sample < (int)id.size(); sample++)
00569                 {
00570                         // copy data
00571                         for (int e = 0; e < *nEigens; e++)
00572                         {
00573                                 data.at<float>(sample, e) = ((float*)projectedTrainFaceMat.data)[sample * *nEigens + e];
00574                                 fout << data.at<float>(sample, e) << "\t";
00575                         }
00576                         // find corresponding label
00577                         for (int i = 0; i < (int)idUnique.size(); i++) // for each person
00578                                 if (!(id[sample].compare(idUnique[i]))) // compare the labels
00579                                         labels.at<int>(sample) = i; // and assign the corresponding label's index from the idUnique list
00580                         fout << labels.at<int>(sample) << "\n";
00581                 }
00582                 fout.close();
00583 
00584                 // train the classifier
00585                 cv::SVMParams svmParams(CvSVM::NU_SVC, CvSVM::RBF, 0.0, 0.001953125, 0.0, 0.0, 0.8, 0.0, 0, cv::TermCriteria(CV_TERMCRIT_ITER + CV_TERMCRIT_EPS, 100, FLT_EPSILON));
00586                 //personClassifier->train_auto(data, labels, cv::Mat(), cv::Mat(), svmParams, 10, cv::SVM::get_default_grid(CvSVM::C), CvParamGrid(0.001953125, 2.01, 2.0), cv::SVM::get_default_grid(CvSVM::P), CvParamGrid(0.0125, 1.0, 2.0));
00587                 personClassifier->train(data, labels, cv::Mat(), cv::Mat(), svmParams);
00588                 cv::SVMParams svmParamsOptimal = personClassifier->get_params();
00589                 std::cout << "Optimal SVM params: gamma=" << svmParamsOptimal.gamma << "  nu=" << svmParamsOptimal.nu << "\n";
00590         }
00591 
00592         std::cout << "done\n";
00593 
00594         return ipa_Utils::RET_OK;
00595 }
00596 


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