PageRenderTime 263ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/ facerecog --username xjed09/frtest/EnrollDlg.cpp

http://facerecog.googlecode.com/
C++ | 358 lines | 289 code | 50 blank | 19 comment | 37 complexity | c826fade042a2f5ad98494f4c83e655f MD5 | raw file
  1. // EnrollDlg.cpp : ????
  2. //
  3. #include "stdafx.h"
  4. #include "frtest.h"
  5. #include "EnrollDlg.h"
  6. #include "WndUtils.h"
  7. #include "ProjDefs.h"
  8. // CEnrollDlg ???
  9. IMPLEMENT_DYNAMIC(CEnrollDlg, CDialog)
  10. CEnrollDlg::CEnrollDlg(CWnd* pParent /*=NULL*/)
  11. : CDialog(CEnrollDlg::IDD, pParent)
  12. , m_strName(_T(""))
  13. , m_bSaveSmallImg(true)
  14. {
  15. m_thrdFace = NULL;
  16. noface = cvLoadImage("noface.bmp");
  17. }
  18. CEnrollDlg::~CEnrollDlg()
  19. {
  20. cvReleaseImage(&noface);
  21. }
  22. void CEnrollDlg::DoDataExchange(CDataExchange* pDX)
  23. {
  24. CDialog::DoDataExchange(pDX);
  25. DDX_Text(pDX, IDC_NAME, m_strName);
  26. //DDX_Text(pDX, IDC_CLASSID, m_strClassId);
  27. DDX_Check(pDX, IDC_SAVE_SMALL, m_bSaveSmallImg);
  28. }
  29. BOOL CEnrollDlg::OnInitDialog() // ??DoModal??????
  30. {
  31. CDialog::OnInitDialog();
  32. faceSz = g_faceMngr->m_faceSz;
  33. showSz = faceSz;
  34. if (showSz.height != 160) // (160*130)??????????????????????
  35. showSz *= (160.0/showSz.height);
  36. if (showSz.width > 130)
  37. showSz *= (130.0/showSz.width);
  38. EmbedCvWindow(GetDlgItem(IDC_FACE)->m_hWnd, "face", showSz.width, showSz.height);
  39. if (noface) cvShowImage("face", noface);
  40. RECT rc;
  41. GetWindowRect(&rc);
  42. SetWindowPos(NULL, rc.left + 15, rc.top + 300, 0,0, SWP_NOSIZE | SWP_NOZORDER);
  43. m_nShootNum = 0;
  44. m_strName = "";
  45. UpdateData(FALSE);
  46. CWnd *pBtn = GetDlgItem(IDC_SHOOT);
  47. RECT rc1;
  48. pBtn->GetClientRect(&rc1);
  49. pBtn->SetWindowText("??");
  50. pBtn->SetWindowPos(NULL, 0,0, 35, rc1.bottom-rc1.top, SWP_NOMOVE | SWP_NOZORDER);
  51. GetDlgItem(IDC_DEL_SHOOT)->ShowWindow(SW_HIDE);
  52. GetDlgItem(IDC_ENROLL_PIC)->ShowWindow(SW_SHOW);
  53. GetDlgItem(IDC_IMPORT_MODELS)->ShowWindow(SW_SHOW);
  54. if (g_bHasWebcam)
  55. {
  56. m_frame = cvCreateImage(g_webcam.GetFrameSize(), IPL_DEPTH_8U, 3);
  57. SetDlgItemText(IDC_SHOOT_GUIDE,
  58. "?????????????????“??”?\n"
  59. "??????,??????????????????????\n"
  60. "????????????????3~4??");
  61. m_bFaceStarted = true;
  62. m_thrdFace = ::AfxBeginThread(ShowFaceProc, this);
  63. }
  64. else
  65. {
  66. m_frame = NULL;
  67. SetDlgItemText(IDC_SHOOT_GUIDE, "");
  68. CWnd *pWnd = GetDlgItem(IDC_SHOOT);
  69. pWnd->EnableWindow(FALSE);
  70. }
  71. return TRUE;
  72. }
  73. BEGIN_MESSAGE_MAP(CEnrollDlg, CDialog)
  74. ON_BN_CLICKED(IDC_SHOOT, &CEnrollDlg::OnBnClickedShoot)
  75. ON_BN_CLICKED(IDCANCEL, &CEnrollDlg::OnBnClickedCancel)
  76. ON_BN_CLICKED(IDOK, &CEnrollDlg::OnBnClickedOk)
  77. ON_BN_CLICKED(IDC_ENROLL_PIC, &CEnrollDlg::OnBnClickedEnrollPic)
  78. ON_BN_CLICKED(IDC_IMPORT_MODELS, &CEnrollDlg::OnBnClickedImportModels)
  79. ON_BN_CLICKED(IDC_ADV, &CEnrollDlg::OnBnClickedAdv)
  80. ON_BN_CLICKED(IDC_DEL_SHOOT, &CEnrollDlg::OnBnClickedDelShoot)
  81. END_MESSAGE_MAP()
  82. // CEnrollDlg ??????
  83. void CEnrollDlg::OnBnClickedShoot()
  84. {
  85. // TODO: ??????????????
  86. if (!m_bFoundFace) return;
  87. //CFaceAlign* &al = g_faceMngr->align;
  88. #ifndef COMPILE_ALIGN_COORD
  89. CvRect rc = g_faceMngr->align->m_rcCurFace;
  90. CvSize fsz = g_webcam.GetFrameSize();
  91. // ???????????????
  92. if (rc.x < fsz.width * 5 / 100 ||
  93. rc.x + rc.width > fsz.width * 98 / 100 ||
  94. rc.y < fsz.height * 5 / 100 ||
  95. rc.y + g_faceMngr->align->m_dis*16/6 > fsz.height*95/100||
  96. rc.width < fsz.width / 4 ||
  97. rc.width > fsz.width * .7 ||
  98. rc.height < fsz.height *.4 ||
  99. rc.height > fsz.height*9/10)
  100. {
  101. ::AfxMessageBox("??????????????????????");
  102. return;
  103. }
  104. #endif
  105. CWnd *pBtn = GetDlgItem(IDC_SHOOT);
  106. RECT rc1;
  107. pBtn->GetClientRect(&rc1);
  108. pBtn->SetWindowText("?????");
  109. pBtn->SetWindowPos(NULL, 0,0, 70, rc1.bottom-rc1.top, SWP_NOMOVE | SWP_NOZORDER);
  110. GetDlgItem(IDC_DEL_SHOOT)->ShowWindow(SW_SHOW);
  111. GetDlgItem(IDC_ENROLL_PIC)->ShowWindow(SW_HIDE);
  112. GetDlgItem(IDC_IMPORT_MODELS)->ShowWindow(SW_HIDE);
  113. CString title;
  114. title.Format("pic %d", m_nShootNum++);
  115. cvNamedWindow(title, 0);
  116. cvResizeWindow(title, showSz.width, showSz.height);
  117. cvShowImage(title, faceImg8);
  118. IplImage *pic1 = cvCloneImage(m_frame);
  119. m_lstPic.AddTail(pic1);
  120. CvMat *face = cvCloneMat(faceImg8);
  121. m_lstFace.AddTail(face);
  122. }
  123. UINT CEnrollDlg::ShowFace()
  124. {
  125. faceImg8 = cvCreateMat(faceSz.height, faceSz.width, CV_8UC1);
  126. m_bFoundFace = false;
  127. while(m_bFaceStarted)
  128. {
  129. g_webcam.GetFrame(m_frame);
  130. m_bFoundFace = g_faceMngr->Pic2NormFace(m_frame, faceImg8, FM_DO_NORM | FM_ALIGN_USE_BUF);
  131. if (m_bFoundFace)
  132. {
  133. cvShowImage("face", faceImg8);
  134. //m_bFoundFace = true;
  135. }
  136. else cvShowImage("face", noface);
  137. cvWaitKey(1);
  138. Sleep(100);
  139. }
  140. cvReleaseMat(&faceImg8);
  141. // ????cvDestroyWindow
  142. return 0;
  143. }
  144. UINT ShowFaceProc( LPVOID pParam )
  145. {
  146. CEnrollDlg *pDlg = (CEnrollDlg *)pParam;
  147. return pDlg->ShowFace();
  148. }
  149. void CEnrollDlg::OnBnClickedCancel()
  150. {
  151. // TODO: ??????????????
  152. //m_nClassId--; // ????
  153. Release();
  154. OnCancel();
  155. }
  156. void CEnrollDlg::OnBnClickedOk()
  157. {
  158. // TODO: ??????????????
  159. UpdateData(TRUE);
  160. if (m_nShootNum > 0)
  161. {
  162. if (m_strName.IsEmpty())
  163. {
  164. ::AfxMessageBox("????????");
  165. return;
  166. }
  167. if (!g_faceMngr->HasTrained())
  168. {
  169. CString msg;
  170. /*msg.Format("?????????????? %s ,?????????????? %s , ?????????\n"
  171. "????????????????????", g_strPicPath, FACE_REL_PATH);
  172. if (::AfxMessageBox(msg, MB_YESNO) == IDYES)*/ SaveShootPics(false);
  173. }
  174. else SaveShootPics(true);
  175. }
  176. Release();
  177. OnOK();
  178. }
  179. void CEnrollDlg::SaveShootPics( bool bSave2Model )
  180. {
  181. CString fn;
  182. ::CreateDirectory(g_strPicPath, NULL);
  183. POSITION pos = m_lstPic.GetHeadPosition(), pos1 = m_lstFace.GetHeadPosition();
  184. for (int i = 0; i < m_nShootNum; i++)
  185. {
  186. fn.Format("%s_%d.bmp", m_strName, i);
  187. cvSaveImage(g_strPicPath+fn, m_lstPic.GetNext(pos)); // ?????????????
  188. if (m_bSaveSmallImg>0)
  189. {
  190. ::CreateDirectory(g_strFacePath, NULL);
  191. cvSaveImage(g_strFacePath+fn, m_lstFace.GetNext(pos1));
  192. }
  193. if (bSave2Model)
  194. if (m_bSaveSmallImg>0)
  195. g_faceMngr->SavePicToModel(g_strFacePath+fn, FM_UNKNOWN_CLASS_ID, FM_DO_NOT_NORM);
  196. else g_faceMngr->SavePicToModel(g_strPicPath+fn, FM_UNKNOWN_CLASS_ID, FM_DO_NORM);
  197. }
  198. CString msg;
  199. msg.Format("???%d????????????%d????", m_nShootNum, g_faceMngr->GetModelCount());
  200. ::AfxMessageBox(msg, MB_OK | MB_ICONINFORMATION);
  201. }
  202. void CEnrollDlg::Release()
  203. {
  204. if (g_bHasWebcam)
  205. {
  206. m_bFaceStarted = false;
  207. if (m_thrdFace) ::WaitForSingleObject(m_thrdFace->m_hThread, INFINITE); // ??????
  208. }
  209. CString title;
  210. POSITION pos = m_lstPic.GetHeadPosition(), pos1 = m_lstFace.GetHeadPosition();
  211. for (int i = 0; i < m_nShootNum; i++)
  212. {
  213. title.Format("pic %d", i);
  214. cvDestroyWindow(title);
  215. cvReleaseImage(& m_lstPic.GetNext(pos));
  216. cvReleaseMat(& m_lstFace.GetNext(pos1));
  217. }
  218. m_lstPic.RemoveAll();
  219. m_lstFace.RemoveAll();
  220. cvReleaseImage(&m_frame);
  221. cvDestroyWindow("face");
  222. }
  223. void CEnrollDlg::OnBnClickedEnrollPic()
  224. {
  225. // TODO: ??????????????
  226. if (! g_faceMngr->HasTrained())
  227. {
  228. ::AfxMessageBox("?????");
  229. return;
  230. }
  231. if (g_bHasWebcam)
  232. {
  233. m_bFaceStarted = false;
  234. if (m_thrdFace) ::WaitForSingleObject(m_thrdFace->m_hThread, INFINITE);
  235. }
  236. UpdateData(TRUE);
  237. CFileDialog dlgFile(TRUE, 0, 0, OFN_ALLOWMULTISELECT | OFN_NOCHANGEDIR | OFN_HIDEREADONLY);
  238. if (dlgFile.DoModal() == IDOK)
  239. {
  240. POSITION pos = dlgFile.GetStartPosition();
  241. int enrollNum = 0;
  242. while (pos)
  243. {
  244. CString path = dlgFile.GetNextPathName(pos);
  245. DWORD flag = FM_DO_NORM;
  246. if (m_bSaveSmallImg) flag |= FM_SAVE_NORM_FACE;
  247. if (g_faceMngr->SavePicToModel(path, FM_UNKNOWN_CLASS_ID, flag)) enrollNum++;
  248. }
  249. CString msg;
  250. msg.Format("???%d????????????%d????", enrollNum, g_faceMngr->GetModelCount());
  251. ::AfxMessageBox(msg, MB_OK | MB_ICONINFORMATION);
  252. }
  253. if (g_bHasWebcam)
  254. {
  255. m_bFaceStarted = true;
  256. m_thrdFace = ::AfxBeginThread(ShowFaceProc, this);
  257. }
  258. }
  259. void CEnrollDlg::OnBnClickedImportModels()
  260. {
  261. // TODO: ??????????????
  262. CFileDialog dlgFile(TRUE, "frmodel", 0, OFN_NOCHANGEDIR | OFN_HIDEREADONLY,
  263. "?????? (*.frmodel)|*.frmodel||");
  264. if (dlgFile.DoModal() == IDOK)
  265. {
  266. CString path = dlgFile.GetPathName();
  267. setlocale(LC_ALL, "Chinese-simplified"); //??????
  268. ifstream is(path, ios::binary);
  269. if (!is)
  270. {
  271. ::AfxMessageBox(path+" : ?????");
  272. return;
  273. }
  274. int readNum = g_faceMngr->ReadModelFromFile(is);
  275. CString msg;
  276. msg.Format("???%d??????%d????\n?????????????????",
  277. readNum, g_faceMngr->GetModelCount());
  278. ::AfxMessageBox(msg, MB_OK | MB_ICONINFORMATION);
  279. is.close();
  280. setlocale(LC_ALL, "C");// ??
  281. if (m_nShootNum == 0) OnBnClickedCancel();
  282. }
  283. }
  284. void CEnrollDlg::OnBnClickedAdv()
  285. {
  286. // TODO: ??????????????
  287. m_dlgAdv.DoModal();
  288. }
  289. void CEnrollDlg::OnBnClickedDelShoot()
  290. {
  291. // TODO: ??????????????
  292. CString title;
  293. title.Format("pic %d", --m_nShootNum);
  294. cvDestroyWindow(title);
  295. m_lstPic.RemoveTail();
  296. m_lstFace.RemoveTail();
  297. if(m_nShootNum == 0)
  298. {
  299. CWnd *pBtn = GetDlgItem(IDC_SHOOT);
  300. RECT rc1;
  301. pBtn->GetClientRect(&rc1);
  302. pBtn->SetWindowText("??");
  303. pBtn->SetWindowPos(NULL, 0,0, 35, rc1.bottom-rc1.top, SWP_NOMOVE | SWP_NOZORDER);
  304. GetDlgItem(IDC_DEL_SHOOT)->ShowWindow(SW_HIDE);
  305. GetDlgItem(IDC_ENROLL_PIC)->ShowWindow(SW_SHOW);
  306. GetDlgItem(IDC_IMPORT_MODELS)->ShowWindow(SW_SHOW);
  307. }
  308. }