[Gdal-dev] how to get pixels' band vector efficiently

Frank Warmerdam warmerdam at pobox.com
Wed Sep 15 09:23:32 EDT 2004

Andrew Finley wrote:
> Hi All,
> I have written an image classification algorithm which uses gdal to fill
> a vector of band values for each pixel.  I'm looking for a better/faster
> way of accessing these values. Two general ways I might think to speed
> this up are: 
> 1) move one tile at a time into memory then apply the loop below.
> 2) find a way to load my target vector more efficiently than one
> pixel/layer at a time.
> So I guess I'm looking for some ideas or example code.  Could the
> tileindex application offer any help? Does it load logical image blocks
> (i.e., from a single page)?

> Current approach:
> //every pixel loop
> for (int row = 0; row < featureDataset->GetRasterYSize(); row++){
> 	for (int col = 0; col < featureDataset->GetRasterXSize(); col++){
> 	//fill targetBandVec
> 	for (layer = 1; layer <= featureDataset->GetRasterCount(); layer++){
> 		featureBand = featureDataset->GetRasterBand( layer );
> 		featureBand->RasterIO(GF_Read, col, row, 1, 1, featurePixel, 1, 1,
> GDT_Float32, 0, 0 );
> 		targetBandVec[layer-1]=featurePixel[0];
> 	}


Reading one pixel at a time is going to be terrible for performance.  I would
encourage you to at least change you code to read one line at a time.  This
will give you a huge performance boost.  Going to a tile oriented (or better
yet to the native block size of the source) will help a bit more in some cases,
but not likely very much.

I am also using the multi-band RasterIO() directly on the dataset, one
line at a time in the following example:

  // Make sure that lineBuf holds one whole line of data.
  float *lineBuf;
  int  xsize = featureDataset->GetRasterXSize();
  int  ysize = featureDataset->GetRasterYSize();
  int  bandCount = featureDataset->GetRasterCount();

  lineBuf = (float *) CPLMalloc(xsize * bandCount);

  //every row loop
  for (int row = 0; row < featureDataset->GetRasterYSize(); row++){
      featureDataset->RasterIO( GF_Read, 0, row, xsize, 1,
                                lineBuf, xsize, 1, GDT_Float32,
                                bandCount, NULL,
                                4 * bandCount, 0, 4 );
      // every pixel in row.
      for (int col = 0; col < featureDataset->GetRasterXSize(); col++){
          float *targetBandVec = lineBuf + col;

          ... perform classification ..

Good luck,

I set the clouds in motion - turn up   | Frank Warmerdam, warmerdam at pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Programmer for Rent

More information about the Gdal-dev mailing list