2

I am trying to open a spectral file and move bands of data from GDAL to OpenCV's Mat data structures. As of now I am just trying to make sure that I can correctly access each band using GDAL and pull the pixel data.

So I want to explain what I think the following code is doing and if I am wrong(must be) then please correct me. It opens the file and loads the dataset. Then I get raster band 1 assigned to currentBand. The float pointer is then made to point at enough memory for one line of pixel data. RasterIO gets this data and places it in the newly allocated space. I then traverse the array printing the value that has been placed in each element. (Code in c++)

GDALDataset  *dataset;
GDALRasterBand *currentBand;
int blockXSize, blockYSize;
GDALAllRegister();
dataset = (GDALDataset *) GDALOpen( specImag->filename.c_str(), GA_ReadOnly );

currentBand = dataset->GetRasterBand(1);
currentBand->GetBlockSize(&blockXSize, &blockYSize);

float *fScanline;
fScanline = (float *) CPLMalloc(sizeof(float)*specImag->widthx);

currentBand->RasterIO( GF_Read, 0, 0, specImag->widthx, 1,
                          fScanline, specImag->widthx, 1, GDT_Float32, 0, 0 );


for(int i=0; i<specImag->widthx; i++){
        std::cout << "Data Point ";
        printf("%d", i);
        std::cout << " is: ";
        printf("%d", fScanline[i]);
        std::cout << std::endl;
    }

(the code is not complete and will not run as is)

When I run the code I get the same number (ex. 421076 or 4210432) for every element in the array. If I wait a little bit and run the program again I get a different number than the prevous run but still the same in each element.

What am i missing when it comes to accessing the pixel/data in each band?

  • Is your data float? i.e. 32 bit IEEE floating point? I notice you're getting the the blocksize into blockXSize and blockYSize but reading specImag->widthx.. is it possible that it's 0 and what you are reading is random crap from initialized memory converted to words depending on the word boundary? From my own code:RasterIO (GDALRWFlag::GF_Read,ColOff,RowOff,BlockCols,BlockRows,CountData,BlockCols,BlockRows, GDALDataType::GDT_UInt32,1,NULL,0,0,0); – Michael Stimson Jul 31 '14 at 22:25
  • Now that I think of it I never had much success reading from a band, that is why I used GDALDataset::RasterIO not GDALRasterBand::RasterIO. It seems the band IO works for some drivers but not others... what raster format are you using? – Michael Stimson Jul 31 '14 at 22:48
  • 1
    Why is fscanline float but you use %d to print? should either cast fscanline[i] to int or to double and use %g. Or use cout. Try that. Typically, the behavior you're seeing is caused by accessing uninitialized memory, so the values change every time. Zero out fscanline after allocation, before read. how about checking the CPLErr value that RasterIO returns? These are the obvious things to try. – Reilly Aug 1 '14 at 11:02
  • Good point @Reilly, the RasterIO function returns a value indicating the error (if present)... CPLErr GDALRasterBand::RasterIO there's a good place to start. I've always used a block of bytes for data; the docs say that it should be words of type eBufType as the OP has done, don't think that would make a difference. – Michael Stimson Aug 3 '14 at 21:40
  • I ask about the %d because C++ will take the 32-bits on the stack and interpret them as an int, when they are a float. If you use %g and cast to double, perhaps the value will be "more reasonable" and you might learn something. Or not. – Reilly Aug 4 '14 at 10:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.