📄 imgprocessview.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 + -