?? hyperspectraldatacompressdlg.cpp
字號:
m_BitsPerPixel=lpHead->iBitPerPixel;
m_BytesPerPixel=((lpHead->iBitPerPixel>8)?2:1);
m_ImageHeight=lpHead->iImageHeight;
if(lpHead->iImageFormat==BSQ_H)m_AuxDataWidth=BSQ_AUXDATA_WIDTH;
else if(lpHead->iImageFormat==BIP_H)m_AuxDataWidth=BIP_AUXDATA_WIDTH;
else if(lpHead->iImageFormat==BIL_H)m_AuxDataWidth=BIL_AUXDATA_WIDTH;
AllDataWidth=lpHead->iImageWidth;
m_ImageWidth=AllDataWidth-m_AuxDataWidth;
m_LinesPerBlock=(lpHead->iImageHeight>=MAX_LINES_PER_BLOCK)?MAX_LINES_PER_BLOCK:lpHead->iImageHeight;
delete lpHead;
PureImageFormat=FALSE;
InitPredictBandString();
m_ComperssFileName=GetCompressFileName(m_InputFileName);
GetDlgItem(IDC_IMAGE_WIDTH)->EnableWindow(FALSE);
GetDlgItem(IDC_BITS_PER_PIXEL)->EnableWindow(FALSE);
GetDlgItem(IDC_BYTES_PER_PIXEL)->EnableWindow(FALSE);
GetDlgItem(IDC_IMAGE_HEIGHT)->EnableWindow(FALSE);
UpdateControlList(FALSE);
UpdateData(FALSE);
PureImageFormat=FALSE;
}
}
}
}
CString CHyperspectralDataCompressDlg::GetCompressFileName(CString &InputFileName)
{//根據輸入文件名和最大允許誤差產生壓縮數據文件名
int i;
CString s,str;
TCHAR asc[512];
str=InputFileName;
strcpy(asc,(LPCTSTR)str);
for(i=str.GetLength()-1;i>=0&&asc[i]!='.'&&asc[i]!='\\'&&asc[i]!=':';i--);
if(asc[i]=='.')asc[i]='\0';
str=asc;
if(PureImageFormat==TRUE)str+=_T("S");
else str+=_T("H");
if(OnOffBandPredict()==TRUE)s.Format(_T("On%03d.cmp"),m_AllowMaxErr);
else s.Format(_T("Off%03d.cmp"),m_AllowMaxErr);
str+=s;
return str;
}
BOOL CHyperspectralDataCompressDlg::OnOffBandPredict()
{
BOOL Return=FALSE;
TCHAR lpasc[4096];
int i,j,k,l;
l=PredictBandList.GetLength();
strcpy(lpasc,(LPCTSTR)PredictBandList);
for(i=0,j=0;i<m_BandNumber&&j<l;i++)
{
for(;lpasc[j]!='-'&&(lpasc[j]>'9'||lpasc[j]<'0')&&j<l;j++);
k=j;
for(;lpasc[j]=='-'||(lpasc[j]<='9'&&lpasc[j]>='0')&&j<l;j++);
lpasc[j]='\0';
if(atoi(lpasc+k)>=0){Return=TRUE;break;}
}
return Return;
}
void CHyperspectralDataCompressDlg::OnKillfocusAllowMasError()
{
UpdateData(TRUE);
int i,j,k;
j=m_AllowMaxErrorString.GetLength();
for(i=j-1;i>0;i--)
{
if(m_AllowMaxErrorString.GetAt(i)=='-')break;
}
if(i<=0)
{
m_AllowMaxErr=atoi((LPCTSTR)m_AllowMaxErrorString);
AllowMaxErrBgn=AllowMaxErrEnd=m_AllowMaxErr;
AllowMaxErrStep=1;
}
else
{
TCHAR asc[32];
strcpy(asc,(LPCTSTR)m_AllowMaxErrorString);
asc[i]='\0';
AllowMaxErrBgn=m_AllowMaxErr=atoi(asc);
for(k=++i;asc[i]!=','&&i<j;i++);
if(i>=j)
{
AllowMaxErrEnd=m_AllowMaxErr;
AllowMaxErrStep=1;
}
else
{
asc[i]='\0';
AllowMaxErrEnd=atoi(asc+k);
AllowMaxErrStep=atoi(asc+i+1);
}
}
if((m_AllowMaxErr+AllowMaxErrStep)<=AllowMaxErrEnd)
{
AllowReport=TRUE;//壓縮過程大于一次時允許報告壓縮結果
Report=_T("誤差界 壓縮比 壓縮碼率 峰值信噪比\r\n");
}
else
{
AllowReport=FALSE;
Report.Empty();
}
m_ComperssFileName=GetCompressFileName(m_InputFileName);
UpdateData(FALSE);
}
void CHyperspectralDataCompressDlg::OnCompressOk()
{
// 執行壓縮
UpdateData(TRUE);
UpdateControlList(TRUE);
if(AllowReport==TRUE&&AllowMaxErrBgn==m_AllowMaxErr)
{
m_ComperssFileName=GetCompressFileName(m_InputFileName);
}
CompressComplete=FALSE;
GetDlgItem(IDC_COMPRESS_OK)->EnableWindow(FALSE);
GetDlgItem(IDC_COMPRESS_FILE_NAME)->EnableWindow(FALSE);
GetDlgItem(IDC_MULBAND_IMAGE_FILENAME_FIND_BUTTON)->EnableWindow(FALSE);
GetDlgItem(IDC_OMIS_I_PREDICT_BAND)->EnableWindow(FALSE);
GetDlgItem(IDC_OMIS_II_PREDICT_BAND)->EnableWindow(FALSE);
GetDlgItem(IDC_TEST_PREDICT_BAND)->EnableWindow(FALSE);
GetDlgItem(IDC_AUX_DATA_WIDTH)->EnableWindow(FALSE);
GetDlgItem(IDC_LINES_PER_BLOCK)->EnableWindow(FALSE);
GetDlgItem(IDC_COMPRESS_RELATIVE_LIST)->EnableWindow(FALSE);
GetDlgItem(IDC_INPUT_FILE_NAME)->EnableWindow(FALSE);
GetDlgItem(IDC_ALLOW_MAS_ERROR)->EnableWindow(FALSE);
GetDlgItem(IDC_COMPRESS_FILE_NAME)->EnableWindow(FALSE);
if(PureImageFormat==TRUE)
{
GetDlgItem(IDC_BITS_PER_PIXEL)->EnableWindow(FALSE);
GetDlgItem(IDC_BYTES_PER_PIXEL)->EnableWindow(FALSE);
GetDlgItem(IDC_IMAGE_HEIGHT)->EnableWindow(FALSE);
GetDlgItem(IDC_IMAGE_WIDTH)->EnableWindow(FALSE);
}
GetDlgItem(IDC_COMPRESS_CANCEL)->SetWindowText(_T("終止"));
m_CompressRateString.Empty();
m_PSNRString.Empty();
m_RateString.Empty();
m_MaxErrString.Empty();
m_NoticeString=_T("正在執行壓縮 ...");
UpdateData(FALSE);
m_pCompressThread = (HyperspectralCompressThread*)//創建線程
AfxBeginThread(RUNTIME_CLASS(HyperspectralCompressThread), THREAD_PRIORITY_NORMAL,
0, CREATE_SUSPENDED);
m_pCompressThread->SetOwner(this);//設置線程對應的窗口
CompressThreadRun=TRUE;//設置線程運行標志,此標置被置成FALSE時,線程結束
m_pCompressThread->ResumeThread();//啟動線程
}
void CHyperspectralDataCompressDlg::OkCompressProce()
{//以線程方式執行
//針對以單波段純圖像文件存放的高譜數據
int i;
LPCTSTR *lpImageFileName=new LPCTSTR[m_BandNumber];
double PSNR;
CHyperspectralImageCode HEncode;
// 1、加載高光譜數據。
// a、支持三種形式的高光譜數據文件格式(BSQ_H、BIP_H、BIL_H)及各波段獨立文件格式。
// b、從格式文件的頭部獲取數據各類參數,獨立文件形式必須輸入壓縮所需格式信息。
// c、配置預測波段。(配置信息來自預先的設定)
if(PureImageFormat==TRUE)
{//如果是純圖像格式
//建立單波段文件名指針表
for(i=0;i<m_BandNumber;i++)lpImageFileName[i]=(LPCTSTR)lpImageFile[i];
//加載純圖像格式的高光譜數據
if(HEncode.LoadHyperspectralImageFile(lpImageFileName,
m_BandNumber,
m_ImageHeight,
m_ImageWidth,
m_BytesPerPixel,
m_BitsPerPixel)==FALSE)
{
//如果加載失敗,發送結束進程消息。
HEncode.EndHyperspectralCode();
PostMessage(WM_USER_HYPERSPECTRAL_COMPRESS_DLG,1,0);
delete lpImageFileName;
return;
}
}
else
{//格式為(BSQ_H、BIP_H、BIL_H)的高光譜數據
if(HEncode.LoadHyperspectralImageFile(m_InputFileName,m_AuxDataWidth)==FALSE)
{
HEncode.EndHyperspectralCode();
PostMessage(WM_USER_HYPERSPECTRAL_COMPRESS_DLG,1,0);
delete lpImageFileName;
return;
}
}
//加載預測波段列表
HEncode.LoadPredictTable((LPCTSTR)PredictBandList);
// 2、為各波段創建編碼器。
HEncode.CreatCompressObject();
// 4、執行壓縮循環
int Line,j,LineBG,LineN,AuxData_cp,CodeBit_cp;
LPBYTE lpAuxData=new BYTE[9+HEncode.OneLineAuxDataWidth*HEncode.OnePixelBytes*HEncode.BandNumber*m_LinesPerBlock];
LPBYTE lpImageData=new BYTE[HEncode.Width*HEncode.OnePixelBytes+4];
LPBYTE lpAuxD;
int AuxL;
double ErrM;
int bg,allLine,a;
for(;m_AllowMaxErr<=AllowMaxErrEnd;m_AllowMaxErr+=AllowMaxErrStep)
{
if(AllowMaxErrBgn!=m_AllowMaxErr)
{
m_ComperssFileName=GetCompressFileName(m_InputFileName);
PostMessage(WM_USER_HYPERSPECTRAL_COMPRESS_DLG,5,0);
}
HEncode.AllowMaxError=m_AllowMaxErr;
// 3、為壓縮碼流準備緩沖區及存放文件。(緩沖區大小取決于壓縮圖像塊的大小)
HEncode.PrepareCodeStreamBuf(m_LinesPerBlock,(LPCTSTR)m_ComperssFileName,m_AllowMaxErr);
//創建并保存高光譜數據壓縮頭信息
i=HEncode.CreatHyperspectralCompressHead(HEncode.lpCodeStreamBuf,lpAuxD,AuxL);
HEncode.WriteDataToFile(HEncode.lpCodeStreamBuf,i-AuxL);
HEncode.ClearCodeStreamBuf();
if(AuxL>0)HEncode.AppendDataToFile(lpAuxD,AuxL);
//執行壓縮循環
BitPerPixel=0;
ErrMse=0;//存放壓縮重建圖像誤差平方和。
allLine=HEncode.Height;
bg=0;
for(Line=0;Line<HEncode.Height;)
{//這是塊循環層
LineBG=Line;
LineN=((HEncode.Height-LineBG)>=HEncode.LinesPerCompressBlock)?HEncode.LinesPerCompressBlock:(HEncode.Height-LineBG);
AuxData_cp=9;//除輔助數據外的壓縮塊頭字節數。
HEncode.CreatBlockCompressHead(lpAuxData,HEncode.AllowMaxError,LineBG,LineN);
for(i=0;i<HEncode.BandNumber;i++)
{//各波段編碼器復位
HEncode.lpCompressUnit[i]->InitialisationsCode(HEncode.OnePixelBits,HEncode.AllowMaxError);
}
CodeBit_cp=0;
for(j=0;j<LineN;j++)
{
a=(j+LineBG)*100/allLine;
if(a>bg)
{//向主窗口報告當前執行的行數
PostMessage(WM_USER_HYPERSPECTRAL_COMPRESS_DLG,0,a);
if(CompressThreadRun==FALSE)break;//檢查是否有中止標志
}
for(i=0;i<HEncode.BandNumber;i++)
{
//取當前行圖像數據
HEncode.GetOneLineImageData(lpImageData,i,j+LineBG);
//取當前行輔助數據
AuxData_cp+=HEncode.GetOneLineAuxData(lpAuxData+AuxData_cp,i,j+LineBG);
//壓縮當前行圖像,碼流以比特為單位存放
CodeBit_cp+=HEncode.lpCompressUnit[i]->DoEncodeLine(lpImageData,
HEncode.OnePixelBytes,
HEncode.lpCodeStreamBuf,
CodeBit_cp,
&ErrM);
ErrMse+=ErrM;//累加誤差平方和
}
}
if(j<LineN)break;//中止時跳出
Line+=LineN;
//累計總的碼流比特數
BitPerPixel+=CodeBit_cp;
//計算當前壓縮塊總字節數
*((int *)lpAuxData)=AuxData_cp+(CodeBit_cp>>3)+((CodeBit_cp&7)?1:0);
//保存當前壓縮塊信息頭
HEncode.AppendDataToFile(lpAuxData,AuxData_cp);
//保存當前壓縮塊碼流
HEncode.AppendDataToFile(HEncode.lpCodeStreamBuf,(CodeBit_cp>>3)+((CodeBit_cp&7)?1:0));
HEncode.ClearCodeStreamBuf();
}
if(Line<HEncode.Height)break;
//計算壓縮誤差的均方值
ErrMse/=(HEncode.Height*HEncode.Width*HEncode.BandNumber);
//計算單象素比特值
BitPerPixel/=(HEncode.Height*HEncode.Width*HEncode.BandNumber);
if(AllowReport==TRUE)
{
if(ErrMse<=0)m_PSNRString.Format(_T("------ "));
else
{
PSNR=10*log10((1<<(m_BitsPerPixel*2))/ErrMse);
m_PSNRString.Format(_T("%-8.5f "),PSNR);
}
m_CompressRateString.Format(_T("%-6.3f "),m_BitsPerPixel/BitPerPixel);
m_RateString.Format(_T("%-8.6f "),BitPerPixel);
m_MaxErrString.Format(_T(" %-3d "),m_AllowMaxErr);
Report+=m_MaxErrString;
Report+=m_CompressRateString;
Report+=m_RateString;
Report+=m_PSNRString;
Report+=_T("\r\n");
PostMessage(WM_USER_HYPERSPECTRAL_COMPRESS_DLG,5,0);
}
else
{
if(ErrMse<=0)m_PSNRString.Format(_T("------"));
else
{
PSNR=10*log10((1<<(m_BitsPerPixel*2))/ErrMse);
m_PSNRString.Format(_T("%-6.3fdb"),PSNR);
}
m_CompressRateString.Format(_T("%-6.3f"),m_BitsPerPixel/BitPerPixel);
m_RateString.Format(_T("%-5.3fb/pix"),BitPerPixel);
m_MaxErrString.Format(_T("%-d"),m_AllowMaxErr);
}
if((m_AllowMaxErr+AllowMaxErrStep)>AllowMaxErrEnd)break;
}
if(m_AllowMaxErr>=AllowMaxErrEnd)CompressComplete=TRUE;
delete lpImageData;
delete lpAuxData;
// 5、釋放碼流及各波段編碼器緩沖區。
HEncode.EndHyperspectralCode();
PostMessage(WM_USER_HYPERSPECTRAL_COMPRESS_DLG,1,0);
}
char szFilter_CompressFile[] = "高光譜圖象(*.BSQ;*.BIP;*.BIL;*.RAW)\0*.bsq;*.bip;*.bil;*.raw;\0全部文件 (*.*) \0*.*\0\0";
void CHyperspectralDataCompressDlg::OnMulbandImageFilenameFindButton()
{
// 查找高光譜文件
LPCTSTR Exfilename;
UpdateData(TRUE);
LPSTR lpBuf=new TCHAR[16388];
stAuxMsg *lpHead;
CFile f;
strcpy(lpBuf,(LPCTSTR)m_InputFileName);
if((FileNumber=::FindFileNameOpreation(TRUE,lpBuf,szFilter_CompressFile,MAXBANDNUMBER,lpImageFile,16384))>=1)
{//多文件存放在串列表中
m_InputFileName=lpBuf;
Exfilename=((LPCTSTR)lpImageFile[0])+lpImageFile[0].GetLength()-3;
if(strcmp(Exfilename,_T("raw"))==0||strcmp(Exfilename,_T("RAW"))==0)
{//純圖像格式
m_BandNumber=FileNumber;
ArrangeFileName(lpImageFile,FileNumber);
InitPredictBandString();
GetDlgItem(IDC_IMAGE_WIDTH)->EnableWindow(TRUE);
GetDlgItem(IDC_BITS_PER_PIXEL)->EnableWindow(TRUE);
GetDlgItem(IDC_BYTES_PER_PIXEL)->EnableWindow(TRUE);
GetDlgItem(IDC_IMAGE_HEIGHT)->EnableWindow(TRUE);
PureImageFormat=TRUE;
m_AuxDataWidth=BFILE_AUXDATA_WIDTH;
m_LinesPerBlock=MAX_LINES_PER_BLOCK;
}
else
{
if(f.Open((LPCTSTR)lpImageFile[0],CFile::modeRead)==TRUE)
{//打開多波段文件
f.Read(lpBuf,sizeof(stAuxMsg));
f.Close();
lpHead=(stAuxMsg *)lpBuf;
m_BandNumber=lpHead->iImageBand;
m_BitsPerPixel=lpHead->iBitPerPixel;
m_BytesPerPixel=((lpHead->iBitPerPixel>8)?2:1);
m_ImageHeight=lpHead->iImageHeight;
if(lpHead->iImageFormat==BSQ_H)m_AuxDataWidth=BSQ_AUXDATA_WIDTH;
else if(lpHead->iImageFormat==BIP_H)m_AuxDataWidth=BIP_AUXDATA_WIDTH;
else if(lpHead->iImageFormat==BIL_H)m_AuxDataWidth=BIL_AUXDATA_WIDTH;
AllDataWidth=lpHead->iImageWidth;
m_ImageWidth=AllDataWidth-m_AuxDataWidth;
m_LinesPerBlock=(lpHead->iImageHeight>=MAX_LINES_PER_BLOCK)?MAX_LINES_PER_BLOCK:lpHead->iImageHeight;
PureImageFormat=FALSE;
InitPredictBandString();
GetDlgItem(IDC_IMAGE_WIDTH)->EnableWindow(FALSE);
GetDlgItem(IDC_BITS_PER_PIXEL)->EnableWindow(FALSE);
GetDlgItem(IDC_BYTES_PER_PIXEL)->EnableWindow(FALSE);
GetDlgItem(IDC_IMAGE_HEIGHT)->EnableWindow(FALSE);
PureImageFormat=FALSE;
}
}
m_CompressRateString.Empty();
m_PSNRString.Empty();
m_RateString.Empty();
m_MaxErrString.Empty();
m_ComperssFileName=GetCompressFileName(m_InputFileName);
UpdateControlList(FALSE);
UpdateData(FALSE);
GotoDlgCtrl(GetDlgItem(IDC_INPUT_FILE_NAME));
}
delete lpBuf;
}
char szPredictBandList_OMIS1[] = "-1 -1 1 2 3 3 4 5 7 8 9 10 11 12 13 14 15 16 17 15 15 20 21 22 23 24 25 26 27 27 29 29 26 32 33 29 28 35 37 31 32 33 34 35 43 44 45 39 40 41 48 47 51 51 52 47 48 49 50 43 44 45 46 61 -1 -1 -1 -1 -1 68 69 70 71 72 73 71 73 75 73 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 97 98 99 99 99 102 102 104 105 106 107 108 109 110 50 112 113 114 115 116 117 118 -1 120 120 119 123 124 125 126\0\0";
void CHyperspectralDataCompressDlg::OnOmisIPredictBand()
{
// 采用OMIS1默認的預測波段配置
UpdateData(TRUE);
PredictBandList=(LPCTSTR)szPredictBandList_OMIS1;
UpdateControlList(FALSE);
m_ComperssFileName=GetCompressFileName(m_InputFileName);
UpdateData(FALSE);
}
char szPredictBandList_OMIS2[] = "-1 0 0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 16 18 12 -1 21 22 23 24 25 26 27 28 29 30 30 32 32 33 33 36 35 32 39 40 41 42 43 44 41 46 38 48 49 50 50 52 52 51 41 56 57 58 -1 60 61 -1\0\0";
void CHyperspectralDataCompressDlg::OnOmisIiPredictBand()
{
// 采用OMIS2默認的預測波段配置
UpdateData(TRUE);
PredictBandList=(LPCTSTR)szPredictBandList_OMIS2;
UpdateControlList(FALSE);
m_ComperssFileName=GetCompressFileName(m_InputFileName);
UpdateData(FALSE);
}
void CHyperspectralDataCompressDlg::OnKillfocusCompressRelativeList(NMHDR* pNMHDR, LRESULT* pResult)
{
// TODO: Add your control notification handler code here
m_ComperssFileName=GetCompressFileName(m_InputFileName);
UpdateData(FALSE);
*pResult = 0;
}
void CHyperspectralDataCompressDlg::OnTestPredictBand()
{
// 從高光譜數據中,通過相關系數自動測試預測波段
UpdateData(TRUE);
GetDlgItem(IDC_COMPRESS_CANCEL)->SetWindowText(_T("終止"));
m_NoticeString=_T("計算相關系數 ...");
UpdateData(FALSE);
m_pTestRelativeThread = (HyperspectralTestRelativeThread*)//創建線程
AfxBeginThread(RUNTIME_CLASS(HyperspectralTestRelativeThread), THREAD_PRIORITY_NORMAL,
0, CREATE_SUSPENDED);
m_pTestRelativeThread->SetOwner(this);//設置線程對應的窗口
TestRelativeThreadRun=TRUE;//設置線程運行標志,此標置被置成FALSE時,線程結束
m_pTestRelativeThread->ResumeThread();//啟動線程
}
void CHyperspectralDataCompressDlg::OkTestRelativeProce()
{//以線程方式執行
int i,j,k;
LPCTSTR *lpImageFileName=new LPCTSTR[m_BandNumber];
TestRelativeComplate=FALSE;
CHyperspectralImageCode HEncode;
if(PureImageFormat==TRUE)
{//如果是純圖像格式
//建立單波段文件名指針表
for(i=0;i<m_BandNumber;i++)lpImageFileName[i]=(LPCTSTR)lpImageFile[i];
//加載純圖像格式的高光譜數據
if(HEncode.LoadHyperspectralImageFile(lpImageFileName,
m_BandNumber,
m_ImageHeight,
m_ImageWidth,
m_BytesPerPixel,
m_BitsPerPixel)==FALSE)
{
//如果加載失敗,發送結束進程消息。
PostMessage(WM_USER_HYPERSPECTRAL_COMPRESS_DLG,3,0);
delete lpImageFileName;
return;
}
}
else
{//格式為(BSQ_H、BIP_H、BIL_H)的高光譜數據
if(HEncode.LoadHyperspectralImageFile((LPCTSTR)m_InputFileName,
m_AuxDataWidth)==FALSE)
{
PostMessage(WM_USER_HYPERSPECTRAL_COMPRESS_DLG,3,0);
delete lpImageFileName;
return;
}
}
delete lpImageFileName;
LPBYTE *lpImageData1=new LPBYTE[HEncode.Height];
for(i=0;i<HEncode.Height;i++)
{
lpImageData1[i]=new BYTE[HEncode.Width*HEncode.OnePixelBytes+4];
}
LPBYTE lpImageData2=new BYTE[HEncode.Width*HEncode.OnePixelBytes+4];
int bg,allLine,a;
double Mse,*AllM,M,**R,Relative;
AllM=new double[HEncode.BandNumber];
R=new double *[HEncode.BandNumber];
for(i=0;i<HEncode.BandNumber;i++)
{
AllM[i]=0;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -