⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imgprocessview.cpp

📁 可用的基于小波的spiht算法
💻 CPP
字号:
// ImgProcessView.cpp : implementation of the CImgProcessView class
//

#include "stdafx.h"
#include "ImgProcess.h"

#include  "GlobalApi.h"
#include "LEVEL.h"
#include "SPIHTCoder.h"

#include "ImgProcessDoc.h"
#include "ImgProcessView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CImgProcessView

IMPLEMENT_DYNCREATE(CImgProcessView, CScrollView)

BEGIN_MESSAGE_MAP(CImgProcessView, CScrollView)
	//{{AFX_MSG_MAP(CImgProcessView)
	ON_COMMAND(ID_TRANS_DWT, OnTransDwt)
	ON_COMMAND(ID_TRANS_IDWT, OnTransIdwt)
	ON_COMMAND(ID_SPIHT_CODE, OnSpihtCode)
	ON_COMMAND(ID_SPIHT_DECODE, OnSpihtDecode)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CImgProcessView construction/destruction

CImgProcessView::CImgProcessView()
{
	// TODO: add construction code here
	// 为小波变换设置的参数
	// 临时存放小波变换系数内存
	m_pDbImage = NULL;	
	
	// 设置当前层数
	m_nDWTCurDepth = 0;

	// 设置小波基紧支集长度
//	m_nSupp = 1;

}

CImgProcessView::~CImgProcessView()
{
	// 释放已分配内存
	if(m_pDbImage){
		delete[]m_pDbImage;
		m_pDbImage = NULL;
	}
}

BOOL CImgProcessView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CScrollView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CImgProcessView drawing

void CImgProcessView::OnDraw(CDC* pDC)
{
	CImgProcessDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	CSize sizeDibDisplay;		
		
	if(!pDoc->m_pDibInit->IsEmpty()){	
		sizeDibDisplay = pDoc->m_pDibInit->GetDimensions();
		pDoc->m_pDibInit->Draw(pDC,CPoint(0,0),sizeDibDisplay);	
	}
}

void CImgProcessView::OnInitialUpdate()
{
	CScrollView::OnInitialUpdate();

	CImgProcessDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);

	CSize sizeTotal = pDoc->m_pDibInit->GetDimensions();
	SetScrollSizes(MM_TEXT, sizeTotal);

	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();
}

/////////////////////////////////////////////////////////////////////////////
// CImgProcessView printing

BOOL CImgProcessView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CImgProcessView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CImgProcessView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CImgProcessView diagnostics

#ifdef _DEBUG
void CImgProcessView::AssertValid() const
{
	CScrollView::AssertValid();
}

void CImgProcessView::Dump(CDumpContext& dc) const
{
	CScrollView::Dump(dc);
}

