PageRenderTime 59ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/ facerecog --username xjed09/FaceMngr/FaceMngr_fast.cpp

http://facerecog.googlecode.com/
C++ | 269 lines | 208 code | 49 blank | 12 comment | 31 complexity | df1e2d470d2c2a2614232275eb6f45bb MD5 | raw file
  1. #define DLLSRC
  2. #include "FaceMngr_fast.h"
  3. #include <iostream>
  4. #ifdef COMPILE_MNGR_FAST
  5. CFaceMngr::CFaceMngr(void)
  6. {
  7. tfaceImg8 = tfaceImg32 = tfeature = tmodel = m_models = NULL;
  8. m_ids = NULL;
  9. align = NULL;
  10. light = NULL;
  11. feature = NULL;
  12. ss = NULL;
  13. }
  14. CFaceMngr::~CFaceMngr(void)
  15. {
  16. cvReleaseMat(&tfaceImg8);
  17. cvReleaseMat(&tfaceImg32);
  18. cvReleaseMat(&tfeature);
  19. cvReleaseMat(&tmodel);
  20. cvReleaseMat(&m_models);
  21. delete []m_ids;
  22. delete align;
  23. delete light;
  24. delete feature;
  25. delete ss;
  26. }
  27. bool CFaceMngr::Init( CvSize faceSz /*= cvSize(0,0)*/ )
  28. {
  29. align = new CFaceAlign;
  30. if (! align->Init(faceSz)) return false;
  31. m_faceSz = align->m_faceSz;
  32. light = new CLightPrep;
  33. if (! light->Init(m_faceSz, true)) return false;
  34. feature = new CFaceFeature;
  35. if (! (m_featureSz = feature->Init(m_faceSz, light->m_mask))) return false;
  36. ss = new CSubspace;
  37. tfaceImg8 = cvCreateMat(m_faceSz.height, m_faceSz.width, CV_8UC1);
  38. tfaceImg32 = cvCreateMat(m_faceSz.height, m_faceSz.width, CV_FT_FC1);
  39. tfeature = cvCreateMat(m_featureSz, 1, CV_FT_FC1);
  40. return true;
  41. }
  42. bool CFaceMngr::Pic2NormFace( CvArr *pic, CvMat *faceImg8, DWORD flag /*= FM_DO_NORM*/,
  43. CvPoint2D32f *leftEye /*= NULL*/, CvPoint2D32f *rightEye /*= NULL*/ )
  44. {
  45. if (flag & FM_DO_FACE_ALIGN)
  46. { // ?????????
  47. if ( ! align->GetFace((IplImage*)pic, faceImg8, leftEye, rightEye) ) // ???FaceAlign_Coord?
  48. return false;
  49. }
  50. else cvResize(pic, faceImg8, CV_INTER_NN); // if flag & FM_DO_FACE_ALIGN
  51. if (flag & FM_DO_LIGHT_PREP)
  52. light->RunLightPrep(faceImg8);
  53. return true;
  54. }
  55. bool CFaceMngr::NormFace2Model( CvArr *faceImg8, CvMat *model )
  56. {
  57. cvConvertScale(faceImg8, tfaceImg32, 1.0/255);
  58. feature->GetFeature(tfaceImg32, tfeature);
  59. ss->Project(tfeature, model);
  60. return true;
  61. }
  62. bool CFaceMngr::BatchPicEnroll( LPCTSTR rootPath, vector<SFInfo> &enrList, DWORD flag )
  63. {
  64. /* ??? */
  65. if ( ! HasTrained() || m_models != NULL ) return false;
  66. if (flag & FM_SHOW_DETAIL) cout<<"Enrolling..."<<endl;
  67. /* ??? */
  68. m_enrNum = enrList.size();
  69. CvMat *fts = cvCreateMat(m_featureSz, m_enrNum, CV_FT_FC1);
  70. CvMat col;
  71. CString strRp = rootPath;
  72. int idx = 0;
  73. m_ids = new int[m_enrNum];
  74. /* ???????????? */
  75. sfi_iter iter = enrList.begin();
  76. for (; iter != enrList.end(); iter++)
  77. {
  78. CString path = strRp + iter->picPath;
  79. IplImage *img = cvLoadImage(path, CV_LOAD_IMAGE_GRAYSCALE);
  80. if (!img)
  81. {
  82. ::MessageBox1(path+" not found.");
  83. exit(1);
  84. }
  85. Pic2NormFace(img, tfaceImg8, flag, &(iter->leye), &(iter->reye));
  86. cvConvertScale(tfaceImg8, tfaceImg32, 1.0/255);
  87. cvGetCol(fts, &col, idx);
  88. feature->GetFeature(tfaceImg32, &col);
  89. m_ids[idx++] = iter->classId;
  90. cvReleaseImage(&img);
  91. }
  92. /* ???????? */
  93. m_models = cvCreateMat(m_modelSz, m_enrNum, CV_MODEL_FC1);
  94. ss->Project(fts, m_models);
  95. cvReleaseMat(&fts);
  96. return true;
  97. }
  98. bool CFaceMngr::Train( LPCTSTR rootPath, vector<SFInfo> &trainList, DWORD flag )
  99. {
  100. /* ??? */
  101. cvReleaseMat(&m_models);
  102. delete []m_ids;
  103. if (flag & FM_SHOW_DETAIL) cout<<"Training..."<<endl<<"\tComputing Feature..."<<endl;
  104. //tic();
  105. /* ??? */
  106. m_trainNum = trainList.size();
  107. CvMat *fts = cvCreateMat(m_featureSz, m_trainNum, CV_FT_FC1);
  108. CvMat col;
  109. CString strRp = rootPath;
  110. int idx = 0;
  111. m_ids = new int[m_trainNum];
  112. /* ???????????? */
  113. sfi_iter iter = trainList.begin();
  114. for (; iter != trainList.end(); iter++)
  115. {
  116. CString path = strRp + iter->picPath;
  117. IplImage *img = cvLoadImage(path, CV_LOAD_IMAGE_GRAYSCALE);
  118. if (!img)
  119. {
  120. ::MessageBox1(path+" not found.");
  121. exit(1);
  122. }
  123. Pic2NormFace(img, tfaceImg8, flag, &(iter->leye), &(iter->reye));
  124. cvConvertScale(tfaceImg8, tfaceImg32, 1.0/255);
  125. cvGetCol(fts, &col, idx);
  126. feature->GetFeature(tfaceImg32, &col);
  127. m_ids[idx++] = iter->classId;
  128. cvReleaseImage(&img);
  129. }
  130. /* ?? */
  131. //double t1 = toc();
  132. if (flag & FM_SHOW_DETAIL) cout<<"\tComputing Subspace..."<<endl;
  133. ss->Train(fts, m_ids);
  134. m_modelSz = ss->GetSubspaceDim();
  135. tmodel = cvCreateMat(m_modelSz, 1, CV_MODEL_FC1);
  136. /* ???????? */
  137. if (flag & FM_TRAIN_SAVE2MODEL)
  138. {
  139. m_models = cvCreateMat(m_modelSz, m_trainNum, CV_MODEL_FC1);
  140. ss->Project(fts, m_models);
  141. }
  142. else
  143. delete []m_ids;
  144. cvReleaseMat(&fts);
  145. m_trainclsNum = ss->classNum;
  146. return true;
  147. }
  148. bool CFaceMngr::HasTrained()
  149. {
  150. return ss->m_bTrained;
  151. }
  152. bool CFaceMngr::ModelRecognize( CvMat *model, SMatch *info)
  153. {
  154. double minDist = 1e9, curVal; // minDist should be among -1~1 for angle metric
  155. int curMatch = 0;
  156. CvMat col;
  157. // ???Matlab?????????tmodel Repeat??????Mul,Reduce,MinMaxLoc???????????????
  158. for (int i = 0; i < m_trainNum; i++)
  159. {
  160. cvGetCol(m_models, &col, i);
  161. curVal = ss->CalcVectorDist(&col, tmodel);
  162. if (curVal < minDist)
  163. {
  164. minDist = curVal;
  165. curMatch = i;
  166. }
  167. }
  168. info->classId = m_ids[curMatch];
  169. info->dist = minDist;
  170. return true;
  171. }
  172. bool CFaceMngr::PicRecognize( CvArr *pic, DWORD flag, SMatch *info, CvPoint2D32f *leye /*= NULL*/, CvPoint2D32f *reye /*= NULL*/ )
  173. {
  174. Pic2NormFace(pic, tfaceImg8, flag, leye, reye);
  175. NormFace2Model(tfaceImg8, tmodel);
  176. ModelRecognize(tmodel, info);
  177. return true;
  178. }
  179. double CFaceMngr::BatchPicRecog( LPCTSTR rootPath, vector<SFInfo> &testList, vector<SMatch> &resList, DWORD flag )
  180. {
  181. if (flag & FM_SHOW_DETAIL) cout<<"Recognizing..."<<endl;
  182. sfi_iter testIter = testList.begin();
  183. int correctNum = 0;
  184. SMatch info;
  185. for (; testIter != testList.end(); testIter++)
  186. {
  187. CString path = rootPath;
  188. path += testIter->picPath;
  189. IplImage *img = cvLoadImage(path, CV_LOAD_IMAGE_GRAYSCALE);
  190. if (!img)
  191. {
  192. ::MessageBox1(path+" not found.");
  193. exit(1);
  194. }
  195. PicRecognize(img, flag, &info, &(testIter->leye), &(testIter->reye));
  196. resList.push_back(info);
  197. if (info.classId == testIter->classId) correctNum++;
  198. }
  199. return (double)correctNum/testList.size();
  200. }
  201. bool CFaceMngr::WriteMatToFile( ofstream &os )
  202. {
  203. ss->WriteDataToFile(os);
  204. return true;
  205. }
  206. bool CFaceMngr::ReadMatFromFile( ifstream &is )
  207. {
  208. bool ret = ss->ReadDataFromFile(is);
  209. if (ss->inputDim != m_featureSz)
  210. {
  211. ss->Release();
  212. MessageBox1("Feature size not match!");
  213. return false;
  214. }
  215. m_modelSz = ss->GetSubspaceDim();
  216. cvReleaseMat(&tmodel);
  217. tmodel = cvCreateMat(m_modelSz, 1, CV_MODEL_FC1);
  218. return ret;
  219. }
  220. #endif