HistogramDlg.cpp
上传用户:mjs2008
上传日期:2021-05-16
资源大小:5089k
文件大小:11k
源码类别:

生物技术

开发平台:

Visual C++

  1. // HistogramDlg.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "cell.h"
  5. #include "HistogramDlg.h"
  6. #include "HSI.h"
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. extern RGB* g_pImgBuffer;
  13. extern int g_nMapHeight;
  14. extern int g_nMapWidth;
  15. extern FLAGS* g_pFlags;
  16. /////////////////////////////////////////////////////////////////////////////
  17. // CHistogramDlg dialog
  18. CHistogramDlg::CHistogramDlg(CWnd* pParent /*=NULL*/)
  19. : CDialog(CHistogramDlg::IDD, pParent)
  20. {
  21. //{{AFX_DATA_INIT(CHistogramDlg)
  22. m_Thresh_B = 0;
  23. m_Thresh_G = 0;
  24. m_Thresh_R = 0;
  25. m_Thresh_BMax = 0;
  26. m_Thresh_GMax = 0;
  27. m_Thresh_RMax = 0;
  28. m_nMag = 0;
  29. //}}AFX_DATA_INIT
  30. m_bUserRatio = false;
  31. }
  32. void CHistogramDlg::DoDataExchange(CDataExchange* pDX)
  33. {
  34. CDialog::DoDataExchange(pDX);
  35. //{{AFX_DATA_MAP(CHistogramDlg)
  36. DDX_Text(pDX, IDC_THRESH_B, m_Thresh_B);
  37. DDX_Text(pDX, IDC_THRESH_G, m_Thresh_G);
  38. DDX_Text(pDX, IDC_THRESH_R, m_Thresh_R);
  39. DDX_Text(pDX, IDC_THRESH_BMAX, m_Thresh_BMax);
  40. DDX_Text(pDX, IDC_THRESH_GMAX, m_Thresh_GMax);
  41. DDX_Text(pDX, IDC_THRESH_RMAX, m_Thresh_RMax);
  42. DDX_Text(pDX, IDC_HISTOGRAM_MAGNIFY, m_nMag);
  43. //}}AFX_DATA_MAP
  44. }
  45. BEGIN_MESSAGE_MAP(CHistogramDlg, CDialog)
  46. //{{AFX_MSG_MAP(CHistogramDlg)
  47. ON_WM_PAINT()
  48. ON_BN_CLICKED(IDC_RED, OnRed)
  49. ON_BN_CLICKED(IDC_GREEN, OnGreen)
  50. ON_BN_CLICKED(IDC_BLUE, OnBlue)
  51. ON_WM_LBUTTONDOWN()
  52. ON_WM_RBUTTONDOWN()
  53. ON_BN_CLICKED(IDC_HISTOGRAM_SAME, OnHistogramSame)
  54. ON_EN_CHANGE(IDC_HISTOGRAM_MAGNIFY, OnChangeHistogramMagnify)
  55. //}}AFX_MSG_MAP
  56. END_MESSAGE_MAP()
  57. // CHistogramDlg message handlers
  58. BEGIN_EVENTSINK_MAP(CHistogramDlg, CDialog)
  59. //{{AFX_EVENTSINK_MAP(CHistogramDlg)
  60. //}}AFX_EVENTSINK_MAP
  61. END_EVENTSINK_MAP()
  62. BOOL CHistogramDlg::OnInitDialog(void)
  63. {
  64. CDialog::OnInitDialog();
  65. // TODO: Add extra initialization here
  66. if(!g_hBitmap)
  67. MessageBox("图像文件错误!无法生成柱状图.");
  68. else
  69. {
  70. GenHistogramData();
  71. ((CButton *) GetDlgItem(IDC_RED))->SetCheck(true);
  72. CWnd *Chart;
  73. Chart = GetDlgItem(IDC_HISTOGRAM_CHART);
  74. Chart->GetWindowRect(&m_ChartRect);
  75. ScreenToClient(&m_ChartRect);
  76. m_Thresh_R = m_Thresh_G = m_Thresh_B = 0;
  77. m_Thresh_RMax = m_Thresh_GMax = m_Thresh_BMax = 255;
  78. m_nMag = ratior;
  79. UpdateData(FALSE);
  80. InvalidateRect(0, TRUE);
  81. }
  82. return TRUE; // return TRUE unless you set the focus to a control
  83. // EXCEPTION: OCX Property Pages should return FALSE
  84. }
  85. void CHistogramDlg::OnChangeHistogramMagnify(void)
  86. {
  87. // TODO: If this is a RICHEDIT control, the control will not
  88. // send this notification unless you override the CDialog::OnInitDialog()
  89. // function and call CRichEditCtrl().SetEventMask()
  90. // with the ENM_CHANGE flag ORed into the mask.
  91. // TODO: Add your control notification handler code here
  92. UpdateData(TRUE);
  93. m_bUserRatio = true;
  94. GenHistogramData();
  95. m_bUserRatio = false;
  96. InvalidateRect(0, TRUE);
  97. }
  98. void CHistogramDlg::GenHistogramData(void)
  99. {
  100. RGB *cur=g_pImgBuffer;
  101. FLAGS *cur_flag=g_pFlags;
  102. memset(m_Histogram, 0, sizeof(m_Histogram));
  103. for(int j = 0; j < g_nMapHeight; j++)
  104. {
  105. for(int i = 0; i < g_nMapWidth; i++)
  106. {
  107. if(!cur_flag->marked)
  108. {
  109. m_Histogram[0][cur->r]++;
  110. m_Histogram[1][cur->g]++;
  111. m_Histogram[2][cur->b]++;
  112. }
  113. cur_flag++;
  114. cur++;
  115. }
  116. }
  117. DWORD maxr = 0, maxg = 0, maxb = 0;
  118. double tot_pixel = g_nMapWidth * g_nMapHeight;
  119. for(int i = 0; i < 256; i++)
  120. {
  121. if(maxr < m_Histogram[0][i]) maxr = m_Histogram[0][i];
  122. if(maxg < m_Histogram[1][i]) maxg = m_Histogram[1][i];
  123. if(maxb < m_Histogram[2][i]) maxb = m_Histogram[2][i];
  124. }
  125. if(m_bUserRatio)
  126. ratior = ratiog = ratiob = m_nMag;
  127. else
  128. {
  129. ratior = tot_pixel / maxr;
  130. ratiog = tot_pixel / maxg;
  131. ratiob = tot_pixel / maxb;
  132. }
  133. for(i = 0; i < 256; i++)
  134. {
  135. m_Histogram[0][i] = (long) ((m_Histogram[0][i] * 100.0 * ratior) / tot_pixel);
  136. m_Histogram[1][i] = (long) ((m_Histogram[1][i] * 100.0 * ratiog) / tot_pixel);
  137. m_Histogram[2][i] = (long) ((m_Histogram[2][i] * 100.0 * ratiob) / tot_pixel);
  138. if(m_Histogram[0][i] > 101) m_Histogram[0][i] = 101;
  139. if(m_Histogram[1][i] > 101) m_Histogram[1][i] = 101;
  140. if(m_Histogram[2][i] > 101) m_Histogram[2][i] = 101;
  141. }
  142. }
  143. void CHistogramDlg::OnPaint(void)
  144. {
  145. CPaintDC dc(this); // device context for painting
  146. // TODO: Add your message handler code here
  147. if(((CButton *) GetDlgItem(IDC_RED))->GetCheck())
  148. {
  149. DrawData(&dc, 0); // red
  150. DrawFrame(&dc, 0);
  151. }
  152. else if(((CButton *) GetDlgItem(IDC_GREEN))->GetCheck())
  153. {
  154. DrawData(&dc, 1); // green
  155. DrawFrame(&dc, 1);
  156. }
  157. else if(((CButton *) GetDlgItem(IDC_BLUE))->GetCheck())
  158. {
  159. DrawData(&dc, 2); // blue
  160. DrawFrame(&dc, 2);
  161. }
  162. else
  163. MessageBox("unknown error");
  164. // Do not call CDialog::OnPaint() for painting messages
  165. }
  166. void CHistogramDlg::DrawFrame(CDC *dc, char type)
  167. {
  168. CPen pen;
  169. int i;
  170. m_ChartRect.left++;
  171. switch(type)
  172. {
  173. case 0:
  174. for(i = 0; i < 256; i++)
  175. {
  176. pen.CreatePen(PS_SOLID, 1, RGB(i, 0, 0));
  177. dc->SelectObject(pen);
  178. dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom + 5);
  179. dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom + 15);
  180. pen.DeleteObject();
  181. }
  182. break;
  183. case 1:
  184. for(i = 0; i < 256; i++)
  185. {
  186. pen.CreatePen(PS_SOLID, 1, RGB(0, i, 0));
  187. dc->SelectObject(pen);
  188. dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom + 5);
  189. dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom + 15);
  190. pen.DeleteObject();
  191. }
  192. break;
  193. case 2:
  194. for(i = 0; i < 256; i++)
  195. {
  196. pen.CreatePen(PS_SOLID, 1, RGB(0, 0, i));
  197. dc->SelectObject(pen);
  198. dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom + 5);
  199. dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom + 15);
  200. pen.DeleteObject();
  201. }
  202. break;
  203. }
  204. pen.CreatePen(PS_SOLID, 1, RGB(128, 128, 128));
  205. dc->SelectObject(pen);
  206. for(i = 1; i < 8; i++)
  207. {
  208. dc->MoveTo(m_ChartRect.left + i * 32, m_ChartRect.top + 1);
  209. dc->LineTo(m_ChartRect.left + i * 32, m_ChartRect.bottom - 1);
  210. }
  211. pen.DeleteObject();
  212. pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 255));
  213. dc->SelectObject(pen);
  214. switch(type)
  215. {
  216. case 0:
  217. dc->MoveTo(m_ChartRect.left + m_Thresh_R, m_ChartRect.top + 1);
  218. dc->LineTo(m_ChartRect.left + m_Thresh_R, m_ChartRect.bottom - 1);
  219. break;
  220. case 1:
  221. dc->MoveTo(m_ChartRect.left + m_Thresh_G, m_ChartRect.top + 1);
  222. dc->LineTo(m_ChartRect.left + m_Thresh_G, m_ChartRect.bottom - 1);
  223. break;
  224. case 2:
  225. dc->MoveTo(m_ChartRect.left + m_Thresh_B, m_ChartRect.top + 1);
  226. dc->LineTo(m_ChartRect.left + m_Thresh_B, m_ChartRect.bottom - 1);
  227. break;
  228. }
  229. pen.DeleteObject();
  230. pen.CreatePen(PS_SOLID, 1, RGB(0, 255, 255));
  231. dc->SelectObject(pen);
  232. switch(type)
  233. {
  234. case 0:
  235. dc->MoveTo(m_ChartRect.left + m_Thresh_RMax, m_ChartRect.top + 1);
  236. dc->LineTo(m_ChartRect.left + m_Thresh_RMax, m_ChartRect.bottom - 1);
  237. break;
  238. case 1:
  239. dc->MoveTo(m_ChartRect.left + m_Thresh_GMax, m_ChartRect.top + 1);
  240. dc->LineTo(m_ChartRect.left + m_Thresh_GMax, m_ChartRect.bottom - 1);
  241. break;
  242. case 2:
  243. dc->MoveTo(m_ChartRect.left + m_Thresh_BMax, m_ChartRect.top + 1);
  244. dc->LineTo(m_ChartRect.left + m_Thresh_BMax, m_ChartRect.bottom - 1);
  245. break;
  246. }
  247. pen.DeleteObject();
  248. m_ChartRect.left--;
  249. }
  250. void CHistogramDlg::DrawData(CDC *dc, char type)
  251. {
  252. int i;
  253. CPen pen;
  254. m_ChartRect.left++;
  255. m_ChartRect.bottom--;
  256. switch(type)
  257. {
  258. case 0:
  259. pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
  260. dc->SelectObject(pen);
  261. for(i = 0; i < 256; i++)
  262. {
  263. dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom);
  264. dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom - m_Histogram[0][i] * 2);
  265. }
  266. DeleteObject(pen);
  267. break;
  268. case 1:
  269. pen.CreatePen(PS_SOLID, 1, RGB(0, 140, 0));
  270. dc->SelectObject(pen);
  271. for(i = 0; i < 256; i++)
  272. {
  273. dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom);
  274. dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom - m_Histogram[1][i] * 2);
  275. }
  276. DeleteObject(pen);
  277. break;
  278. case 2:
  279. pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 255));
  280. dc->SelectObject(pen);
  281. for(i = 0; i < 256; i++)
  282. {
  283. dc->MoveTo(m_ChartRect.left + i, m_ChartRect.bottom);
  284. dc->LineTo(m_ChartRect.left + i, m_ChartRect.bottom - m_Histogram[2][i] * 2);
  285. }
  286. DeleteObject(pen);
  287. break;
  288. }
  289. m_ChartRect.left--;
  290. m_ChartRect.bottom++;
  291. }
  292. void CHistogramDlg::OnRed(void)
  293. {
  294. // TODO: Add your control notification handler code here
  295. m_nMag = ratior;
  296. UpdateData(FALSE);
  297. InvalidateRect(0, TRUE);
  298. }
  299. void CHistogramDlg::OnGreen(void)
  300. {
  301. // TODO: Add your control notification handler code here
  302. m_nMag = ratiog;
  303. UpdateData(FALSE);
  304. InvalidateRect(0, TRUE);
  305. }
  306. void CHistogramDlg::OnBlue(void)
  307. {
  308. // TODO: Add your control notification handler code here
  309. m_nMag = ratiob;
  310. UpdateData(FALSE);
  311. InvalidateRect(0, TRUE);
  312. }
  313. void CHistogramDlg::OnLButtonDown(UINT nFlags, CPoint point)
  314. {
  315. // TODO: Add your message handler code here and/or call default
  316. if
  317. (
  318. point.x > m_ChartRect.left
  319. && point.x < m_ChartRect.right - 1
  320. && point.y > m_ChartRect.top
  321. && point.y < m_ChartRect.bottom
  322. )
  323. {
  324. if(((CButton *) GetDlgItem(IDC_RED))->GetCheck())
  325. {
  326. m_Thresh_R = point.x - m_ChartRect.left - 1;
  327. }
  328. else if(((CButton *) GetDlgItem(IDC_GREEN))->GetCheck())
  329. {
  330. m_Thresh_G = point.x - m_ChartRect.left - 1;
  331. }
  332. else if(((CButton *) GetDlgItem(IDC_BLUE))->GetCheck())
  333. {
  334. m_Thresh_B = point.x - m_ChartRect.left - 1;
  335. }
  336. else
  337. {
  338. MessageBox("unknown error");
  339. return;
  340. }
  341. UpdateData(FALSE);
  342. InvalidateRect(&m_ChartRect, TRUE);
  343. }
  344. CDialog::OnLButtonDown(nFlags, point);
  345. }
  346. void CHistogramDlg::OnRButtonDown(UINT nFlags, CPoint point)
  347. {
  348. // TODO: Add your message handler code here and/or call default
  349. if
  350. (
  351. point.x > m_ChartRect.left
  352. && point.x < m_ChartRect.right - 1
  353. && point.y > m_ChartRect.top
  354. && point.y < m_ChartRect.bottom
  355. )
  356. {
  357. if(((CButton *) GetDlgItem(IDC_RED))->GetCheck())
  358. {
  359. m_Thresh_RMax = point.x - m_ChartRect.left - 1;
  360. }
  361. else if(((CButton *) GetDlgItem(IDC_GREEN))->GetCheck())
  362. {
  363. m_Thresh_GMax = point.x - m_ChartRect.left - 1;
  364. }
  365. else if(((CButton *) GetDlgItem(IDC_BLUE))->GetCheck())
  366. {
  367. m_Thresh_BMax = point.x - m_ChartRect.left - 1;
  368. }
  369. else
  370. {
  371. MessageBox("unknown error");
  372. return;
  373. }
  374. UpdateData(FALSE);
  375. InvalidateRect(&m_ChartRect, TRUE);
  376. }
  377. CDialog::OnRButtonDown(nFlags, point);
  378. }
  379. void CHistogramDlg::OnExclusivePressed(void)
  380. {
  381. // TODO: Add your control notification handler code here
  382. UpdateData(TRUE);
  383. }
  384. void CHistogramDlg::OnOK(void)
  385. {
  386. // TODO: Add extra validation here
  387. if(m_Thresh_R > m_Thresh_RMax || m_Thresh_G > m_Thresh_GMax || m_Thresh_B > m_Thresh_BMax)
  388. {
  389. MessageBox("阈值最大值不应小于最小值");
  390. return;
  391. }
  392. CDialog::OnOK();
  393. }
  394. void CHistogramDlg::OnHistogramSame(void)
  395. {
  396. // TODO: Add your control notification handler code here
  397. m_Thresh_GMax = m_Thresh_BMax = m_Thresh_RMax;
  398. m_Thresh_G = m_Thresh_B = m_Thresh_R;
  399. UpdateData(FALSE);
  400. InvalidateRect(0, TRUE);
  401. }
  402. /////////////////////////////////////////////////////////////////////////////
  403. // CHistogramDlg message handlers