CImgProcessDoc* CImgProcessView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CImgProcessDoc)));
	return (CImgProcessDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CImgProcessView message handlers

void CImgProcessView::OnTransDwt() 
{
	// TODO: Add your command handler code here
	// 获得文档类指针
	CImgProcessDoc * pDoc = (CImgProcessDoc *)this->GetDocument();

	// 指向图象的指针
	CDib * pDib = pDoc->m_pDibInit;

	// 更改光标形状
	BeginWaitCursor();

//*****************************************************
	int* pDbTemp;
	BYTE* pBits;

	CSize m_size;
	// 获取图象的存储尺寸
	CSize sizeImageSave = pDib->GetDibSaveDim();

	m_size.cx = pDib->m_lpBMIH->biWidth;
	m_size.cy = pDib->m_lpBMIH->biHeight;
	iwidth=m_size.cx ;
	iheight=m_size.cy;
	
	frame=new int[m_size.cx * m_size.cy];
	
	// 将图象数据放入frame中 
		for (int j=0; j<iheight; j++)
		{
			pDbTemp = frame + j*sizeImageSave.cx;
			pBits = pDib->m_lpImage + (iheight-1-j)*sizeImageSave.cx;		
			for (int i=0; i<iwidth; i++)
				pDbTemp[i] = pBits[i];
		}

//**********************************************
    //产生对话框
	CLEVEL Dialog;
    Dialog.m_level = 1;
	Dialog.m_supp = 1;
	if (Dialog.DoModal()!=IDOK)
    return;
	// 设置需要分解的层数
	m_nDWTLevel = Dialog.m_level;
	// 设置小波基紧支集长度
	m_nSupp = Dialog.m_supp;
	
	//删除对话框
	delete Dialog;
//*********************************************

	// 进行小波变换
	int rsl;
	for(int i=0;i<m_nDWTLevel;i++)
	 rsl = DIBDWTStep(pDib,0);

	// 恢复光标形状
	EndWaitCursor();

	// 如果小波变换不成功,则直接返回
	if (!rsl)			
		return;

	// 设置脏标志
	pDoc->SetModifiedFlag(TRUE);

	// 更新显示
	pDoc->UpdateAllViews(NULL);

}

void CImgProcessView::OnTransIdwt() 
{
	// TODO: Add your command handler code here
	// 获得文档类指针	
	CImgProcessDoc * pDoc = (CImgProcessDoc *)this->GetDocument();

	// 指向图象的指针
	CDib * pDib = pDoc->m_pDibInit;

	// 更改光标形状
	BeginWaitCursor();

//**************************************

	try{
		if(m_nDWTCurDepth<1) 
			throw new CException;}
		//错误处理
	catch(CException* pe)
	{
		AfxMessageBox("当前已不能反变换");
		pe->Delete();
		return;
	}

//************************************

	// 进行小波反变换
	int rsl;
	for(int i=m_nDWTLevel;i>0;i--)
	 rsl = DIBDWTStep(pDib,1);
	//int rsl = DIBDWTStep(pDib,1);
//*****************************
	// 获取图象的存储尺寸
	CSize sizeImageSave = pDib->GetDibSaveDim();
	int* image;
	int* pDbTemp;
	BYTE* pBits;
		image=new int[iheight * iwidth];
	
	// 将图象数据放入frame中 
		for (int j=0; j<iheight; j++)
		{
			pDbTemp = image + j*sizeImageSave.cx;
			pBits = pDib->m_lpImage + (iheight-1-j)*sizeImageSave.cx;		
			for (int i=0; i<iwidth; i++)
				pDbTemp[i] = pBits[i];
		}
//计算PSNR
	int m,n,MSE;
	float PSNR;
	CString str;
	   MSE=0;
	   for(m=0;m<iheight;m++)
	      for(n=0;n<iwidth;n++)
		      MSE=MSE+(image[m*iwidth+n]-frame[m*iwidth+n])*(image[m*iwidth+n]-frame[m*iwidth+n]);
		      MSE=MSE/(iwidth*iheight);
		      PSNR=10*log10(255*255/MSE);  
			  str.Format("PSNR为%f",PSNR);
	          //AfxMessageBox(str);

	delete []image;
	delete []frame;

	// 恢复光标形状
	EndWaitCursor();
	// 如果小波变换不成功,则直接返回
	if (!rsl)			
		return;
	pDoc->UpdateAllViews(FALSE);

	// 设置脏标记
	pDoc->SetModifiedFlag(TRUE);
	
	// 更新视图
	pDoc->UpdateAllViews(NULL);
	AfxMessageBox(str);
}

BOOL CImgProcessView::DIBDWTStep(CDib* pDib,int nInv)
{
	// 循环变量
	int i, j;

	// 获取图象的长度和宽度
	int nWidth  = pDib->m_lpBMIH->biWidth;
	int nHeight = pDib->m_lpBMIH->biHeight;
		
	// 获取变换的最大层数
	int nMaxWLevel = Log2(nWidth);
	int nMaxHLevel = Log2(nHeight);
	int nMaxLevel;
	if (nWidth == 1<<nMaxWLevel && nHeight == 1<<nMaxHLevel)
		nMaxLevel = min(nMaxWLevel, nMaxHLevel);

	// 获取图象的存储尺寸
	CSize sizeImageSave = pDib->GetDibSaveDim();

	// 临时变量
	double	*pDbTemp;
	BYTE	*pBits;

	// 如果小波变换的存储内存还没有分配,则分配此内存
	if(!m_pDbImage){			
		m_pDbImage = new double[nWidth*nHeight];
		if (!m_pDbImage)	return FALSE;

		// 将图象数据放入m_pDbImage中 
		for (j=0; j<nHeight; j++)
		{
			pDbTemp = m_pDbImage + j*sizeImageSave.cx;
			pBits = pDib->m_lpImage + (nHeight-1-j)*sizeImageSave.cx;		
			for (i=0; i<nWidth; i++)
				pDbTemp[i] = pBits[i];
		}
	}
	
	// 进行小波变换(或反变换)
	if (!DWTStep_2D(m_pDbImage, nMaxWLevel-m_nDWTCurDepth, nMaxHLevel-m_nDWTCurDepth,
						nMaxWLevel, nMaxHLevel, nInv, 1, m_nSupp))
		return FALSE;

	// 如果是反变换,则当前层数减1
	if (nInv)
		m_nDWTCurDepth --;
	// 否则加1
	else
		m_nDWTCurDepth ++;

	// 然后,将数据拷贝回原CDib中,并进行相应的数据转换
	int lfw = nWidth>>m_nDWTCurDepth, lfh = nHeight>>m_nDWTCurDepth;
	for (j=0; j<nHeight; j++)
	{
		pDbTemp = m_pDbImage + j*sizeImageSave.cx;
		pBits = pDib->m_lpImage + (nHeight-1-j)*sizeImageSave.cx;
		for (i=0; i<nWidth; i++)
		{
			if (j<lfh && i<lfw)
				pBits[i] = FloatToByte(pDbTemp[i]);
			else
				pBits[i] = BYTE(FloatToChar(pDbTemp[i]) ^ 0x80);			
		}
	}

	// 返回
	return TRUE;
}

void CImgProcessView::OnSpihtCode() 
{
	// TODO: Add your command handler code here
	// 获得文档类指针	
	CImgProcessDoc * pDoc = (CImgProcessDoc *)this->GetDocument();

	// 指向图象的指针
	CDib * pDib = pDoc->m_pDibInit;

	int nWidth  = pDib->m_lpBMIH->biWidth;
	int nHeight = pDib->m_lpBMIH->biHeight;

	int i,j,*data;
	float bytecounts2;
	data=new int[nHeight*nWidth];
   	CSPIHTCoder SPIHTCoder;

	for (j=0; j<nHeight; j++)
		for (i=0; i<nWidth; i++)
			data[j*nHeight+i] = (int)m_pDbImage[j*nHeight+i];
	
	
    //开始计时
//	start = clock();
	 
	/*5/3提升小波变换*/
 //  IntDwt53.Dwt2D(data1, iheight,iwidth,level);
//	SPTransform.Dwt2D(data1, nHeight,nWidth,level);

	//计时开始
	start = clock();	
	/*spiht编码*/
    SPIHTCoder.Losslessencode(data,nWidth,nHeight); 
	threshold2=SPIHTCoder.threshold;
    bytecounts2=SPIHTCoder.counts;

	//计时结束
	finish = clock();

	double  duration1;
	//计算编码时间
    duration1 = (double)(finish - start)/CLOCKS_PER_SEC;

	float CR1;
	/*计算压缩比*/
	CR1=float((nWidth*nHeight)/bytecounts2);
 		 
    //清除内存
 	delete []data;

	
	CString str1,str2;
	str1.Format("%f",duration1);
	str2.Format("%f",CR1);

    AfxMessageBox("编码时间:"+str1+"s"+"\n压缩比:"+str2);
    
}

void CImgProcessView::OnSpihtDecode() 
{
	// TODO: Add your command handler code here
	CImgProcessDoc * pDoc = (CImgProcessDoc *)this->GetDocument();

	// 指向图象的指针
	CDib * pDib = pDoc->m_pDibInit;

	int nWidth  = pDib->m_lpBMIH->biWidth;
	int nHeight = pDib->m_lpBMIH->biHeight;

	int i,j,*data;
	
	data=new int[nHeight*nWidth];
   	CSPIHTCoder SPIHTCoder;
//	CString str;
//	lpDst1=lpSrc;
	      
	//计时开始
	start = clock();
    /*spiht解码*/
    SPIHTCoder.Losslessdecoder(nWidth,nHeight,threshold2);  
	//计时结束
	finish = clock();

	double  duration1;
	//计算编码时间
    duration1 = (double)(finish - start)/CLOCKS_PER_SEC;
	   

	/*获取spiht解码后的数据*/
	for(i=0;i<nHeight;i++)
	  for(j=0;j<nWidth;j++)
	      data[i*nWidth+j]=SPIHTCoder.MR->m[i][j];

    /*5/3提升小波反变换*/
  //  IntDwt53.IDwt2D(data1, iheight,iwidth,level);
   //   SPTransform.IDwt2D(data, iheight,iwidth,level);
	  FILE *fp;
	 fp = fopen("lenai1dwt.txt","w");
	 for(i=0;i<nHeight;i++)
	   for(j=0;j<nWidth;j++)
		   fprintf(fp,"%d ",data[i*nWidth+j]);
	   fclose(fp);

	 //解码后数据赋值给m_pDbImage
	 for (i=0; i<nWidth; i++) 
	{
		for (j=0; j<nHeight; j++) 
		 {
			m_pDbImage[i*nWidth+j] = (double)data[i*nWidth+j];
		 }	
	}

    /*清除内存*/
 	delete []data;

	CString str1;
	str1.Format("%f",duration1);
	
    AfxMessageBox("解码时间:"+str1+"s");
	
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -