DlgShannon.cpp
上传用户:piaozanzhu
上传日期:2008-02-14
资源大小:212k
文件大小:7k
源码类别:

图形图像处理

开发平台:

Visual C++

  1. // DlgShannon.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. // CDlgShannon dialog
  14. CDlgShannon::CDlgShannon(CWnd* pParent /*=NULL*/)
  15. : CDialog(CDlgShannon::IDD, pParent)
  16. {
  17. //{{AFX_DATA_INIT(CDlgShannon)
  18. //}}AFX_DATA_INIT
  19. }
  20. /*
  21. void CDlgShannon::DoDataExchange(CDataExchange* pDX)
  22. {
  23. CDialog::DoDataExchange(pDX);
  24. //{{AFX_DATA_MAP(CDlgShannon)
  25. //}}AFX_DATA_MAP
  26. }
  27. */
  28. BEGIN_MESSAGE_MAP(CDlgShannon, CDialog)
  29. //{{AFX_MSG_MAP(CDlgShannon)
  30. //}}AFX_MSG_MAP
  31. END_MESSAGE_MAP()
  32. /////////////////////////////////////////////////////////////////////////////
  33. // CDlgShannon message handlers
  34. /*
  35. BOOL CDlgShannon::OnInitDialog() 
  36. {
  37. // 调用默认得OnInitDialog()函数
  38. CDialog::OnInitDialog();
  39. // 初始化变量
  40. m_dEntropy = 0.0;
  41. m_dAvgCodeLen = 0.0;
  42. // 字符串变量
  43. CString str;
  44. str = "1";
  45. // 循环变量
  46. LONG i;
  47. LONG j;
  48. // 控件ListCtrl的ITEM
  49. LV_ITEM lvItem;
  50. // 保存控件ListCtrl中添加的ITEM编号
  51. int nItem2View;
  52. // 中间变量
  53. double dT;
  54. LONG lTemp;
  55. // 保存计算中间结果的数组
  56. double * dTemp;
  57. dTemp = new double[m_nColorNum];
  58. // 数组用来存放灰度值和其位置之间的映射
  59. LONG * l4Turn;
  60. l4Turn = new LONG[m_nColorNum];
  61. // 当前编码区间的概率和
  62. double dAccum;
  63. dAccum = 1.0;
  64. // 已经编码灰度值概率的统计和
  65. double dSum;
  66. dSum    = 0;
  67. // 已编码灰度值
  68. LONG lCount = 0;
  69. // 起始位置
  70. LONG lBegin;
  71. // 指示编码是否已经完成一段
  72. BOOL * bFinished;
  73. bFinished = new BOOL[m_nColorNum];
  74. // 分配内存
  75. m_strCode = new CString[m_nColorNum];
  76. for (i = 0; i < m_nColorNum; i ++)
  77. {
  78. // 初始化为FALSE
  79. bFinished[i] = FALSE;
  80. // 将概率赋值dTemp数组
  81. dTemp[i] = m_dProba[i];
  82. // 按灰度值大小顺序排列
  83. l4Turn[i] = i;
  84. }
  85. // 用冒泡法对进行灰度值出现的概率排序
  86. // 同时改变灰度值位置的映射关系
  87. for (j = 0; j < m_nColorNum - 1; j ++)
  88. for (i = 0; i < m_nColorNum - j - 1; i ++)
  89. if (dTemp[i] > dTemp[i + 1])
  90. {
  91. // 互换
  92. dT = dTemp[i];
  93. dTemp[i] = dTemp[i + 1];
  94. dTemp[i + 1] = dT;
  95. // 将i和i+1灰度的位置值互换
  96. lTemp = l4Turn[i];
  97. l4Turn[i] = l4Turn[i+1];
  98. l4Turn[i+1] = lTemp;
  99. }
  100. */
  101. /*******************************************************
  102. 计算香农-弗诺编码表
  103. *******************************************************/
  104. /*
  105. // 从概率大于0处开始编码
  106. for (lBegin = 0; lBegin < m_nColorNum - 1; lBegin ++)
  107. if (dTemp[lBegin] > 0)
  108. break;
  109. // 开始编码
  110. while(lCount < m_nColorNum)
  111. {
  112. // 从概率大于零的灰度值开始编码
  113. lCount = lBegin;
  114. // 对区间进行分割,对每个区间的灰度值编码
  115. for (i = lBegin; i < m_nColorNum; i ++)
  116. {
  117. // 判断是否编码完成
  118. if (bFinished[i] == FALSE)
  119. {
  120. // 增加当前编码区间的概率综合
  121. dSum += dTemp[i];
  122. // 判断是否超出总和的一半
  123. if (dSum > dAccum/2.0)
  124. {
  125. // 超出,追加的字符改为0
  126. str = "0";
  127. }
  128. // 追加字符
  129. m_strCode[l4Turn[i]] = m_strCode[l4Turn[i]] + str;
  130. // 判断是否编码完一段
  131. if (dSum == dAccum)
  132. {
  133. // 完成一部分编码,重新计算dAccum
  134. // 初始化dSum为0
  135. dSum = 0;
  136. // 判断是不是对所有灰度值已经编码一遍
  137. if (i == m_nColorNum - 1)
  138. j = lBegin;
  139. else
  140. j = i + 1;
  141. // 保存j值
  142. lTemp = j;
  143. str = m_strCode[l4Turn[j]];
  144. // 计算下一编码区间的概率总和
  145. dAccum = 0;
  146. for (; j < m_nColorNum; j++)
  147. {
  148. // 判断是否是同一段编码
  149. if ((m_strCode[l4Turn[j]].Right(1) != str.Right(1)) 
  150. || (m_strCode[l4Turn[j]].GetLength() != str.GetLength()))
  151. break;
  152. // 当前区间的概率总和增加
  153. dAccum += dTemp[j];
  154. }
  155. // 码字增加值为1
  156. str = "1";
  157. // 判断该段编码已经完成
  158. if (lTemp + 1 == j)
  159. bFinished[lTemp] = TRUE;
  160. }
  161. }
  162. else
  163. {
  164. //  开始下一轮编码
  165. lCount ++;
  166. // 重新赋2dSum为0
  167. dSum = 0;
  168. // 判断是不是对所有灰度值已经编码一遍
  169. if (i == m_nColorNum - 1)
  170. j = lBegin;
  171. else
  172. j = i + 1;
  173. // 保存j值
  174. lTemp = j;
  175. str = m_strCode[l4Turn[j]];
  176. // 计算下一编码区间的概率总和
  177. dAccum = 0;
  178. for (; j < m_nColorNum; j++)
  179. {
  180. // 判断是否是同一段编码
  181. if ((m_strCode[l4Turn[j]].Right(1) != str.Right(1)) 
  182. || (m_strCode[l4Turn[j]].GetLength() != str.GetLength()))
  183. {
  184. // 退出循环
  185. break;
  186. }
  187. // 累加
  188. dAccum += dTemp[j];
  189. }
  190. str = "1";
  191. // 判断该段编码已经完成
  192. if (lTemp + 1 == j)
  193. bFinished[lTemp] = TRUE;
  194. }
  195. }
  196. }
  197. // 计算图像熵
  198. for (i = 0; i < m_nColorNum; i ++)
  199. {
  200. // 判断概率是否大于0
  201. if (m_dProba[i] > 0)
  202. {
  203. // 计算图像熵
  204. m_dEntropy -= m_dProba[i] * log(m_dProba[i]) / log(2.0);
  205. }
  206. }
  207. // 计算平均码字长度
  208. for (i = 0; i < m_nColorNum; i ++)
  209. {
  210. // 累加
  211. m_dAvgCodeLen += m_dProba[i] * m_strCode[i].GetLength();
  212. }
  213. // 计算编码效率
  214. m_dEfficiency = m_dEntropy / m_dAvgCodeLen;
  215. // 保存变动
  216. UpdateData(FALSE);
  217. */ /*************************************************
  218. 输出编码结果
  219. *************************************************/
  220. /*
  221. // 设置List控件样式
  222. m_lstTable.ModifyStyle(LVS_TYPEMASK, LVS_REPORT);
  223. // 给List控件添加Header
  224. m_lstTable.InsertColumn(0, "灰度值", LVCFMT_LEFT, 60, 0);
  225. m_lstTable.InsertColumn(1, "灰度值概率", LVCFMT_LEFT, 78, 0);
  226. m_lstTable.InsertColumn(2, "香农-弗诺编码", LVCFMT_LEFT, 110, 1);
  227. m_lstTable.InsertColumn(3, "码字长度", LVCFMT_LEFT, 78, 2);
  228. // 设置样式为文本
  229. lvItem.mask = LVIF_TEXT;
  230. // 添加显示
  231. for (i = 0; i < m_nColorNum; i ++)
  232. {
  233. // 第一列显示
  234. lvItem.iItem = m_lstTable.GetItemCount();
  235. str.Format("%u",i);
  236. lvItem.iSubItem = 0;
  237. lvItem.pszText= (LPTSTR)(LPCTSTR)str;
  238. nItem2View = m_lstTable.InsertItem(&lvItem);
  239. // 其它列显示
  240. lvItem.iItem = nItem2View;
  241. // 添加灰度值出现的频率
  242. lvItem.iSubItem = 1;
  243. str.Format("%f",m_dProba[i]);
  244. lvItem.pszText = (LPTSTR)(LPCTSTR)str;
  245. m_lstTable.SetItem(&lvItem);
  246. // 添加香农-弗诺编码
  247. lvItem.iSubItem = 2;
  248. lvItem.pszText = (LPTSTR)(LPCTSTR)m_strCode[i];
  249. m_lstTable.SetItem(&lvItem);
  250. // 添加码字长度
  251. lvItem.iSubItem = 3;
  252. str.Format("%u",m_strCode[i].GetLength());
  253. lvItem.pszText = (LPTSTR)(LPCTSTR)str;
  254. m_lstTable.SetItem(&lvItem);
  255. }
  256. //  内存释放
  257. delete l4Turn;
  258. delete dTemp;
  259. delete bFinished;
  260. return TRUE;
  261. }
  262. */