[Gdal-dev] featureDataset->RasterIO efficient pixel value reading
question
Frank Warmerdam
fwarmerdam at gmail.com
Wed Jan 19 00:04:10 EST 2005
On Tue, 18 Jan 2005 22:24:30 CST, Andrew Finley <afinley at gis.umn.edu> wrote:
> Hi Frank,
> Some time ago, you helped me out with some code to speed up multi-band
> image pixel value access. I was using rasterIO to read one pixel at a
> time. You suggested the code below to grab a larger block (xsize*bands):
>
> // 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 );
Andy,
The last 3 arguments are the pixeloffset, line offset and
band offset. In the above case the buffer is "pixel interleaved",
that is if there were 2 bands we would have the values as
<band1_pixel1> <band2_pixel1> <band1_pixel2> <band2_pixel2>...
The pixel offset is 4*bandCount because when moving from one pixel
to the next for a bandcount bytes (4 is for the size of float). The line
offset is 0 because we are operating on one line at a time so we don't
need to set this with a meaningful value since we will never be
advancing a scanline within a call. The band offset is 4 because
the second band starts 4 bytes after the place where the first band
starts.
I'm really bad at explaining this, but i hope the above helps.
> // every pixel in row.
> for (int col = 0; col < featureDataset->GetRasterXSize(); col++){
> float *targetBandVec = lineBuf + col;
> ... perform classification ..
> }
> }
>
> I'm having some trouble understanding the parameters that go into
> featureDataset rasterIO and how it packs the data into the row lineBuf.
> What are the values of 4 you put in the RasterIO above? Could you take me
> one step further in the above example, so I can see how the pixel bands are
> layed out in the lineBuf. I took a shot below:
>
> // 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(sizeof(float)*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;
The above should read "lineBuf + col*bandCount" so that as you
advance one pixel you skip all the band values for the previous
pixel.
> //every band value in pixel (i.e., each cout row is a pixel and row
> elements are specific band values in that pixel)
> //I know this part is wrong.
>
> for(int band = 0; band < bandCount; band++)
> cout << targetBandVec[band] <<" ";
> cout << endl;
The above is fine as long as you compute the targetBandVec
properly.
Best regards,
--
---------------------------------------+--------------------------------------
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