1

我已经geotiff使用RasterIO. GDAL library由于显示的图像OpenGL需要具有宽度和高度均为 4 的倍数,因此我在提取数据后使用了此代码。
第一个switch块计算RasterXSize(width)除以 4 的其余部分,例如,如果它是 1,则意味着我们应该添加 3 列,这意味着我们应该在每行的末尾添加 3 个零。这是由代码完成的:

for ( int i = 1; i <= RasterYSize; i++)
    pRasterData.insert(pRasterData.begin()+i*RasterXSize*depthOfPixel+(i-1)*3,3,0);  

第二个switch块计算RasterYSize(height)除以 4 的其余部分,例如,如果它是 1,这意味着我们应该轻松地将 3 行添加到数据的末尾,这是由以下代码完成的:

pRasterData.insert(pRasterData.end(),3*RasterXSize,0);  

这是我用来提取数据并准备由 OpenGL 显示的全部代码:

void FilesWorkFlow::ReadRasterData(GDALDataset* poDataset)
{
    RasterXSize = poDataset -> GetRasterXSize();
    RasterYSize = poDataset -> GetRasterYSize();
    RasterCount = poDataset -> GetRasterCount();
    CPLErr error = CE_None;
    GDALRasterBand *poRasterBand; 
    poRasterBand = poDataset -> GetRasterBand(1);
    eType = poRasterBand -> GetRasterDataType();
    BytesPerPixel = GDALGetDataTypeSize(eType) / 8;
    depthOfPixel = RasterCount * BytesPerPixel;
    pRasterData.resize(RasterXSize * RasterYSize * RasterCount * BytesPerPixel);
    error = poDataset -> RasterIO(GF_Read,0,0,RasterXSize,RasterYSize,&pRasterData[0],RasterXSize,RasterYSize,eType,RasterCount,0,0,0,0);
    int modRasterXSize = RasterXSize % 4;
    switch (modRasterXSize)
    {
    case 1:
        {
         for ( int i = 1; i <= RasterYSize; i++)
            pRasterData.insert(pRasterData.begin()+i*RasterXSize*depthOfPixel+(i-1)*3,3,0);
        RasterXSize = RasterXSize+3;
        break;
        }
    case 2:
        {
        for ( int i = 1; i <= RasterYSize; i++)
            pRasterData.insert(pRasterData.begin()+i*RasterXSize*depthOfPixel+(i-1)*2,2,0);
        RasterXSize = RasterXSize+2;
        break;
        }
    case 3:
        {
        for ( int i = 1; i <= RasterYSize; i++)
            pRasterData.insert(pRasterData.begin()+i*RasterXSize*depthOfPixel+(i-1)*1,1,0);
        RasterXSize = RasterXSize+1;
        break;
        }
    }
    int modRasterYSize = RasterYSize % 4;
    switch (modRasterYSize)
    {
    case 1:
        {
        pRasterData.insert(pRasterData.end(),3*RasterXSize,0);
        RasterYSize = RasterYSize+3;
        break;
        }
    case 2:
        {
        pRasterData.insert(pRasterData.end(),2*RasterXSize,0);
        RasterYSize = RasterYSize+2;
        break;
        }
    case 3:
        {
        pRasterData.insert(pRasterData.end(),1*RasterXSize,0);
        RasterYSize = RasterYSize+1;
        break;
        }
    }
}  

第一个switch块是我的代码变慢的地方,因为我正在使用 16997*15931 图像,所以程序运行 for 循环需要很长时间。
请注意,这pRasterData是一个member variableFilesWorkFlow,并且由于我在将此变量发送到由 Brett Fowle 在 codeguru 中编写的 COpenGLControl 类中遇到的问题,并在项目中使用了一些细微的变化,因此决定使用vector<unsigned char>而不是unsighned char*.
现在我想知道有没有办法更快地实现这部分代码vectors
无论如何在向量的某些部分插入零而不使用for循环并浪费太多时间?
std::transform什么?我不知道!
请记住,我正在使用MFCinVisual Studio 2010并且它对我来说更好,STL但是如果您除了使用vectorsor之外还有其他建议STL,我会很高兴听到这个?

4

1 回答 1

1

它很慢的原因是因为向量的成员被多次移动。想想你图片最后一行的成员。对于图像的每一行,它们都必须移动一次。创建一个全新的图像会更快,只需从原始图像中复制您需要的像素并在适当的地方添加零。

这是一个例子:

void
  padColumns(
    std::vector<unsigned char> &old_image,
    size_t old_width,
    size_t new_width
  )
{
  size_t height = image.size() / old_width;
  assert(image.size() == old_width*height);

  std::vector<unsigned char> new_image(new_width * height);

  for (size_t row=0; row!=height; ++row) {
    std::copy(
      old_image.begin() + row*old_width,
      old_image.begin() + row*old_width + old_width,
      new_image.begin() + row*new_width
    );
    std::fill(
      new_image.begin() + row*new_width + old_width,
      new_image.begin() + row*new_width + new_width,
      0
    );
  }

  old_image = new_image;
}
于 2013-08-05T13:36:24.747 回答