?? dlgshannon.cpp
字號:
// DlgShannon.cpp : implementation file//#include "stdafx.h"#include "ch1_1.h"#include "DlgShannon.h"#include <math.h>#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif/////////////////////////////////////////////////////////////////////////////// CDlgShannon dialogCDlgShannon::CDlgShannon(CWnd* pParent /*=NULL*/) : CDialog(CDlgShannon::IDD, pParent){ //{{AFX_DATA_INIT(CDlgShannon) m_dEntropy = 0.0; m_dAvgCodeLen = 0.0; m_dEfficiency = 0.0; //}}AFX_DATA_INIT}void CDlgShannon::DoDataExchange(CDataExchange* pDX){ CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CDlgShannon) DDX_Control(pDX, IDC_LST_Table, m_lstTable); DDX_Text(pDX, IDC_EDIT1, m_dEntropy); DDX_Text(pDX, IDC_EDIT2, m_dAvgCodeLen); DDX_Text(pDX, IDC_EDIT3, m_dEfficiency); //}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CDlgShannon, CDialog) //{{AFX_MSG_MAP(CDlgShannon) //}}AFX_MSG_MAPEND_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CDlgShannon message handlersBOOL CDlgShannon::OnInitDialog() { // 字符串變量 CString str; // 循環變量 LONG i; LONG j; // 中間變量 FLOAT fT; LONG iTemp; // 保存計算中間結果的數組 FLOAT * fTemp; // 保存映射關系的數組 LONG * iMap; // 當前編碼區間的頻率和 FLOAT fTotal; // 計數(編碼完成的個數) LONG iCount = 0; // 頻率和 FLOAT fSum; // 起始位置 LONG iStart; // 指向布爾型數組的指針 BOOL * bFinished; // 調用默認得OnInitDialog()函數 CDialog::OnInitDialog(); // 初始化變量 m_dEntropy = 0.0; m_dAvgCodeLen = 0.0; // 計算圖像熵 for (i = 0; i < m_iColorNum; i ++) { // 判斷概率是否大于0 if (m_fFreq[i] > 0) { // 計算圖像熵 m_dEntropy -= m_fFreq[i] * log(m_fFreq[i]) / log(2.0); } } // 分配內存 fTemp = new FLOAT[m_iColorNum]; m_strCode = new CString[m_iColorNum]; bFinished = new BOOL[m_iColorNum]; iMap = new LONG[m_iColorNum]; fTotal = 0; // 初始化fTemp為m_fFreq, bFinished為FALSE for (i = 0; i < m_iColorNum; i ++) { // 賦值 fTemp[i] = m_fFreq[i]; // 初始化映射關系 iMap[i] = i; // 初始化為FALSE bFinished[i] = FALSE; // 計算fTotal fTotal += m_fFreq[i]; } // 用冒泡法對進行灰度值出現的概率排序,結果保存在數組fTemp中 for (j = 0; j < m_iColorNum - 1; j ++) { for (i = 0; i < m_iColorNum - j - 1; i ++) { if (fTemp[i] > fTemp[i + 1]) { // 互換 fT = fTemp[i]; fTemp[i] = fTemp[i + 1]; fTemp[i + 1] = fT; // 更新映射關系 iTemp = iMap[i]; iMap[i] = iMap[i+1]; iMap[i+1] = iTemp; } } } ////////////////////////////////////////////////////////// // 計算香農-弗諾編碼表 // 找到概率大于0處才開始編碼 for (iStart = 0; iStart < m_iColorNum - 1; iStart ++) { // 判斷概率是否大于0 if (fTemp[iStart] > 0) { // 跳出 break; } } // 初始化變量 fSum = 0; str = "1"; // 開始編碼 while(iCount < m_iColorNum) { // 初始化iCount為iStart iCount = iStart; // 循環編碼 for (i = iStart; i < m_iColorNum; i ++) { // 判斷是否編碼完成 if (bFinished[i] == FALSE) { // 編碼沒有完成,繼續編碼 // fSum加當前出現的頻率 fSum += fTemp[i]; // 判斷是否超出總和的一半 if (fSum > fTotal/2.0) { // 超出,追加的字符改為0 str = "0"; } // 編碼追加字符1或0 m_strCode[iMap[i]] += str; // 判斷是否編碼完一段 if (fSum == fTotal) { // 完成一部分編碼,重新計算fTotal // 初始化fSum為0 fSum = 0; // 判斷是否是最后一個元素 if (i == m_iColorNum - 1) { // 是最后,設置從起始點開始 j = iStart; } else { // 不是最后,設置從下一個點開始 j = i + 1; } // 保存j值 iTemp = j; str = m_strCode[iMap[j]]; // 計算下一段的fTotal fTotal = 0; for (; j < m_iColorNum; j++) { // 判斷是否是同一段編碼 if ((m_strCode[iMap[j]].Right(1) != str.Right(1)) || (m_strCode[iMap[j]].GetLength() != str.GetLength())) { // 退出循環 break; } // 累加 fTotal += fTemp[j]; } // 初始化str為1 str = "1"; // 判斷是否該段長度為1 if (iTemp + 1 == j) { // 是,表示該段編碼已經完成 bFinished[iTemp] = TRUE; } } } else { // iCount加1 iCount ++; // 計算下一次循環的fTotal // 初始化fSum為0 fSum = 0; // 判斷是否是最后一個元素 if (i == m_iColorNum - 1) { // 是最后,設置從起始點開始 j = iStart; } else { // 不是最后,設置從下一個點開始 j = i + 1; } // 保存j值 iTemp = j; str = m_strCode[iMap[j]]; // 計算下一段的fTotal fTotal = 0; for (; j < m_iColorNum; j++) { // 判斷是否是同一段編碼 if ((m_strCode[iMap[j]].Right(1) != str.Right(1)) || (m_strCode[iMap[j]].GetLength() != str.GetLength())) { // 退出循環 break; } // 累加 fTotal += fTemp[j]; } // 初始化str為1 str = "1"; // 判斷是否該段長度為1 if (iTemp + 1 == j) { // 是,表示該段編碼已經完成 bFinished[iTemp] = TRUE; } } } } // 計算平均碼字長度 for (i = 0; i < m_iColorNum; i ++) { // 累加 m_dAvgCodeLen += m_fFreq[i] * m_strCode[i].GetLength(); } // 計算編碼效率 m_dEfficiency = m_dEntropy / m_dAvgCodeLen; // 保存變動 UpdateData(FALSE); ////////////////////////////////////////////////////////// // 輸出計算結果 // ListCtrl的ITEM LV_ITEM lvitem; // 中間變量,保存ListCtrl中添加的ITEM編號 int iActualItem; // 設置List控件樣式 m_lstTable.ModifyStyle(LVS_TYPEMASK, LVS_REPORT); // 給List控件添加Header m_lstTable.InsertColumn(0, "灰度值", LVCFMT_LEFT, 60, 0); m_lstTable.InsertColumn(1, "出現頻率", LVCFMT_LEFT, 78, 0); m_lstTable.InsertColumn(2, "香農弗諾編碼", LVCFMT_LEFT, 110, 1); m_lstTable.InsertColumn(3, "碼字長度", LVCFMT_LEFT, 78, 2); // 設置樣式為文本 lvitem.mask = LVIF_TEXT; // 計算平均碼字長度 for (i = 0; i < m_iColorNum; i ++) { // 添加一項 lvitem.iItem = m_lstTable.GetItemCount(); str.Format("%u",i); lvitem.iSubItem = 0; lvitem.pszText= (LPTSTR)(LPCTSTR)str; iActualItem = m_lstTable.InsertItem(&lvitem); // 添加其它列 lvitem.iItem = iActualItem; // 添加灰度值出現的頻率 lvitem.iSubItem = 1; str.Format("%f",m_fFreq[i]); lvitem.pszText = (LPTSTR)(LPCTSTR)str; m_lstTable.SetItem(&lvitem); // 添加香農弗諾編碼 lvitem.iSubItem = 2; lvitem.pszText = (LPTSTR)(LPCTSTR)m_strCode[i]; m_lstTable.SetItem(&lvitem); // 添加碼字長度 lvitem.iSubItem = 3; str.Format("%u",m_strCode[i].GetLength()); lvitem.pszText = (LPTSTR)(LPCTSTR)str; m_lstTable.SetItem(&lvitem); } // 返回TRUE return TRUE;}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -