>>使用RasterIO()对大图像进行分块操作<<
RasterIO()函数能够对图像任意指定区域任意波段的数据按指定数据类型,指定排列方式读入内存和写入文件中,因此可以实现对大影像的分块读,运算,写操作。对于大图像处理,按照传统方法,首先要将图像所有数据读入内存中,进行相应操作后,再一次性将处理好的数据写入文件中,这样需要耗费很大内存,容易内存溢出,而且存续可执行行差。采用分块处理技术,一幅1G的影像,在整个数据处理过程中,可以只占用几十兆的内存,而且运算量不会增加。下面通过一个示例加以演示:
>>所有波段分块处理示例<<
void CTestzwDoc::OnLowers()
{
Inoutput dlg; //获取文件路径的对话框类
if (dlg.DoModal()==IDCANCEL)
{
return;
}
CString strFilePath1(dlg.m_input);
CString strFilePath2(dlg.m_output);
GDALDataset *poDataset1; //GDAL数据集
GDALDataset *poDataset2; //GDAL数据集
GDALDriver *poDriver;
GDALAllRegister();
poDataset1 = (GDALDataset *) GDALOpen(strFilePath1, GA_ReadOnly );
if( poDataset1 == NULL )
{
AfxMessageBox("文件打开失败!!!");
m_FileFlag=FALSE;
return;
}
int BandCount=poDataset1->GetRasterCount();
int nImgSizeX=poDataset1->GetRasterXSize();
int nImgSizeY=poDataset1->GetRasterYSize();
//创建新文件
CString format;
format="Gtiff";
poDriver = GetGDALDriverManager()->GetDriverByName(format);
char ** papszMetadata = poDriver->GetMetadata();
poDataset2=poDriver->Create(strFilePath2,nImgSizeX,nImgSizeY,nBandCount,GDT_Byte,papszMetadata);
poDataset2->SetGeoTransform(adfGeoTransform );//设置图像坐标,缺少这一步,创建的图像用erdas打开将无法正常现实
//
//分块处理.将影像分成很多512*512大小的块,通过循环对每一块进行处理
int nxNum=(nImgSizeX-1)/512+1;//计算列方向上块数
int nyNum=(nImgSizeY-1)/512+1;//计算行方向块数
intpafsizex; //当前块宽度
intpafsizey; //当前块高度
BYTE * lp;
BYTE *ppafScan= new BYTE [512*512*nBandCount];
for (int nYI=0;nYI<nyNum;nYI++)
for (int nXI=0;nXI<nxNum;nXI++)
{
pafsizex=512;
pafsizey=512;
//行列末尾小块处理
if(nXI==nxNum-1)pafsizex=(nImgSizeX-1)%512+1;
if (nYI==nyNum-1)pafsizey=(nImgSizeY-1)%512+1;
//读取当前块数据
poDataset1->RasterIO(GF_Read, nXI*512, nYI*512,pafsizex,
pafsizey,ppafScan,pafsizex,pafsizey,GDT_Byte,BandCount,0,0,0,0);
//对当前块进行处理,边缘提取
for(intnnum=0;nnum<nBandCount;nnum++)
for (inti=0;i<pafsizey;i++)
for(intj=0;j<pafsizex;j++)
{
{
lp=ppafScan+nnum*pafsizex*pafsizey+i*pafsizex+j;
if(j==pafsizex-1&&i!=pafsizey-1)
*lp=abs(*lp-*(lp+pafsizex));
else if(i==pafsizey-1&&j==pafsizex-1)
*lp=0;
else if(i==pafsizey-1&&j!=pafsizex-1)
*lp=abs(*lp-*(lp+1));
else *lp=abs((*lp)-*(lp+1))+abs(*lp-*(lp+pafsizex));
//边缘处理是难点
if(*lp<15)
*lpp=0;
elseif(15<=*lpp<30)
*lpp=128;
elseif(*lpp>=30)
*lpp=255;
}
}
//将当前块数据写入新图像相应位置
poDataset2->RasterIO(GF_Write,nXI*512,nYI*512,pafsizex,pafsizey,ppafScan,pafsizex,pafsizey,GDT_Byte,nBandCount,0,0, 0,0 );
}
delete []ppafScan;
//写操作完成后必须释放,不然写入操作不成功
delete poDataset2;
delete poDataset1;
delete poDriver;
delete dlg;
}
大图像操作
最新推荐文章于 2024-04-26 09:38:23 发布