大图像操作

来源:互联网 发布:java开源报表框架 编辑:程序博客网 时间:2024/06/09 09:47

>>使用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;
}

原创粉丝点击