www.pudn.com > 图像处理源代码.rar > Task5.cpp
// Task5.cpp : implementation file // #include "stdafx.h" #include "tuxiang.h" #include "image.h" #include "imgview.h" #include "Task5.h" #include#ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif #define INDEXNUM 256 CODETABLEITEM codetab[INDEXNUM]; //遍历HUFFMAN树,生成各索引值的HUFFMAN码 // node指向当前结点,codelen为当前的码长, codeval为当前的编码 void list(TWOTREE *node,int codelen,int codeval) { if(node->lChild ==NULL && node->rChild ==NULL) { codetab[node->indexvalue].codelen = codelen; codetab[node->indexvalue].codeval = codeval; } else { list(node->lChild,codelen+1,codeval*2+1); list(node->rChild,codelen+1,codeval*2); } } void listfree(TWOTREE* node) { if(node->lChild !=NULL) listfree(node->lChild); if(node->rChild !=NULL) listfree(node->rChild); } int compare( const void *arg1, const void *arg2 ) { /* Compare all of both strings: */ HISTOARRAY *val1,*val2; val1=( HISTOARRAY* ) arg1; val2=( HISTOARRAY* ) arg2; return (val2->count - val1->count ); } ///////////////////////////////////////////////////////////////////////////// // CTask5 property page IMPLEMENT_DYNCREATE(CTask5, CPropertyPage) CTask5::CTask5() : CPropertyPage(CTask5::IDD) { //{{AFX_DATA_INIT(CTask5) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT } CTask5::~CTask5() { } void CTask5::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CTask5) // NOTE: the ClassWizard will add DDX and DDV calls here //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CTask5, CPropertyPage) //{{AFX_MSG_MAP(CTask5) ON_BN_CLICKED(IDOPEN, OnOpen) ON_BN_CLICKED(IDCLEAR, OnClear) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CTask5 message handlers extern MYIMAGE* pImage; extern CImgView *m_ImgView; void CTask5::OnOpen() { if(m_ImgView!=NULL) m_ImgView->ShowWindow (SW_HIDE); if(pImage!=NULL) delete pImage; static char BASED_CODE szFilter[] = "图象文件 (*.bmp)|*.bmp"; CString sFileName; //显示一个Open File Dialog CFileDialog opendlg(TRUE,NULL,NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,szFilter,NULL); int choice=opendlg.DoModal(); if(choice!=IDOK) return; //读取文件名 sFileName=opendlg.GetPathName(); if(opendlg.GetFileExt()=="bmp") pImage=ReadBmp(sFileName,this->m_hWnd); if(m_ImgView==NULL) m_ImgView=new CImgView(pImage,this); m_ImgView->ShowWindow (SW_SHOWNORMAL); m_ImgView->DisplayImage(); HISTOARRAY histoarray[INDEXNUM]; for(int x=0;x Height * pImage->Width ;x++) histoarray[pImage->ImgData[x]].count++; /* histoarray[0].count=40; histoarray[1].count=8; histoarray[2].count=8; histoarray[3].count=20; histoarray[4].count=12; histoarray[5].count=8; histoarray[6].count=4; histoarray[7].count=0;*/ for(x=0;x lChild=NULL; tt[x]->rChild=NULL; tt[x]->Parent=NULL; tt[x]->indexvalue=histoarray[x].indexvalue; tt[x]->count=histoarray[x].count; } for(x=1;x rChild = tt[INDEXNUM-x]; //概率最小的为右子结点 tt[INDEXNUM-x]->Parent=newnode; newnode->lChild = tt[INDEXNUM-x-1]; //概率次小的为左子结点 tt[INDEXNUM-x-1]->Parent=newnode; //父结点的概率为两个子结点的概率之和 newnode->count = newnode->lChild ->count + newnode->rChild ->count ; //将父结点按概率顺序插入到序列中,始终保持序列的概率按顺序排列, //丢弃原最小的两个结点 int times=0; int end=INDEXNUM-x-2; while(end-times>=0 && newnode->count > tt[end-times]->count ) { tt[end-times+1]=tt[end-times]; times++; } tt[end-times+1]=newnode; } TWOTREE *root=tt[0]; //根结点 list(root,0,0); listfree(root); // 下面的代码用于计算平均码长、熵以及显示代码表 FILE *result=fopen("result.txt","w"); long int totalbit=0; double h=0.0; for(x=0;x Height * pImage->Width); h += p*log10(p)/log10(2.0); totalbit += codetab[x].codelen * codetab[x].count ; fprintf(result,"index:%4d count: %8d codelen: %2d codeval %6X \n", x,codetab[x].count, codetab[x].codelen,codetab[x].codeval); } double averlen=(double)totalbit/(pImage->Height * pImage->Width); fprintf(result,"\nAverage code length: %f\n",averlen); fprintf(result,"Entropy = %f\n",fabs(h)); fclose(result); } void CTask5::OnClear() { if(m_ImgView!=NULL) { m_ImgView->EndDialog(IDOK); m_ImgView=NULL; } if(pImage!=NULL) { delete pImage; pImage=NULL; } }