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