Как создать QImage из данных GeoTIFF (или просто правильно его интерпретировать) - PullRequest
0 голосов
/ 18 декабря 2018

Мне нужно создать QImage или что-то, что можно нарисовать на экране из геофизического изображения.К сожалению, встроенная в QT TIFF поддержка дросселей в структурах geotiff ... так что для достижения этого я использовал следующий код (который является более или менее копией вставки со страницы "tutorial" gdal (https://gdal.org/gdal_tutorial.html) за исключениемчасть создания изображения):

GDALRasterBand  *poBand;
int             nBlockXSize, nBlockYSize;
int             bGotMin, bGotMax;
double          adfMinMax[2];
poBand = poDataset->GetRasterBand( 1 );
poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
adfMinMax[0] = poBand->GetMinimum( &bGotMin );
adfMinMax[1] = poBand->GetMaximum( &bGotMax );
if( ! (bGotMin && bGotMax) )
    GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);


float *pafScanline;
int   nXSize = poBand->GetXSize();
int   nYSize = poBand->GetYSize();
pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize * nYSize);
poBand->RasterIO( GF_Read, 0, 0, nXSize, nYSize, 
                  pafScanline, nXSize, nYSize, GDT_Float32, 0, 0 );

QImage* image = new QImage((unsigned char*)pafScanline, 
                          nXSize, nYSize,
                          QImage::Format_RGB32);

image->save("blaa.jpg");

Теперь изображение, которое я пытаюсь загрузить, находится на левой стороне, а изображение, которое отображается (и сохраняется Qt), - на правой стороне.

Вопрос : как создать правильно окрашенное изображение из данных tiff, учитывая, что я получаю в float, и я не знаю, как создать QImage данные из группы float.

Side by side

1 Ответ

0 голосов
/ 20 декабря 2018

Ваш входной GeoTIFF может иметь не одну полосу с плавающей запятой, а 3 (или 4) 8-битных полосы.

Полосы в GeoTIFF в основном являются каналами изображения.В отличие от других форматов изображений, эти каналы также могут иметь значения с плавающей запятой.

Вы можете ознакомиться с документацией GDAL здесь , чтобы узнать больше о разрешенных форматах.

Так что, вероятно, (хотя я не могу быть уверен на 100%не смотря на это), что ваш файл - просто GeoTIFF RGBA и, следовательно, имеет 4 полосы UNIT8.

Следовательно, ваш вызов в RasterIO совершенно неправильный.Вы должны перебрать 4 полосы и скопировать их с помощью RasterIO в буфер памяти QImage, соблюдая порядок полос.

Что-то вроде:

int nBands = poDataset->GetRasterCount();

for(int b=0; b < nBands; b++)
{
    GDALRasterBand *band = poDataset->GetRasterBand(b);
    if(band != nullptr)
    {
        CPLErr error = band->RasterIO(GF_Write, 0, 0, image.width(), image.height(), image.bits() + b, image.width(), image.height(), GDT_Byte, nBands, 0);
        if(error != CE_None)
        {
            // REPORT ERROR
        }
    }
}

Обратите внимание, что в приведенном выше коде пропущены всетребуемые проверки (убедитесь, что тип полосы байтов и т. д.), и в зависимости от вашего файла порядок диапазонов может варьироваться (BGRA, RGBA, ecc).

...