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);  

2 番目の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 ループを実行するのに多くの時間がかかります。
この変数を COpenGLControl クラスに送信する際に問題が発生したため、pRasterDataBrett Fowle によって codeguru で記述さmember variableれ、プロジェクトで使用され、若干の変更が加えられたため、の代わりに使用することにしました。 今、コードのこれらの部分をより速く実装する方法はあるのでしょうか? for ループを使用して時間を無駄にすることなく、ベクトルの特定の部分にゼロを挿入する方法はありますか? みたいな?知らない!FilesWorkFlowvector<unsigned char>unsighned char*
vectors

std::transform
MFC私はin を使用していることを覚えておいてください。使用Visual Studio 2010する方が良いのですが、 orのSTL使用以外に別の提案があれば、それを聞いてうれしいですか?vectorsSTL

4

1 に答える 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 に答える