DlgCodingHuffman.cpp
上传用户:panpan8800
上传日期:2013-06-29
资源大小:274k
文件大小:5k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. // DlgCodingHuffman.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "imageProcessing.h"
  5. #include "DlgCoding.h"
  6. #include <math.h>
  7. #ifdef _DEBUG
  8. #define new DEBUG_NEW
  9. #undef THIS_FILE
  10. static char THIS_FILE[] = __FILE__;
  11. #endif
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CDlgHuffman dialog
  14. CDlgHuffman::CDlgHuffman(CWnd* pParent /*=NULL*/)
  15. : CDialog(CDlgHuffman::IDD, pParent)
  16. {
  17. //{{AFX_DATA_INIT(CDlgHuffman)
  18. m_dEntropy = 0.0;
  19. m_dCodLength = 0.0;
  20. m_dRatio = 0.0;
  21. //}}AFX_DATA_INIT
  22. }
  23. void CDlgHuffman::DoDataExchange(CDataExchange* pDX)
  24. {
  25. CDialog::DoDataExchange(pDX);
  26. //{{AFX_DATA_MAP(CDlgHuffman)
  27. DDX_Control(pDX, IDC_LST_Table, m_lstTable);
  28. DDX_Text(pDX, IDC_EDIT1, m_dEntropy);
  29. DDX_Text(pDX, IDC_EDIT2, m_dCodLength);
  30. DDX_Text(pDX, IDC_EDIT3, m_dRatio);
  31. //}}AFX_DATA_MAP
  32. }
  33. BEGIN_MESSAGE_MAP(CDlgHuffman, CDialog)
  34. //{{AFX_MSG_MAP(CDlgHuffman)
  35. //}}AFX_MSG_MAP
  36. END_MESSAGE_MAP()
  37. /////////////////////////////////////////////////////////////////////////////
  38. // CDlgHuffman message handlers
  39. BOOL CDlgHuffman::OnInitDialog() 
  40. {
  41. // 调用默认得OnInitDialog()函数
  42. CDialog::OnInitDialog();
  43. // 循环变量
  44. LONG i;
  45. LONG j;
  46. LONG k;
  47. // 中间变量
  48. double dT;
  49. // 字符串变量
  50. CString str2View;
  51. // 控件ListCtrl的ITEM
  52. LV_ITEM lvItem;
  53. // 保存控件ListCtrl中添加的ITEM编号
  54. int nItem2View;
  55. // 保存计算中间结果的数组
  56. double * dTemp;
  57. // 数组用来存放灰度值和其位置之间的映射
  58. int * n4Turn;
  59. // 初始化变量
  60. m_dEntropy = 0.0;
  61. m_dCodLength = 0.0;
  62. // 分配内存
  63. m_strCode = new CString[nColorNum];
  64. n4Turn  = new int[nColorNum];
  65. dTemp = new double[nColorNum];
  66. // 令dTemp赋值
  67. // 开始的灰度值按灰度值大小排列相同
  68. for (i = 0; i < nColorNum; i ++)
  69. {
  70. dTemp[i] = dProba[i];
  71. n4Turn[i] = i;
  72. }
  73. // 用冒泡法对进行灰度值出现的概率排序
  74. // 同时改变灰度值位置的映射关系
  75. for (j = 0; j < nColorNum - 1; j ++)
  76. {
  77. for (i = 0; i < nColorNum - j - 1; i ++)
  78. {
  79. if (dTemp[i] > dTemp[i + 1])
  80. {
  81. dT = dTemp[i];
  82. dTemp[i] = dTemp[i + 1];
  83. dTemp[i + 1] = dT;
  84. // 将i和i+1灰度的位置值互换
  85. for (k = 0; k < nColorNum; k ++)
  86. {
  87. if (n4Turn[k] == i)
  88. n4Turn[k] = i + 1;
  89. else if (n4Turn[k] == i + 1)
  90. n4Turn[k] = i;
  91. }
  92. }
  93. }
  94. }
  95. /*******************************************************
  96. 计算哈夫曼编码表
  97. *******************************************************/
  98. // 从概率大于0处开始编码
  99. for (i = 0; i < nColorNum - 1; i ++)
  100. {
  101. if (dTemp[i] > 0)
  102. break;
  103. }
  104. for (; i < nColorNum - 1; i ++)
  105. {
  106. // 更新m_strCode
  107. for (k = 0; k < nColorNum; k ++)
  108. {
  109. // 灰度值是否i
  110. if (n4Turn[k] == i)
  111. {
  112. // 灰度值较小的码字加1
  113. m_strCode[k] = "1" + m_strCode[k];
  114. }
  115. else if (n4Turn[k] == i + 1)
  116. {
  117. // 灰度值较小的码字加0
  118. m_strCode[k] = "0" + m_strCode[k];
  119. }
  120. }
  121. // 概率最小的两个概率相加,保存在dTemp[i + 1]中
  122. dTemp[i + 1] += dTemp[i];
  123. // 改变映射关系
  124. for (k = 0; k < nColorNum; k ++)
  125. {
  126. // 将位置为i的灰度值i改为灰度值i+1
  127. if (n4Turn[k] == i)
  128. n4Turn[k] = i + 1;
  129. }
  130. // 重新排序
  131. for (j = i + 1; j < nColorNum - 1; j ++)
  132. {
  133. if (dTemp[j] > dTemp[j + 1])
  134. {
  135. // 互换
  136. dT = dTemp[j];
  137. dTemp[j] = dTemp[j + 1];
  138. dTemp[j + 1] = dT;
  139. // // 将i和i+1灰度的位置值互换
  140. for (k = 0; k < nColorNum; k ++)
  141. {
  142. if (n4Turn[k] == j)
  143. n4Turn[k] = j + 1;
  144. else if (n4Turn[k] == j + 1)
  145. n4Turn[k] = j;
  146. }
  147. }
  148. else
  149. // 退出循环
  150. break;
  151. }
  152. }
  153. // 计算图像熵
  154. for (i = 0; i < nColorNum; i ++)
  155. {
  156. if (dProba[i] > 0)
  157. {
  158. // 计算图像熵
  159. m_dEntropy -= dProba[i] * log(dProba[i]) / log(2.0);
  160. }
  161. }
  162. // 计算平均码字长度
  163. for (i = 0; i < nColorNum; i ++)
  164. {
  165. // 累加
  166. m_dCodLength += dProba[i] * m_strCode[i].GetLength();
  167. }
  168. // 计算编码效率
  169. m_dRatio = m_dEntropy / m_dCodLength;
  170. // 保存变动
  171. UpdateData(FALSE);
  172. /*************************************************
  173. 输出计算结果
  174. *************************************************/
  175. // 设置CListCtrl控件样式
  176. m_lstTable.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
  177. // 给List控件添加Header
  178. m_lstTable.InsertColumn(0, "灰度值", LVCFMT_LEFT, 60, 0);
  179. m_lstTable.InsertColumn(1, "概率值", LVCFMT_LEFT, 78, 0);
  180. m_lstTable.InsertColumn(2, "哈夫曼编码", LVCFMT_LEFT, 110, 1);
  181. m_lstTable.InsertColumn(3, "码字长度", LVCFMT_LEFT, 78, 2);
  182. // 设置样式为文本
  183. lvItem.mask = LVIF_TEXT;
  184. // 添加显示
  185. for (i = 0; i < nColorNum; i ++)
  186. {
  187. // 第一列显示
  188. lvItem.iItem = m_lstTable.GetItemCount();
  189. str2View.Format("%u",i);
  190. lvItem.iSubItem = 0;
  191. lvItem.pszText= (LPTSTR)(LPCTSTR)str2View;
  192. nItem2View = m_lstTable.InsertItem(&lvItem);
  193. // 其它列显示
  194. lvItem.iItem = nItem2View;
  195. // 添加灰度值的概率值
  196. lvItem.iSubItem = 1;
  197. str2View.Format("%f",dProba[i]);
  198. lvItem.pszText = (LPTSTR)(LPCTSTR)str2View;
  199. m_lstTable.SetItem(&lvItem);
  200. // 添加哈夫曼编码
  201. lvItem.iSubItem = 2;
  202. lvItem.pszText = (LPTSTR)(LPCTSTR)m_strCode[i];
  203. m_lstTable.SetItem(&lvItem);
  204. // 添加码字长度
  205. lvItem.iSubItem = 3;
  206. str2View.Format("%u",m_strCode[i].GetLength());
  207. lvItem.pszText = (LPTSTR)(LPCTSTR)str2View;
  208. m_lstTable.SetItem(&lvItem);
  209. }
  210. //  内存释放
  211. delete n4Turn;
  212. delete dTemp;
  213. // 返回TRUE
  214. return TRUE;
  215. }