?? 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 + -