StereoPlusDlg.cpp
上传用户:fengshi120
上传日期:2014-07-17
资源大小:6155k
文件大小:30k
源码类别:

3D图形编程

开发平台:

C/C++

  1. // StereoPlusDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include <gdiplus.h>
  5. #include "StereoPlus.h"
  6. #include "GeneralPurpose.h"
  7. #include "StereoPlusDlg.h"
  8. #include ".stereoplusdlg.h"
  9. #include "stereomatching.h"
  10. #include "DirectXDialog.h"
  11. #include "ThumbnailFileDialog.h"
  12. #ifdef _DEBUG
  13. #define new DEBUG_NEW
  14. #undef THIS_FILE
  15. static char THIS_FILE[] = __FILE__;
  16. #endif
  17. // CStereoPlusDlg dialog
  18. #define MIN_HOROPTER -500
  19. #define MAX_HOROPTER 500
  20. #define MIN_DISPARITY_RANGE 8
  21. #define MAX_DISPARITY_RANGE 128
  22. #define MIN_CORRELATION_WINDOW 5
  23. #define MAX_CORRELATION_WINDOW 49
  24. #define MIN_SAD_THRESHOLD 0
  25. #define MAX_SAD_THRESHOLD 99
  26. #define MIN_DISPARITY_IMAGE_SCALE 0
  27. #define MAX_DISPARITY_IMAGE_SCALE 4
  28. #define DELETENULL(object) if (object) {delete object;object = NULL;}
  29. CStereoPlusDlg* pMainDialog = NULL;
  30. CStereoPlusDlg::CStereoPlusDlg(CWnd* pParent /*=NULL*/)
  31. : CDialog(CStereoPlusDlg::IDD, pParent)
  32. , m_iDisparityRange(0)
  33. , m_iHoropter(0)
  34. , m_iCorrelationWindow(0)
  35. , m_iSADThreshold(0)
  36. , m_iDisparityImageScale(0)
  37. , m_bPropagateStereo(FALSE)
  38.   , m_SADControls(this,IDC_STATIC_CONTROLS)
  39. , m_fBaseLine(0)
  40. , m_fFocalLength(0)
  41. , m_bSwapLeftRight(FALSE)
  42. , m_iImageResampleWidth(0)
  43. {
  44. m_bClosing = false;
  45. m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
  46. m_pLeftImageBitmap = NULL;
  47. m_pRightImageBitmap = NULL;
  48. m_pDisparityBitmap = NULL;
  49. m_bSizeChanged = true;
  50. m_bNewFilesLoaded = false;
  51. m_pLeftBitmapData = NULL;
  52. m_pRightBitmapData = NULL;
  53. m_bImagesAreSwapped = FALSE;
  54. m_iImageXTranslation = 0;
  55. m_iImageYTranslation = 0;
  56. m_fFocalLength = 260.0f / 0.01;
  57. m_fBaseLine = 100.0f;
  58. m_pStereoContext = NULL;
  59. m_pPts3d = NULL;
  60. m_bPropagateStereo  = false;
  61. m_bGreyScaleDataLoaded = false;
  62. m_fExtentX = 1.0f;
  63. m_fExtentZ = 1.0f;
  64. m_iHoropter = theApp.GetProfileInt("SAD Params","Horopter",0);
  65. m_iDisparityRange = theApp.GetProfileInt("SAD Params","Disparity Range",32);
  66. m_iCorrelationWindow = theApp.GetProfileInt("SAD Params","Correlation Window Size",7);
  67. m_iSADThreshold = theApp.GetProfileInt("SAD Params","SAD Threshold",2);
  68. m_iDisparityImageScale = theApp.GetProfileInt("SAD Params","Disparity Image Scale",1);
  69. m_bPropagateStereo = theApp.GetProfileInt("SAD Params","Propagate Stereo",0);
  70. m_fFocalLength = (float)theApp.GetProfileDouble("Recon Params","Focal Length",150.0);
  71. m_fBaseLine = (float)theApp.GetProfileDouble("Recon Params","Base Line",0.05);
  72. m_iImageResampleWidth = theApp.GetProfileInt("Image Options","Resample Size",320);
  73. m_bResample = theApp.GetProfileInt("Image Options","Resample ON",1);
  74. m_iImageXTranslation = theApp.GetProfileInt("Image Options","xAxis Translate",0);
  75. m_iImageYTranslation = theApp.GetProfileInt("Image Options","yAxis Translate",0);
  76. InitStereoContext();
  77. pMainDialog = this;
  78. }
  79. CStereoPlusDlg::~CStereoPlusDlg()
  80. {
  81. theApp.WriteProfileInt("SAD Params","Disparity Range",m_iDisparityRange);
  82. theApp.WriteProfileInt("SAD Params","Horopter",m_iHoropter);
  83. theApp.WriteProfileInt("SAD Params","Correlation Window Size",m_iCorrelationWindow);
  84. theApp.WriteProfileInt("SAD Params","SAD Threshold",m_iSADThreshold);
  85. theApp.WriteProfileInt("SAD Params","Disparity Image Scale",m_iDisparityImageScale);
  86. theApp.WriteProfileInt("SAD Params","Propagate Stereo",m_bPropagateStereo);
  87. theApp.WriteProfileDouble("Recon Params","Focal Length",(double)m_fFocalLength);
  88. theApp.WriteProfileDouble("Recon Params","Base Line",(double)m_fBaseLine);
  89. theApp.WriteProfileInt("Image Options","Resample Size",m_iImageResampleWidth);
  90. theApp.WriteProfileInt("Image Options","Resample ON",m_bResample);
  91. theApp.WriteProfileInt("Image Options","xAxis Translate",m_iImageXTranslation);
  92. theApp.WriteProfileInt("Image Options","yAxis Translate",m_iImageYTranslation);
  93. if(m_pLeftImageBitmap)
  94. {
  95. delete m_pLeftImageBitmap;
  96. m_pLeftImageBitmap = NULL;
  97. }
  98. if(m_pRightImageBitmap)
  99. {
  100. delete m_pRightImageBitmap;
  101. m_pRightImageBitmap = NULL;
  102. }
  103. if(m_pDisparityBitmap)
  104. {
  105. delete m_pDisparityBitmap;
  106. m_pDisparityBitmap = NULL;
  107. }
  108. if(m_pLeftBitmapData) 
  109. delete [] m_pLeftBitmapData;
  110. if(m_pRightBitmapData) 
  111. delete [] m_pRightBitmapData;
  112. if(m_pStereoContext)
  113. delete m_pStereoContext;
  114. if(m_pPts3d)
  115. delete m_pPts3d;
  116. }
  117. void CStereoPlusDlg::DoDataExchange(CDataExchange* pDX)
  118. {
  119. CDialog::DoDataExchange(pDX);
  120. DDX_Text(pDX, IDC_EDIT_DISPARITYRANGE, m_iDisparityRange);
  121. DDV_MinMaxInt(pDX, m_iDisparityRange, MIN_DISPARITY_RANGE, MAX_DISPARITY_RANGE);
  122. DDX_Text(pDX, IDC_EDIT_HOROPTER, m_iHoropter);
  123. DDV_MinMaxInt(pDX, m_iHoropter, MIN_HOROPTER, MAX_HOROPTER);
  124. DDX_Text(pDX, IDC_EDIT_CORRWINSIZE, m_iCorrelationWindow);
  125. DDV_MinMaxInt(pDX, m_iCorrelationWindow, MIN_CORRELATION_WINDOW, MAX_CORRELATION_WINDOW);
  126. DDX_Text(pDX, IDC_EDIT_SADTHRESH, m_iSADThreshold);
  127. DDV_MinMaxInt(pDX, m_iSADThreshold, MIN_SAD_THRESHOLD, MAX_SAD_THRESHOLD);
  128. DDX_Text(pDX, IDC_EDIT_DISPARITYSCALE, m_iDisparityImageScale);
  129. DDV_MinMaxInt(pDX, m_iDisparityImageScale, MIN_DISPARITY_IMAGE_SCALE, MAX_DISPARITY_IMAGE_SCALE);
  130. DDX_Check(pDX, IDC_CHECK_STEREOPROPAG, m_bPropagateStereo);
  131. DDX_Text(pDX, IDC_EDIT_BASE_LINE, m_fBaseLine);
  132. DDV_MinMaxFloat(pDX, m_fBaseLine, 0.00001f, 1000.0f);
  133. DDX_Text(pDX, IDC_EDIT_FOCAL_LENGTH, m_fFocalLength);
  134. DDV_MinMaxFloat(pDX, m_fFocalLength, 1.0f, 100000.0f);
  135. DDX_Check(pDX, IDC_CHECK_SWAP, m_bSwapLeftRight);
  136. DDX_Control(pDX, IDC_CHECK_SWAP, m_ctrlCheckSwapLeftRight);
  137. DDX_Control(pDX, IDC_CHECK_RESAMPLE, m_ctrlResampleImages);
  138. DDX_Text(pDX, IDC_EDIT_RESAMPLE_WIDTH, m_iImageResampleWidth);
  139. DDV_MinMaxInt(pDX, m_iImageResampleWidth, 64, 1280);
  140. DDX_Control(pDX, IDC_EDIT_RESAMPLE_WIDTH, m_ctrlEditResampleWidth);
  141. DDX_Text(pDX, IDC_EDIT_XTRANSLATE, m_iImageXTranslation);
  142. DDX_Text(pDX, IDC_EDIT_YTRANSLATE, m_iImageYTranslation);
  143. }
  144. BEGIN_MESSAGE_MAP(CStereoPlusDlg, CDialog)
  145. ON_WM_PAINT()
  146. ON_WM_QUERYDRAGICON()
  147. //}}AFX_MSG_MAP
  148. ON_BN_CLICKED(IDC_BUTTON_LOAD_LEFT, OnBnClickedButtonLoadLeft)
  149. ON_WM_DESTROY()
  150. ON_WM_SIZE()
  151. ON_BN_CLICKED(IDC_BUTTON_LOAD_RIGHT, OnBnClickedButtonLoadRight)
  152. ON_BN_CLICKED(IDC_BUTTON_LOAD_PAIR, OnBnClickedButtonLoadPair)
  153. ON_BN_CLICKED(IDC_BUTTON_DO_STEREO, OnBnClickedButtonDoStereo)
  154. ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DISPARITYRANGE, OnDeltaposSpinDisparityrange)
  155. ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_HOROPTER, OnDeltaposSpinHoropter)
  156. ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_CORRWINSIZE, OnDeltaposSpinCorrwinsize)
  157. ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_SADTHRESH, OnDeltaposSpinSadthresh)
  158. ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_DISPARITYSCALE, OnDeltaposSpinDisparityscale)
  159. ON_BN_CLICKED(IDC_CHECK_STEREOPROPAG, OnBnClickedCheckStereoPropagation)
  160. ON_WM_CLOSE()
  161. ON_BN_CLICKED(IDC_BUTTON_DO_RECONSTRUCTION_DIRECTX, OnBnClickedButtonDoReconstructionDirectx)
  162. ON_BN_CLICKED(IDC_CHECK_SWAP, OnBnClickedCheckSwap)
  163. ON_BN_CLICKED(IDC_CHECK_RESAMPLE, OnBnClickedCheckResample)
  164. ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_XTRANSLATE, OnDeltaposSpinXtranslate)
  165. ON_NOTIFY(UDN_DELTAPOS, IDC_SPIN_YTRANSLATE, OnDeltaposSpinYtranslate)
  166. ON_BN_CLICKED(IDC_BUTTON_SAVEDISPARITY, OnBnClickedButtonSavedisparity)
  167. END_MESSAGE_MAP()
  168. // CStereoPlusDlg message handlers
  169. BOOL CStereoPlusDlg::OnInitDialog()
  170. {
  171. CDialog::OnInitDialog();
  172. m_strLeftImagePath = theApp.GetProfileString("Images","Left Image","C:\");
  173. m_strRightImagePath = theApp.GetProfileString("Images","Right Image","C:\");
  174. m_strImagePairPath = theApp.GetProfileString("Images","Image Pair","C:\");
  175. // Set the icon for this dialog.  The framework does this automatically
  176. //  when the application's main window is not a dialog
  177. SetIcon(m_hIcon, TRUE); // Set big icon
  178. SetIcon(m_hIcon, FALSE); // Set small icon
  179. m_ctrlEditResampleWidth.EnableWindow(m_bResample);
  180. if(m_bResample)
  181. m_ctrlResampleImages.SetCheck(BST_CHECKED);
  182. //this is so the controls maintain there position relative to IDC_STATIC_CONTROLS
  183. //when that window is moved by the user resizing the app window
  184. m_SADControls.AddControl(IDC_STATIC_SAD_FRAME);
  185. m_SADControls.AddControl(IDC_BUTTON_DO_STEREO);
  186. m_SADControls.AddControl(IDC_BUTTON_SAVEDISPARITY);
  187. m_SADControls.AddControl(IDC_STATIC_TEXT1);
  188. m_SADControls.AddControl(IDC_STATIC_TEXT2);
  189. m_SADControls.AddControl(IDC_STATIC_TEXT3);
  190. m_SADControls.AddControl(IDC_STATIC_TEXT4);
  191. m_SADControls.AddControl(IDC_SPIN_DISPARITYRANGE);
  192. m_SADControls.AddControl(IDC_SPIN_HOROPTER);
  193. m_SADControls.AddControl(IDC_SPIN_CORRWINSIZE);
  194. m_SADControls.AddControl(IDC_SPIN_SADTHRESH);
  195. m_SADControls.AddControl(IDC_SPIN_DISPARITYSCALE);
  196. m_SADControls.AddControl(IDC_CHECK_STEREOPROPAG);
  197. m_SADControls.AddControl(IDC_EDIT_DISPARITYRANGE);
  198. m_SADControls.AddControl(IDC_EDIT_HOROPTER);
  199. m_SADControls.AddControl(IDC_EDIT_CORRWINSIZE);
  200. m_SADControls.AddControl(IDC_EDIT_SADTHRESH);
  201. m_SADControls.AddControl(IDC_EDIT_DISPARITYSCALE);
  202. m_SADControls.AddControl(IDC_STATIC_PROPAGATION_FRAME);
  203. m_SADControls.AddControl(IDC_BUTTON_DO_RECONSTRUCTION_DIRECTX);
  204. m_SADControls.AddControl(IDC_STATIC_SCALE_FRAME);
  205. m_SADControls.AddControl(IDC_EDIT_BASE_LINE);
  206. m_SADControls.AddControl(IDC_EDIT_FOCAL_LENGTH);
  207. m_SADControls.AddControl(IDC_STATIC_FOCAL_LENGTH);
  208. m_SADControls.AddControl(IDC_STATIC_BASE_LINE);
  209. m_SADControls.AddControl(IDC_STATIC_RECON_FRAME);
  210. m_SADControls.AddControl(IDC_CHECK_SWAP);
  211. m_SADControls.AddControl(IDC_STATIC_IMAGE_FRAME);
  212. m_SADControls.AddControl(IDC_EDIT_RESAMPLE_WIDTH);
  213. m_SADControls.AddControl(IDC_STATIC_WIDTH);
  214. m_SADControls.AddControl(IDC_CHECK_RESAMPLE);
  215. m_SADControls.AddControl(IDC_STATIC_XTRANSLATE);
  216. m_SADControls.AddControl(IDC_EDIT_XTRANSLATE);
  217. m_SADControls.AddControl(IDC_SPIN_XTRANSLATE);
  218. m_SADControls.AddControl(IDC_STATIC_YTRANSLATE);
  219. m_SADControls.AddControl(IDC_EDIT_YTRANSLATE);
  220. m_SADControls.AddControl(IDC_SPIN_YTRANSLATE);
  221. return TRUE;  // return TRUE  unless you set the focus to a control
  222. }
  223. // If you add a minimize button to your dialog, you will need the code below
  224. //  to draw the icon.  For MFC applications using the document/view model,
  225. //  this is automatically done for you by the framework.
  226. void CStereoPlusDlg::OnPaint() 
  227. {
  228. if (IsIconic())
  229. {
  230. CPaintDC dc(this); // device context for painting
  231. SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
  232. // Center icon in client rectangle
  233. int cxIcon = GetSystemMetrics(SM_CXICON);
  234. int cyIcon = GetSystemMetrics(SM_CYICON);
  235. CRect rect;
  236. GetClientRect(&rect);
  237. int x = (rect.Width() - cxIcon + 1) / 2;
  238. int y = (rect.Height() - cyIcon + 1) / 2;
  239. // Draw the icon
  240. dc.DrawIcon(x, y, m_hIcon);
  241. }
  242. else
  243. {
  244. CDialog::OnPaint();
  245. if(m_bSizeChanged)
  246. ArrangeControls();
  247. DrawBitmap(IDC_STATIC_LEFT,m_pLeftImageBitmap);
  248. DrawBitmap(IDC_STATIC_RIGHT,m_pRightImageBitmap);
  249. DrawBitmap(IDC_STATIC_DISPARITY,m_pDisparityBitmap);
  250. }
  251. }
  252. // The system calls this function to obtain the cursor to display while the user drags
  253. //  the minimized window.
  254. HCURSOR CStereoPlusDlg::OnQueryDragIcon()
  255. {
  256. return static_cast<HCURSOR>(m_hIcon);
  257. }
  258. void CStereoPlusDlg::OnBnClickedButtonLoadLeft()
  259. {
  260. if(SelectImageFile(m_strLeftImagePath))
  261. {
  262. m_bGreyScaleDataLoaded = false;
  263. if(m_pLeftImageBitmap)
  264. {
  265. delete m_pLeftImageBitmap;
  266. m_pLeftImageBitmap = NULL;
  267. }
  268. WCHAR wString[MAX_PATH];
  269. MultiByteToWideChar (CP_ACP, 0,m_strLeftImagePath,-1,wString,MAX_PATH);
  270. // load bitmap
  271. m_pLeftImageBitmap = new Bitmap(wString);
  272. if(m_bResample)
  273. ResampleBitmap(m_pLeftImageBitmap,m_iImageResampleWidth);
  274. DrawBitmap(IDC_STATIC_LEFT,m_pLeftImageBitmap);
  275. m_bNewFilesLoaded = true;
  276. }
  277. }
  278. void CStereoPlusDlg::OnBnClickedButtonLoadRight()
  279. {
  280. if(SelectImageFile(m_strRightImagePath))
  281. {
  282. m_bGreyScaleDataLoaded = false;
  283. if(m_pRightImageBitmap)
  284. {
  285. delete m_pRightImageBitmap;
  286. m_pRightImageBitmap = NULL;
  287. }
  288. WCHAR wString[MAX_PATH];
  289. MultiByteToWideChar (CP_ACP, 0,m_strRightImagePath,-1,wString,MAX_PATH);
  290. m_pRightImageBitmap = new Bitmap(wString);
  291. if(m_bResample)
  292. ResampleBitmap(m_pRightImageBitmap,m_iImageResampleWidth);
  293. DrawBitmap(IDC_STATIC_RIGHT,m_pRightImageBitmap);
  294. m_bNewFilesLoaded = true;
  295. }
  296. }
  297. void CStereoPlusDlg::ResampleBitmap(Bitmap *&pBitmap,UINT iNewWidth)
  298. {
  299. UINT w = pBitmap->GetWidth();
  300. UINT h = pBitmap->GetHeight();
  301. float fAspect = (float)h/(float)w;
  302. UINT wSmall = iNewWidth;
  303. UINT hSmall = (int)(iNewWidth*fAspect);
  304. Bitmap *pNewBitmap = new Bitmap(wSmall,hSmall);
  305. Graphics* pGraphics = new Graphics(pNewBitmap);
  306. Rect rcDst(0,0,wSmall,hSmall);
  307. pGraphics->DrawImage(pBitmap,rcDst,0,0,w,h, UnitPixel,NULL,NULL,NULL);
  308. delete pGraphics;
  309. delete pBitmap;
  310. pBitmap = pNewBitmap;
  311. }
  312. void CStereoPlusDlg::OnBnClickedButtonLoadPair()
  313. {
  314. if(SelectImageFile(m_strImagePairPath))
  315. {
  316. m_bGreyScaleDataLoaded = false;
  317. if(m_pRightImageBitmap)
  318. {
  319. delete m_pRightImageBitmap;
  320. m_pRightImageBitmap = NULL;
  321. }
  322. if(m_pLeftImageBitmap)
  323. {
  324. delete m_pLeftImageBitmap;
  325. m_pLeftImageBitmap = NULL;
  326. }
  327. WCHAR wString[MAX_PATH];
  328. MultiByteToWideChar (CP_ACP, 0,m_strImagePairPath,-1,wString,MAX_PATH);
  329. Bitmap* pPairBitmap = new Bitmap(wString);
  330. if(pPairBitmap->GetLastStatus() == Ok)
  331. {
  332. int w = pPairBitmap->GetWidth();
  333. int h = pPairBitmap->GetHeight();
  334. m_pLeftImageBitmap = pPairBitmap->Clone(0,0,w/2,h,PixelFormat24bppRGB);
  335. if(m_bResample)
  336. ResampleBitmap(m_pLeftImageBitmap,m_iImageResampleWidth);
  337. m_pRightImageBitmap = pPairBitmap->Clone(w/2,0,w/2,h,PixelFormat24bppRGB);
  338. if(m_bResample)
  339. ResampleBitmap(m_pRightImageBitmap,m_iImageResampleWidth);
  340. m_bNewFilesLoaded = true;
  341. }
  342. delete pPairBitmap;
  343. }
  344. }
  345. BYTE* CStereoPlusDlg::GetGrayScaleData(Bitmap* pBitmap)
  346. {
  347. //Gdiplus sucks at manipulating greyscale images so it's simpler to just extract the luminance directly
  348. UINT uWidth = pBitmap->GetWidth();
  349. UINT uHeight = pBitmap->GetHeight();
  350. BitmapData *pBitmapData = new BitmapData;
  351. UINT nPixels = pBitmap->GetWidth()*pBitmap->GetHeight();
  352. BYTE* pGrayScaleData = new BYTE[nPixels];
  353. UINT i=0;
  354. Rect rect(0,0,uWidth,uHeight);
  355. if(pBitmap->LockBits(&rect,ImageLockModeRead,PixelFormat32bppARGB,pBitmapData) == Ok)
  356. {
  357. Color* pLine = (Color*)pBitmapData->Scan0;
  358. Color c;
  359. UINT uPixelsPerLine = pBitmapData->Stride / 4;
  360. for(UINT row=0;row<uHeight;row++)
  361. {
  362. for(UINT col=0;col<uWidth;col++)
  363. {
  364. c = pLine[col];
  365. pGrayScaleData[i++] =(BYTE) ((double)c.GetR()*0.3 + (double)c.GetG()*0.59 + (double)c.GetB()*0.11);
  366. }
  367. pLine += uPixelsPerLine;
  368. }
  369. pBitmap->UnlockBits(pBitmapData);
  370. }
  371. delete pBitmapData;
  372. return pGrayScaleData;
  373. }
  374. void CStereoPlusDlg::OnDestroy()
  375. {
  376. CDialog::OnDestroy();
  377. theApp.WriteProfileString("Images","Left Image",m_strLeftImagePath);
  378. theApp.WriteProfileString("Images","Right Image",m_strRightImagePath);
  379. theApp.WriteProfileString("Images","Image Pair",m_strImagePairPath);
  380. }
  381. void CStereoPlusDlg::DrawBitmap(UINT idWindow,Bitmap *pBitmap)
  382. {
  383. CWnd* pWnd = GetDlgItem(idWindow);
  384. if(pWnd)
  385. {
  386. CRect rcWindow;
  387. pWnd->GetClientRect(&rcWindow);
  388. int wWindow = rcWindow.Width()-10;
  389. int hWindow = rcWindow.Height()-20;
  390. Rect rcDest(5,15,wWindow,hWindow);
  391. CDC* pDC = pWnd->GetDC();
  392. if(pBitmap)
  393. {
  394. Graphics* pGraphics = new Graphics(pDC->m_hDC);
  395.   pGraphics->ResetTransform();
  396.   pGraphics->SetInterpolationMode(InterpolationModeHighQualityBicubic);
  397. pGraphics->DrawImage(pBitmap,rcDest,0,0,pBitmap->GetWidth(),pBitmap->GetHeight(),UnitPixel);
  398. pGraphics->ReleaseHDC(pDC->m_hDC);
  399. delete pGraphics;
  400. }
  401. else
  402. {
  403. CRect rcFill(CPoint(5,15),CSize(wWindow,hWindow));
  404. pDC->FillSolidRect(rcFill,RGB(0,0,0));
  405. }
  406. ReleaseDC(pDC);
  407. }
  408. }
  409. void CStereoPlusDlg::OnSize(UINT nType, int cx, int cy)
  410. {
  411. CDialog::OnSize(nType, cx, cy);
  412. m_bSizeChanged = true;
  413. Invalidate();
  414. }
  415. void CStereoPlusDlg::ArrangeControls(void)
  416. {//Set conrol positions optimally if window is resized
  417. CRect rcHost;
  418. GetClientRect(&rcHost);
  419. int wHost = rcHost.Width();
  420. int hHost = rcHost.Height();
  421. int hImageMax = (int)(0.5 +  (double)(hHost-50)/2.0);
  422. int iSpacing = 10; 
  423. int wImage = (wHost - 3*iSpacing)/2;
  424. double dAspectRatio = 1.0/1.33;
  425. int hImage = (int)(0.5 + dAspectRatio * (double)wImage );
  426. if(hImage > hImageMax)
  427. {
  428. wImage = (int)((double)hImageMax/dAspectRatio);
  429. iSpacing = (wHost - 2*wImage)/3;
  430. hImage = hImageMax;
  431. }
  432. int iYPos = 5;
  433. int xPos = iSpacing;
  434. CRect rcControl1(CPoint(xPos,iYPos),CSize(wImage,hImage));
  435. GetDlgItem(IDC_STATIC_LEFT)->MoveWindow(&rcControl1);
  436. int iButtonWidth = rcControl1.Width()/2-20;
  437. xPos += (wImage + iSpacing);
  438. CRect rcControl2(CPoint(xPos,iYPos),CSize(wImage,hImage));
  439. GetDlgItem(IDC_STATIC_RIGHT)->MoveWindow(&rcControl2);
  440. xPos = iSpacing;
  441. iYPos = rcControl1.bottom + 10;
  442. CRect rcControl3( CPoint(xPos,iYPos),CSize(iButtonWidth,20));
  443. GetDlgItem(IDC_BUTTON_LOAD_LEFT)->MoveWindow(&rcControl3);
  444. xPos += (wImage + iSpacing);
  445. CRect rcControl4(CPoint(rcControl2.right - rcControl1.Width()/2,iYPos),CSize(iButtonWidth,20));
  446. GetDlgItem(IDC_BUTTON_LOAD_RIGHT)->MoveWindow(&rcControl4);
  447. CRect rcControl6(CPoint(wHost/2-iButtonWidth/2,iYPos),CSize(iButtonWidth,20));
  448. GetDlgItem(IDC_BUTTON_LOAD_PAIR)->MoveWindow(&rcControl6);
  449. iYPos = rcControl4.bottom + 10;
  450. CRect rcControl5(CPoint(xPos,iYPos),CSize(wImage,hImage));
  451. GetDlgItem(IDC_STATIC_DISPARITY)->MoveWindow(&rcControl5);
  452. CRect rcControlHost;
  453. GetDlgItem(IDC_STATIC_CONTROLS)->GetWindowRect(&rcControlHost);
  454. ScreenToClient(&rcControlHost);
  455. xPos = iSpacing;
  456. iYPos = rcControl4.bottom + 10;
  457. CRect rcControl7(CPoint(xPos,iYPos),CSize(wImage,hImage));
  458. GetDlgItem(IDC_STATIC_CONTROLS)->MoveWindow(&rcControl7);
  459. //this moves all the controls grouped by IDC_STATIC_CONTROLS
  460. m_SADControls.PositionControls();
  461. }
  462. //The good stuff
  463. void CStereoPlusDlg::OnBnClickedButtonDoStereo()
  464. {
  465. if(m_bNewFilesLoaded)
  466. {
  467. if(m_pLeftBitmapData) 
  468. delete [] m_pLeftBitmapData;
  469. if(m_pRightBitmapData) 
  470. delete [] m_pRightBitmapData;
  471. m_pLeftBitmapData = GetGrayScaleData(m_pLeftImageBitmap);
  472. m_pRightBitmapData = GetGrayScaleData(m_pRightImageBitmap);
  473. m_bGreyScaleDataLoaded = true;
  474. m_bNewFilesLoaded = false;
  475. }
  476. if(m_bGreyScaleDataLoaded)
  477. {
  478. UINT wL = m_pLeftImageBitmap->GetWidth();
  479. UINT hL = m_pLeftImageBitmap->GetHeight();
  480. UINT wR = m_pRightImageBitmap->GetWidth();
  481. UINT hR = m_pRightImageBitmap->GetHeight();
  482. if(wL != wR || hL != hR)
  483. {
  484. AfxMessageBox("Images need to be of similar dimension",MB_ICONSTOP | MB_OK);
  485. return;
  486. }
  487. ComputeStereo();
  488. }
  489. }
  490. // save the 3D reconstruction in 'filename'
  491. bool CStereoPlusDlg::Save3DReconst(CString filename)
  492. {
  493. return true;
  494. }
  495.  void CStereoPlusDlg::ComputeStereo(void)
  496.  {
  497. UINT w = m_pLeftImageBitmap->GetWidth();
  498. UINT h = m_pLeftImageBitmap->GetHeight();
  499. // do (SAD-based) stereo processing
  500. estereo_process(m_pStereoContext,(m_bPropagateStereo==TRUE),&m_StereoData,
  501. //((char*)m_pLeftBitmapData)-m_iImageXTranslation,
  502. ((char*)m_pLeftBitmapData),
  503. (char*)m_pRightBitmapData, w,h, -m_iImageXTranslation, m_iImageYTranslation);
  504. int disp_h, disp_w; // size of disparity image (could be different from input images)
  505. disp_w = m_StereoData.width;
  506. disp_h = m_StereoData.height;
  507. if(!m_pDisparityBitmap)
  508. {
  509. m_pDisparityBitmap = new Bitmap(disp_w,disp_h,PixelFormat32bppARGB );//don't mess with palettes Gdi+ doesn't like them
  510. }
  511. else if(m_pDisparityBitmap->GetWidth() != disp_w || m_pDisparityBitmap->GetHeight() != disp_h)
  512. {
  513. delete m_pDisparityBitmap;
  514. m_pDisparityBitmap = new Bitmap(disp_w,disp_h,PixelFormat32bppARGB );
  515. }
  516. Rect rect(0,0,disp_w,disp_h);
  517. BitmapData *pBitmapData = new BitmapData;
  518. if(m_pDisparityBitmap->LockBits(&rect,ImageLockModeWrite,PixelFormat32bppARGB,pBitmapData) == Ok)
  519. {
  520. BYTE* ptd_src = (BYTE*)m_StereoData.imDepth8u;
  521. Color* pLine = (Color*)pBitmapData->Scan0;
  522. UINT uPixelsPerLine = pBitmapData->Stride / 4;
  523. for(int row=0;row<disp_h;row++)
  524. {
  525. for(int col=0;col<disp_w;col++)
  526. {
  527. if (*ptd_src>0)
  528. {
  529. BYTE lum = 50 + *ptd_src*4; 
  530. pLine[col] = Color::MakeARGB(255,lum,lum,lum);
  531. }
  532. else
  533. {
  534. pLine[col] = Color::MakeARGB(255,0,0,0);
  535. }
  536. ptd_src++;
  537. }
  538. pLine += uPixelsPerLine;
  539. }
  540. m_pDisparityBitmap->UnlockBits(pBitmapData);
  541. }
  542. delete pBitmapData;
  543. DrawBitmap(IDC_STATIC_DISPARITY,m_pDisparityBitmap);
  544.  }
  545. void CStereoPlusDlg::estereo_process(StereoMatching* stereo, bool propag_stereo,
  546.   StereoImage* simage,
  547.   const char* imLeft, const char* imRight, 
  548.   int width, int height, int xOffset, int yOffset)
  549. {
  550. // set the 'undefined depth' value to 0
  551. simage->setUndefinedDepthValue(0);
  552. // do the disparity calculation - SAD
  553. stereo->setInputImageSize(width, height);
  554. stereo->setLeftImageXOffset(xOffset);
  555. stereo->setLeftImageYOffset(yOffset);
  556. // set monoscale/multiscale processing
  557. stereo->setScaleProcessing(propag_stereo?StereoMatching::MULTISCALE 
  558. : StereoMatching::MONOSCALE);
  559. stereo->doStereo(simage, (const unsigned char*)imLeft, (const unsigned char*)imRight);
  560. }
  561. void CStereoPlusDlg::InitStereoContext()
  562. {
  563. // *********************************************
  564. // ******** initialize disparity estimation context
  565. m_pStereoContext = new StereoMatching();
  566. // initialize SAD parameters
  567. m_pStereoContext->setHoropter(m_iHoropter);
  568. m_pStereoContext->setNumDepth(m_iDisparityRange);
  569. m_pStereoContext->setCorrelationWindowSize(m_iCorrelationWindow,m_iCorrelationWindow);
  570. m_pStereoContext->setInputImageSize(320,240);
  571. m_pStereoContext->setScale(m_iDisparityImageScale);
  572. m_pStereoContext->setAcceptDisparityThreshold((float)m_iSADThreshold);
  573. // allocate buffers for SAD computation
  574. m_pStereoContext->initializeContext();
  575. }
  576. void CStereoPlusDlg::OnDeltaposSpinDisparityrange(NMHDR *pNMHDR, LRESULT *pResult)
  577. {
  578. LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
  579. if(UpdateData())
  580. {
  581. m_iDisparityRange -= 8*pNMUpDown->iDelta;
  582. m_iDisparityRange = max(MIN_DISPARITY_RANGE,min(MAX_DISPARITY_RANGE,m_iDisparityRange));
  583. UpdateData(FALSE);
  584. if(m_pStereoContext)
  585. m_pStereoContext->setNumDepth(m_iDisparityRange);
  586. if (m_bGreyScaleDataLoaded) 
  587. {
  588. ComputeStereo();
  589. }
  590. }
  591. *pResult = 0;
  592. }
  593. void CStereoPlusDlg::OnDeltaposSpinHoropter(NMHDR *pNMHDR, LRESULT *pResult)
  594. {
  595. LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
  596. if(UpdateData())
  597. {
  598. m_iHoropter -= pNMUpDown->iDelta;
  599. m_iHoropter = max(MIN_HOROPTER,min(MAX_HOROPTER,m_iHoropter));
  600. UpdateData(FALSE);
  601. if(m_pStereoContext)
  602. m_pStereoContext->setHoropter(m_iHoropter);
  603. if (m_bGreyScaleDataLoaded) 
  604. {
  605. ComputeStereo();
  606. }
  607. }
  608. *pResult = 0;
  609. }
  610. void CStereoPlusDlg::OnDeltaposSpinCorrwinsize(NMHDR *pNMHDR, LRESULT *pResult)
  611. {
  612. LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
  613. if(UpdateData())
  614. {
  615. m_iCorrelationWindow -= 2*pNMUpDown->iDelta;
  616. m_iCorrelationWindow = max(MIN_CORRELATION_WINDOW,min(MAX_CORRELATION_WINDOW,m_iCorrelationWindow));
  617. UpdateData(FALSE);
  618. if(m_pStereoContext)
  619. m_pStereoContext->setCorrelationWindowSize(m_iCorrelationWindow,m_iCorrelationWindow);
  620. if (m_bGreyScaleDataLoaded) 
  621. {
  622. ComputeStereo();
  623. }
  624. }
  625. // TODO: Add your control notification handler code here
  626. *pResult = 0;
  627. }
  628. void CStereoPlusDlg::OnDeltaposSpinSadthresh(NMHDR *pNMHDR, LRESULT *pResult)
  629. {
  630. LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
  631. if(UpdateData())
  632. {
  633. m_iSADThreshold -= pNMUpDown->iDelta;
  634. m_iSADThreshold = max(MIN_SAD_THRESHOLD,min(MAX_SAD_THRESHOLD,m_iSADThreshold));
  635. UpdateData(FALSE);
  636. if(m_pStereoContext)
  637. m_pStereoContext->setAcceptDisparityThreshold((float)m_iSADThreshold);
  638. if (m_bGreyScaleDataLoaded) 
  639. {
  640. ComputeStereo();
  641. }
  642. }
  643. *pResult = 0;
  644. }
  645. void CStereoPlusDlg::OnDeltaposSpinDisparityscale(NMHDR *pNMHDR, LRESULT *pResult)
  646. {
  647. LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
  648. if(UpdateData())
  649. {
  650. m_iDisparityImageScale -= pNMUpDown->iDelta;
  651. m_iDisparityImageScale = max(MIN_DISPARITY_IMAGE_SCALE,min(MAX_DISPARITY_IMAGE_SCALE,m_iDisparityImageScale));
  652. UpdateData(FALSE);
  653. if(m_pStereoContext)
  654. m_pStereoContext->setScale(m_iDisparityImageScale);
  655. if (m_bGreyScaleDataLoaded) 
  656. {
  657. ComputeStereo();
  658. }
  659. }
  660. *pResult = 0;
  661. }
  662. void CStereoPlusDlg::OnBnClickedCheckStereoPropagation()
  663. {
  664. if(UpdateData())
  665. {
  666. if(m_bPropagateStereo)
  667. OutputDebugString("Stereo Propagation is ONn");
  668. else
  669. OutputDebugString("Stereo Propagation is OFFn");
  670. if (m_bGreyScaleDataLoaded) 
  671. {
  672. ComputeStereo();
  673. }
  674. }
  675. }
  676. void CStereoPlusDlg::OnClose()
  677. {
  678. m_bClosing = true;
  679. CDialog::OnClose();
  680. }
  681. // build the 3D reconstruction and display it using directX
  682. void CStereoPlusDlg::OnBnClickedButtonDoReconstructionDirectx()
  683. {
  684. if(!UpdateData())
  685. return;
  686. // create a '3D reconstruction' structure
  687. if(m_pPts3d)
  688. delete m_pPts3d;
  689. m_pPts3d = new ReconstPoints3D();
  690. // set virtual camera parameters
  691. m_Reconst3d.setCameraParameters(m_fFocalLength,m_fBaseLine,
  692. (float)(m_StereoData.width/2),
  693. (float)(m_StereoData.height/2));
  694. // perform the 3D reconstruction
  695. switch(m_Reconst3d.doReconstruction(m_pPts3d,&m_StereoData,m_pRightImageBitmap))
  696. {
  697. case Reconst3D::RECONST_OK: {
  698. CDirectXDialog DirectXDlg(this);
  699. DirectXDlg.SetData( m_pPts3d->getNumPoints(),
  700. m_pPts3d->getXlist(),
  701. m_pPts3d->getYlist(),
  702. m_pPts3d->getZlist(),
  703. m_pPts3d->getARGBlist(),
  704. m_pPts3d->getPointSizelist());
  705. DirectXDlg.DoModal();
  706. }
  707. break;
  708.   
  709. //
  710. case Reconst3D::CAMERA_PARAM_NOT_SET:
  711. AfxMessageBox("Set cam parameters before attempting reconstruction",MB_ICONEXCLAMATION);
  712. break;
  713. case Reconst3D::IMAGE_BUFFER_NULL:
  714. AfxMessageBox("Set the image buffer before attempting reconstruction",MB_ICONEXCLAMATION);
  715. break;
  716. case Reconst3D::WRONG_IMAGE_SIZE:
  717. AfxMessageBox("Image size doesn't match the SAD data",MB_ICONEXCLAMATION);
  718. break;
  719. }
  720. }
  721. void CStereoPlusDlg::OnBnClickedCheckSwap()
  722. {
  723. if(UpdateData())
  724. {
  725. if(m_bImagesAreSwapped != m_bSwapLeftRight)
  726. SwapImages();
  727. m_bImagesAreSwapped = m_bSwapLeftRight;
  728. }
  729. }
  730. void CStereoPlusDlg::SwapImages(void)
  731. {
  732. if(m_pLeftImageBitmap && m_pRightImageBitmap)
  733. {
  734. Bitmap* pLeft = m_pLeftImageBitmap;
  735. Bitmap* pRight = m_pRightImageBitmap;
  736. BYTE* pLeftData = m_pLeftBitmapData;
  737. BYTE* pRightData = m_pRightBitmapData;
  738. m_pLeftImageBitmap = pRight;
  739. m_pRightImageBitmap = pLeft;
  740. m_pLeftBitmapData = pRightData;
  741. m_pRightBitmapData = pLeftData;
  742. DrawBitmap(IDC_STATIC_LEFT,m_pLeftImageBitmap);
  743. DrawBitmap(IDC_STATIC_RIGHT,m_pRightImageBitmap);
  744. ComputeStereo();
  745. }
  746. }
  747. void CStereoPlusDlg::OnBnClickedCheckResample()
  748. {
  749. m_bResample = (m_ctrlResampleImages.GetCheck() == BST_CHECKED);
  750. m_ctrlEditResampleWidth.EnableWindow(m_bResample);
  751. if(m_bResample && (m_pLeftImageBitmap || m_pRightImageBitmap) )
  752. AfxMessageBox("Re-Load images to apply resampling",MB_ICONINFORMATION);
  753. }
  754. void CStereoPlusDlg::OnDeltaposSpinXtranslate(NMHDR *pNMHDR, LRESULT *pResult)
  755. {
  756. LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
  757. if(UpdateData())
  758. {
  759. m_iImageXTranslation -= pNMUpDown->iDelta;
  760. m_iImageXTranslation = max(-128,min(128,m_iImageXTranslation));
  761. UpdateData(FALSE);
  762. if (m_bGreyScaleDataLoaded) {
  763. ComputeStereo();
  764. }
  765. }
  766. // TODO: Add your control notification handler code here
  767. *pResult = 0;
  768. }
  769. void CStereoPlusDlg::OnDeltaposSpinYtranslate(NMHDR *pNMHDR, LRESULT *pResult)
  770. {
  771. LPNMUPDOWN pNMUpDown = reinterpret_cast<LPNMUPDOWN>(pNMHDR);
  772. if(UpdateData())
  773. {
  774. m_iImageYTranslation -= pNMUpDown->iDelta;
  775. m_iImageYTranslation = max(-128,min(128,m_iImageYTranslation));
  776. UpdateData(FALSE);
  777. if (m_bGreyScaleDataLoaded) {
  778. ComputeStereo();
  779. }
  780. }
  781. // TODO: Add your control notification handler code here
  782. *pResult = 0;
  783. }
  784. int GetEncoderClsid(const WCHAR* format, CLSID* pClsid)
  785. {
  786.    UINT  num = 0;          // number of image encoders
  787.    UINT  size = 0;         // size of the image encoder array in bytes
  788.    ImageCodecInfo* pImageCodecInfo = NULL;
  789.    GetImageEncodersSize(&num, &size);
  790.    if(size == 0)
  791.       return -1;  // Failure
  792.    pImageCodecInfo = (ImageCodecInfo*)(malloc(size));
  793.    if(pImageCodecInfo == NULL)
  794.       return -1;  // Failure
  795.    GetImageEncoders(num, size, pImageCodecInfo);
  796.    for(UINT j = 0; j < num; ++j)
  797.    {
  798.       if( wcscmp(pImageCodecInfo[j].MimeType, format) == 0 )
  799.       {
  800.          *pClsid = pImageCodecInfo[j].Clsid;
  801.          free(pImageCodecInfo);
  802.          return j;  // Success
  803.       }    
  804.    }
  805.    free(pImageCodecInfo);
  806.    return -1;  // Failure
  807. }
  808. void CStereoPlusDlg::OnBnClickedButtonSavedisparity()
  809. {
  810. // TODO: Add your control notification handler code here
  811. // save m_pDisparityBitmap
  812. CString FilePath = m_strLeftImagePath;
  813. CFileDialog* pFileDlg = new CThumbnailFileDialog(FALSE,"jpg",NULL,
  814. OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_FILEMUSTEXIST,
  815. "Image Files (*.jpg) |*.jpg| All Files (*.*) |*.*||", 
  816. // "Image Files (*.jpg;*.jps,*.bmp) |*.jpg;*.jps;*.bmp| All Files (*.*) |*.*||", 
  817. AfxGetMainWnd() );
  818. char drive[_MAX_DRIVE];
  819. char dir[_MAX_DIR]; 
  820. char fname[_MAX_FNAME];
  821. char ext[_MAX_EXT];
  822. CString FileDir;
  823. _splitpath( FilePath, drive, dir, fname, ext );
  824. if(strlen(drive) != 0)FileDir = drive;
  825. if(strlen(dir) != 0)FileDir += dir;
  826. pFileDlg->m_ofn.nFilterIndex = 0;
  827. pFileDlg->m_ofn.lpstrInitialDir = FileDir;
  828. pFileDlg->m_ofn.lpstrTitle = "Select Image";
  829. CString InitialFileName = fname;
  830. lstrcpy(pFileDlg->m_ofn.lpstrFile,InitialFileName);
  831. BOOL FileSelected = FALSE;
  832. if(pFileDlg->DoModal() == IDOK)
  833. {
  834. FilePath = pFileDlg->GetPathName();
  835. FileSelected = TRUE;
  836. CString strPathName = FilePath;
  837. CLSID clsid;
  838.     GetEncoderClsid(L"image/jpeg", &clsid);
  839. Status status = m_pDisparityBitmap->Save(strPathName.AllocSysString(), &clsid);
  840. if(Ok != status)
  841. {
  842. TRACE2(_T("nFailed to save image in '%s' filen")
  843. _T("GDI+ Error: %u"),
  844. strPathName,
  845. status);
  846. }
  847. }
  848. delete pFileDlg;
  849. pFileDlg = NULL;
  850. }