TestSIFTDlg.cpp
上传用户:yli86818
上传日期:2014-07-15
资源大小:273k
文件大小:11k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. // TestSIFTDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "TestSIFT.h"
  5. #include "TestSIFTDlg.h"
  6. #include "SIFT.h"
  7. #include "cvcam.h"
  8. #include "MatchInfo.h"
  9. #include "MinHeap.h"
  10. #ifdef _DEBUG
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15. IplImage *grayImg = NULL;
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CAboutDlg dialog used for App About
  18. class CAboutDlg : public CDialog
  19. {
  20. public:
  21. CAboutDlg();
  22. // Dialog Data
  23. //{{AFX_DATA(CAboutDlg)
  24. enum { IDD = IDD_ABOUTBOX };
  25. //}}AFX_DATA
  26. // ClassWizard generated virtual function overrides
  27. //{{AFX_VIRTUAL(CAboutDlg)
  28. protected:
  29. virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  30. //}}AFX_VIRTUAL
  31. // Implementation
  32. protected:
  33. //{{AFX_MSG(CAboutDlg)
  34. //}}AFX_MSG
  35. DECLARE_MESSAGE_MAP()
  36. };
  37. CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
  38. {
  39. //{{AFX_DATA_INIT(CAboutDlg)
  40. //}}AFX_DATA_INIT
  41. }
  42. void CAboutDlg::DoDataExchange(CDataExchange* pDX)
  43. {
  44. CDialog::DoDataExchange(pDX);
  45. //{{AFX_DATA_MAP(CAboutDlg)
  46. //}}AFX_DATA_MAP
  47. }
  48. BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  49. //{{AFX_MSG_MAP(CAboutDlg)
  50. // No message handlers
  51. //}}AFX_MSG_MAP
  52. END_MESSAGE_MAP()
  53. /////////////////////////////////////////////////////////////////////////////
  54. // CTestSIFTDlg dialog
  55. CTestSIFTDlg::CTestSIFTDlg(CWnd* pParent /*=NULL*/)
  56. : CDialog(CTestSIFTDlg::IDD, pParent)
  57. {
  58. //{{AFX_DATA_INIT(CTestSIFTDlg)
  59. m_pause = FALSE;
  60. //}}AFX_DATA_INIT
  61. // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
  62. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  63. }
  64. void CTestSIFTDlg::DoDataExchange(CDataExchange* pDX)
  65. {
  66. CDialog::DoDataExchange(pDX);
  67. //{{AFX_DATA_MAP(CTestSIFTDlg)
  68. DDX_Check(pDX, IDC_CHK_PAUSE, m_pause);
  69. //}}AFX_DATA_MAP
  70. }
  71. BEGIN_MESSAGE_MAP(CTestSIFTDlg, CDialog)
  72. //{{AFX_MSG_MAP(CTestSIFTDlg)
  73. ON_WM_SYSCOMMAND()
  74. ON_WM_PAINT()
  75. ON_WM_QUERYDRAGICON()
  76. ON_BN_CLICKED(ID_EXIT, OnExit)
  77. ON_BN_CLICKED(IDC_BTN_CAM, OnBtnCam)
  78. ON_WM_CLOSE()
  79. ON_BN_CLICKED(IDC_BTN_TRACK, OnBtnTrack)
  80. ON_BN_CLICKED(IDC_CHK_PAUSE, OnChkPause)
  81. //}}AFX_MSG_MAP
  82. END_MESSAGE_MAP()
  83. /////////////////////////////////////////////////////////////////////////////
  84. // CTestSIFTDlg message handlers
  85. BOOL CTestSIFTDlg::OnInitDialog()
  86. {
  87. CDialog::OnInitDialog();
  88. // Add "About..." menu item to system menu.
  89. // IDM_ABOUTBOX must be in the system command range.
  90. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
  91. ASSERT(IDM_ABOUTBOX < 0xF000);
  92. CMenu* pSysMenu = GetSystemMenu(FALSE);
  93. if (pSysMenu != NULL)
  94. {
  95. CString strAboutMenu;
  96. strAboutMenu.LoadString(IDS_ABOUTBOX);
  97. if (!strAboutMenu.IsEmpty())
  98. {
  99. pSysMenu->AppendMenu(MF_SEPARATOR);
  100. pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
  101. }
  102. }
  103. // Set the icon for this dialog.  The framework does this automatically
  104. //  when the application's main window is not a dialog
  105. SetIcon(m_hIcon, TRUE); // Set big icon
  106. SetIcon(m_hIcon, FALSE); // Set small icon
  107. // TODO: Add extra initialization here
  108. return TRUE;  // return TRUE  unless you set the focus to a control
  109. }
  110. void CTestSIFTDlg::OnSysCommand(UINT nID, LPARAM lParam)
  111. {
  112. if ((nID & 0xFFF0) == IDM_ABOUTBOX)
  113. {
  114. CAboutDlg dlgAbout;
  115. dlgAbout.DoModal();
  116. }
  117. else
  118. {
  119. CDialog::OnSysCommand(nID, lParam);
  120. }
  121. }
  122. // If you add a minimize button to your dialog, you will need the code below
  123. //  to draw the icon.  For MFC applications using the document/view model,
  124. //  this is automatically done for you by the framework.
  125. void CTestSIFTDlg::OnPaint() 
  126. {
  127. if (IsIconic())
  128. {
  129. CPaintDC dc(this); // device context for painting
  130. SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);
  131. // Center icon in client rectangle
  132. int cxIcon = GetSystemMetrics(SM_CXICON);
  133. int cyIcon = GetSystemMetrics(SM_CYICON);
  134. CRect rect;
  135. GetClientRect(&rect);
  136. int x = (rect.Width() - cxIcon + 1) / 2;
  137. int y = (rect.Height() - cyIcon + 1) / 2;
  138. // Draw the icon
  139. dc.DrawIcon(x, y, m_hIcon);
  140. }
  141. else
  142. {
  143. CDialog::OnPaint();
  144. }
  145. }
  146. // The system calls this to obtain the cursor to display while the user drags
  147. //  the minimized window.
  148. HCURSOR CTestSIFTDlg::OnQueryDragIcon()
  149. {
  150. return (HCURSOR) m_hIcon;
  151. }
  152. /// Begin Global functions 
  153. void drawSq (CKeyPoint* kp,IplImage* img)
  154. {
  155. CvPoint pt[4];
  156. int size = 10;
  157. size *= kp->m_imgScale;
  158. pt[0] = cvPoint (-size,-size);
  159. pt[1] = cvPoint (-size,size);
  160. pt[2] = cvPoint (size,size);
  161. pt[3] = cvPoint (size,-size);
  162. for (int i = 0; i < 4; i++)
  163. {
  164. double angle = kp->m_orientation;
  165. double xR = cos (angle) * pt[i].x - sin (angle) * pt[i].y;
  166. double yR = sin (angle) * pt[i].x + cos (angle) * pt[i].y;
  167. pt[i] = cvPoint ((int)(kp->m_x+xR),(int)(kp->m_y+yR));
  168. }
  169. for (i = 0; i < 4; i++)
  170. cvLine(img, pt[i], pt[(i+1)%4], cvScalar(0,255,255),1);
  171. cvLine (img,cvPoint(kp->m_x,kp->m_y),cvPoint((pt[2].x+pt[3].x)/2,(pt[2].y+pt[3].y)/2),cvScalar(0,255,255),1);
  172. }
  173. std::vector <CKeyPoint*> keypoints0;
  174. std::vector <CKeyPoint*> keypoints1;
  175. BOOL isPause = false;
  176. void callback (IplImage *camImg)
  177. {
  178. if (isPause)
  179. return;
  180. cvFlip (camImg,NULL,0);
  181. camImg->origin = 0;
  182. if (grayImg == NULL)
  183. grayImg = cvCreateImage (cvGetSize(camImg),IPL_DEPTH_8U,1);
  184. cvCvtColor (camImg,grayImg,CV_RGB2GRAY);
  185. CSIFT sift;
  186. keypoints0.clear();
  187. sift.detect(grayImg,&keypoints0);
  188. for (int i = 0; i < keypoints0.size(); i++)
  189. drawSq (keypoints0[i],camImg);
  190. for (i = 0; i < keypoints0.size(); i++)
  191. delete keypoints0[i];
  192. cvShowImage ("cam",camImg);
  193. }
  194. CMatchInfo findNearest (CKeyPoint* kp0,int index0,std::vector<CKeyPoint*>& keypoints)
  195. {
  196. CMinHeap heap;
  197. for (int index1 = 0; index1 < keypoints.size(); index1++)
  198. {
  199. CKeyPoint* kp1 = keypoints[index1];
  200. int dim = kp0->m_xDim*kp0->m_yDim*kp0->m_oDim;
  201. double dist = 0;
  202. double secondMin = heap.get2ndMin();
  203. bool tooLarge = false;
  204. for (int j = 0; j < dim; j++)
  205. {
  206. double diff = (kp0->m_featureVec[j]-kp1->m_featureVec[j]);
  207. dist += diff * diff;
  208. if (dist > secondMin)
  209. {
  210. tooLarge = true;
  211. break;
  212. }
  213. }
  214. if (tooLarge)
  215. continue;
  216. CMatchInfo info;
  217.   info.m_distance = dist;
  218. info.m_index0 = index0;
  219. info.m_index1 = index1;
  220. heap.insert (info);
  221. }
  222. if (heap.getSize() >= 2)
  223. {
  224. CMatchInfo min1st = heap.deleteMin();
  225. CMatchInfo min2nd = heap.deleteMin();
  226. double ratio = min1st.m_distance/min2nd.m_distance;
  227. if (ratio < 0.8)
  228. return min1st;
  229. }
  230. CMatchInfo dummy;
  231. return dummy;
  232. }
  233. void findCorrespond (std::vector<CKeyPoint*>& keypoints0,std::vector<CKeyPoint*>& keypoints1,
  234.  CMinHeap& corrHeap)
  235. {
  236. for (int i = 0; i < keypoints0.size(); i++)
  237. {
  238. CMatchInfo info = findNearest (keypoints0[i],i,keypoints1);
  239. if (info.m_index0 >= 0)
  240. corrHeap.insert (info);
  241. }
  242. }
  243. IplImage *showImg = NULL;
  244. void stereocallback (IplImage *camImg0, IplImage *camImg1)
  245. {
  246. if (isPause)
  247. return;
  248. cvFlip (camImg0,NULL,0);
  249. camImg0->origin = 0;
  250. cvFlip (camImg1,NULL,0);
  251. camImg1->origin = 0;
  252. CSIFT sift;
  253. keypoints0.clear();
  254. keypoints1.clear();
  255. if (grayImg == NULL)
  256. grayImg = cvCreateImage (cvGetSize(camImg0),IPL_DEPTH_8U,1);
  257. cvCvtColor (camImg0,grayImg,CV_RGB2GRAY);
  258. sift.detect(grayImg,&keypoints0);
  259. cvCvtColor (camImg1,grayImg,CV_RGB2GRAY);
  260. sift.detect(grayImg,&keypoints1);
  261. int i;
  262. //for (i = 0; i < keypoints0.size(); i++)
  263. // drawSq (keypoints0[i],camImg0);
  264. //for (i = 0; i < keypoints1.size(); i++)
  265. // drawSq (keypoints1[i],camImg1);
  266. //TRACE ("%d , %dn",keypoints0.size(),keypoints1.size());
  267. if (showImg == NULL)
  268. showImg = cvCreateImage (cvSize(cvGetSize(camImg0).width*2,cvGetSize(camImg0).height),IPL_DEPTH_8U,3);
  269. cvSetImageROI (showImg,cvRect(0,0,cvGetSize(camImg0).width,cvGetSize(camImg1).height));
  270. cvCopy (camImg0,showImg);
  271. cvSetImageROI (showImg,cvRect(cvGetSize(camImg0).width,0,cvGetSize(camImg0).width,cvGetSize(camImg1).height));
  272. cvCopy (camImg1,showImg);
  273. cvSetImageROI (showImg,cvRect(0,0,cvGetSize(camImg0).width*2,cvGetSize(camImg0).height));
  274. CMinHeap corrHeap;
  275. findCorrespond (keypoints0,keypoints1,corrHeap);
  276. //TRACE ("Correct match : %dn",corrHeap.getSize());
  277. if (corrHeap.getSize() >= 10)
  278. for (i = 0; i < 10; i++) 
  279. {
  280. CMatchInfo info = corrHeap.deleteMin();
  281. //TRACE ("Found matchn");
  282. CvPoint pt0 = cvPoint (keypoints0[info.m_index0]->m_x,keypoints0[info.m_index0]->m_y);
  283. CvPoint pt1 = cvPoint (keypoints1[info.m_index1]->m_x,keypoints1[info.m_index1]->m_y);
  284. pt1.x += cvGetSize(camImg0).width;
  285. cvCircle(showImg, pt0, 2, cvScalar(0,0,255), 2);
  286. cvCircle(showImg, pt1, 2, cvScalar(0,0,255), 2);
  287. cvLine(showImg, pt0, pt1, cvScalar(0,0,255),1);
  288. }
  289. for (i = 0; i < keypoints0.size(); i++)
  290. delete keypoints0[i];
  291. for (i = 0; i < keypoints1.size(); i++)
  292. delete keypoints1[i];
  293. cvShowImage ("cam",showImg);
  294. }
  295. /// End Global functions 
  296. void CTestSIFTDlg::OnClose() 
  297. {
  298. ClearResource();
  299. CDialog::OnClose();
  300. }
  301. void CTestSIFTDlg::OnExit() 
  302. {
  303. ClearResource();
  304. DestroyWindow();
  305. }
  306. void CTestSIFTDlg::ClearResource()
  307. {
  308. cvcamStop( );
  309. cvcamExit( );
  310. cvDestroyWindow ("Image");
  311. if (grayImg != NULL)
  312. cvReleaseImage (&grayImg);
  313. if (showImg != NULL)
  314. cvReleaseImage (&showImg);
  315. cvDestroyWindow ("cam");
  316. }
  317. void CTestSIFTDlg::OnBtnCam() 
  318. {
  319. cvNamedWindow ("cam",CV_WINDOW_AUTOSIZE);
  320. //cvCreateTrackbar ("mode","Debug",&debugindex,PARAMCOUNT-1,NULL);//trackChange);
  321. int ncams = cvcamGetCamerasCount();
  322. if (ncams == 0)
  323. {
  324. MessageBox ("Please plug-in camera");
  325. return;
  326. }
  327. cvcamSetProperty(0, CVCAM_PROP_ENABLE, CVCAMTRUE);
  328. //cvcamSetProperty(0, CVCAM_PROP_RENDER, CVCAMTRUE);
  329. cvcamSetProperty(0, CVCAM_PROP_CALLBACK, callback);
  330. cvcamInit( );
  331. cvcamStart( );
  332. cvDestroyWindow ("cvcam window");
  333. }
  334. void CTestSIFTDlg::OnBtnTrack() 
  335. {
  336. // TODO: Add your control notification handler code here
  337. if (cvcamGetCamerasCount() < 2)
  338. {
  339. MessageBox ("Please plug-in 2 cameras");
  340. return;
  341. }
  342. cvNamedWindow ("cam",CV_WINDOW_AUTOSIZE);
  343. cvcamSetProperty(0, CVCAM_PROP_ENABLE, CVCAMTRUE); 
  344. cvcamSetProperty(1, CVCAM_PROP_ENABLE, CVCAMTRUE); 
  345. int width = 320;
  346. int height = 240;
  347. cvcamSetProperty(0, CVCAM_RNDWIDTH, &width);
  348. cvcamSetProperty(0, CVCAM_RNDHEIGHT, &height);
  349. cvcamSetProperty(1, CVCAM_RNDWIDTH, &width);
  350. cvcamSetProperty(1, CVCAM_RNDHEIGHT, &height);
  351. cvcamSetProperty(1, CVCAM_STEREO_CALLBACK , stereocallback);
  352. cvcamInit();
  353. cvcamStart();
  354. cvDestroyWindow ("cvcam window");
  355. }
  356. void CTestSIFTDlg::OnChkPause() 
  357. {
  358. // TODO: Add your control notification handler code here
  359. UpdateData(true);
  360. isPause = m_pause; 
  361. }