gusucode.com > VC 实现的二维小波变换用于图像去噪、压缩等源码程序 > HaffmanDlg.cpp
// HaffmanDlg.cpp : implementation file // #include "stdafx.h" #include "小波变换.h" #include "HaffmanDlg.h" #include "math.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CHaffmanDlg dialog CHaffmanDlg::CHaffmanDlg(CWnd* pParent /*=NULL*/) : CDialog(CHaffmanDlg::IDD, pParent) { //{{AFX_DATA_INIT(CHaffmanDlg) m_avgcodelen = 0.0; m_efficiency = 0.0; m_entropy = 0.0; m_compressionrate = 0.0; //}}AFX_DATA_INIT } void CHaffmanDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CHaffmanDlg) DDX_Control(pDX, IDC_LISTHUFFMAN, m_listhuffman); DDX_Text(pDX, IDC_EDITAVGCODELEN, m_avgcodelen); DDX_Text(pDX, IDC_EDITEFFICIENCY, m_efficiency); DDX_Text(pDX, IDC_EDITENTROPY, m_entropy); DDX_Text(pDX, IDC_EDITCOMPRESSIONRATE, m_compressionrate); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CHaffmanDlg, CDialog) //{{AFX_MSG_MAP(CHaffmanDlg) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CHaffmanDlg message handlers BOOL CHaffmanDlg::OnInitDialog() { CString str; LONG i,j,k; double fT; // ListCtrl的ITEM LV_ITEM lvitem; // 中间变量,保存ListCtrl中添加的ITEM编号 int iActualItem; // 调用默认得OnInitDialog()函数 CDialog::OnInitDialog(); // 初始化变量 m_entropy = 0.0; m_avgcodelen = 0.0; // 计算图像熵 for (i = 0; i < m_iColorNum; i ++) { if (m_fFreq[i] > 0)// 判断概率是否大于0 { m_entropy -= m_fFreq[i] * log(m_fFreq[i]) / log(2.0); } } double* fTemp;// 保存计算中间结果的数组 int * iMap;// 保存映射关系的数组 // 分配内存 fTemp = new double[m_iColorNum]; iMap = new int[m_iColorNum]; // 设置List控件样式 m_listhuffman.ModifyStyle(LVS_TYPEMASK, LVS_REPORT); // 给List控件添加Header m_listhuffman.InsertColumn(0, "灰度值", LVCFMT_CENTER, 60, 0); m_listhuffman.InsertColumn(1, "出现频率", LVCFMT_CENTER, 80, 0); m_listhuffman.InsertColumn(2, "哈夫曼编码", LVCFMT_CENTER, 150, 1); m_listhuffman.InsertColumn(3, "码字长度", LVCFMT_CENTER, 80, 2); // 设置样式为文本 lvitem.mask = LVIF_TEXT; // 初始化fTemp为m_fFreq m_strCode = new CString[m_iColorNum]; for (i = 0; i < m_iColorNum; i ++) { fTemp[i] = m_fFreq[i]; iMap[i] = 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; // 更新映射关系 for (k = 0; k < m_iColorNum; k ++) { if (iMap[k] == i)// 判断是否是fTemp[i]的子节点 { iMap[k] = i + 1;// 改变映射到节点i+1 } else if (iMap[k] == i + 1) { iMap[k] = i; // 改变映射到节点i } } } } } // 计算哈夫曼编码表 // 找到概率大于0处才开始编码 for (i = 0; i < m_iColorNum - 1; i ++) { if (fTemp[i] > 0) // 判断概率是否大于0 { break; } } // 开始编码 for (; i < m_iColorNum - 1; i ++) { // 更新m_strCode for (k = 0; k < m_iColorNum; k ++) { if (iMap[k] == i)// 判断是否是fTemp[i]的子节点 { m_strCode[k] = "1" + m_strCode[k];// 改变编码字符串 } else if (iMap[k] == i + 1) { m_strCode[k] = "0" + m_strCode[k];// 改变编码字符串 } } fTemp[i + 1] += fTemp[i]; // 概率最小的两个概率相加,保存在fTemp[i + 1]中 // 改变映射关系 for (k = 0; k < m_iColorNum; k ++) { if (iMap[k] == i)// 判断是否是fTemp[i]的子节点 { iMap[k] = i + 1;// 改变映射到节点i+1 } } // 重新排序 for (j = i + 1; j < m_iColorNum - 1; j ++) { if (fTemp[j] > fTemp[j + 1]) { // 互换 fT = fTemp[j]; fTemp[j] = fTemp[j + 1]; fTemp[j + 1] = fT; // 更新映射关系 for (k = 0; k < m_iColorNum; k ++) { if (iMap[k] == j)// 判断是否是fTemp[i]的子节点 { iMap[k] = j + 1;// 改变映射到节点j+1 } else if (iMap[k] == j + 1) { iMap[k] = j;// 改变映射到节点j } } } else { break;// 退出循环 } } } // 计算平均码字长度 for (i = 0; i < m_iColorNum; i ++) { m_avgcodelen += m_fFreq[i] * m_strCode[i].GetLength(); // 累加 } m_efficiency = m_entropy / m_avgcodelen; // 计算编码效率 m_compressionrate=m_avgcodelen/8.0; ////////////////////////////////////////////////////////// // 输出计算结果 // 计算平均码字长度 for (i = 0; i < m_iColorNum; i ++) { // 添加一项 lvitem.iItem = m_listhuffman.GetItemCount(); str.Format("%u",i); lvitem.iSubItem = 0; lvitem.pszText= (LPTSTR)(LPCTSTR)str; iActualItem = m_listhuffman.InsertItem(&lvitem); // 添加其它列 lvitem.iItem = iActualItem; // 添加灰度值出现的频率 lvitem.iSubItem = 1; str.Format("%f",m_fFreq[i]); lvitem.pszText = (LPTSTR)(LPCTSTR)str; m_listhuffman.SetItem(&lvitem); // 添加哈夫曼编码 lvitem.iSubItem = 2; lvitem.pszText = (LPTSTR)(LPCTSTR)m_strCode[i]; m_listhuffman.SetItem(&lvitem); // 添加码字长度 lvitem.iSubItem = 3; str.Format("%u",m_strCode[i].GetLength()); lvitem.pszText = (LPTSTR)(LPCTSTR)str; m_listhuffman.SetItem(&lvitem); } UpdateData(FALSE); // 保存变动 delete fTemp; delete iMap; return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE }