2015-11-19 81 views
0

我使用GDAL來讀取一些圖像文件並希望使用Qt來顯示它們。到目前爲止,我設法爲我的GDALDataSet中的每個GDALRasterBand創建了一個灰度級QImage,但我不知道如何創建單個RGB圖像。從GDALDataSet創建RBG顏色QImage

這裏是我做了什麼:

#include <gdal_priv.h> 
#include <QtGui\QImage> 

int main(int argc, char *argv[]) 
{ 
    GDALAllRegister(); 

    GDALDataset* dataset = static_cast<GDALDataset*>(GDALOpen("path_to_some_image.tif", GA_ReadOnly)); 
    int size_out = 200; 

    for (int i = 1; i <= 3; ++i) 
    { 
     GDALRasterBand* band = dataset->GetRasterBand(i); 

     std::vector<uchar> band_data(size_out * size_out); 
     band->RasterIO(GF_Read, 0, 0, size_out, size_out, band_data.data(), size_out, size_out, GDT_Byte, 0, 0); 

     QImage band_image(band_data.data(), size_out, size_out, QImage::Format_Grayscale8); 
     band_image.save(QString("C:\\band_%1.png").arg(i)); 
    } 

    return 0; 
} 

如何讀取數據,所以我可以創建一個單一的RGB QImage

回答

2

你快到了。第一項是QImage帶格式標誌的緩衝區。因此,該格式標誌需要與您從文件加載的映像匹配,否則需要進行轉換。下面的例子假設一個4通道圖像。

QImage的格式標誌文檔:http://doc.qt.io/qt-5/qimage.html#Format-enum

下一個組件是GDAL的RasterIO方法分別處理每個頻段,這意味着你必須單獨的交錯像素或失去附帶由帶帶加載光柵效率。

RasterIO:http://gdal.org/classGDALRasterBand.html#a30786c81246455321e96d73047b8edf1

我喜歡的OpenCV的這個merge方法。只需爲每個樂隊創建一個灰度圖像並將它們結合在一起即可。

OpenCV的合併:http://docs.opencv.org/3.0.0/d2/de8/group__core__array.html#ga61f2f2bde4a0a0154b2333ea504fab1d

例如,給定一個RGBA支持GeoTiff,

// OpenCV Libraries 
#include <opencv2/core/core.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 

// GDAL Libraries 
#include <gdal.h> 

// QT Libraries 
#include <QtGui\QImage> 

using namespace cv; 


int main(int argc, char* argv[]) 
{ 

    // Initialize GDAL 
    GDALAllRegister(); 

    // Load image 
    GDALDataset* dataset = GDALOpen("path_to_some_image.tif", GA_ReadOnly); 

    // Get raster image size 
    int rows = dataset->GetRasterYSize(); 
    int cols = dataset->GetRasterXSize(); 
    int channels = dataset->GetRasterCount(); 

    // Create each separate image as grayscale 
    std::vector<cv::Mat> image_list(channels, cv::Mat(rows, cols, CV_8UC1)); 
    cv::Mat output_image; 

    // Iterate over each channel 
    for (int i = 1; i <= channels; ++i) 
    { 
     // Fetch the band 
     GDALRasterBand* band = dataset->GetRasterBand(i); 

     // Read the data 
     band->RasterIO(GF_Read, 0, 0, 
         cols, rows, 
         image_list[i-1].data, 
         cols, rows, 
         GDT_Byte, 0, 0); 

    } 

    // Merge images 
    cv::merge(image_list, output_image); 

    // Create the QImage 
    QImage qt_image(band_data.data(), 
        cols, 
        rows, 
        QImage::Format_RGBA8888); 

    // Do some stuff with the image 

    return 0; 
} 
+0

我希望我可以逃脫不使用OpenCV的,但多了一些嘗試後,我用您的解決方案(以一點調整,以適應16位圖像)。 – undu

+0

否則,您可以遍歷柵格帶,在圖像的每一行調用RasterIO。然後,遍歷行中的每一列,您可以在QImage中設置像素值。這並非不合理,但絕對不是最快的。 – msmith81886