GDAL分塊處理流程

使用GDAL庫在編寫圖像處理算法時,爲了提高處理的效率,經常會進行分塊處理,下面的代碼是使用GDAL分塊處理的一個簡單示例:

圖像分塊代碼

影像分塊代碼,只有輸入輸出圖像路徑,對原始圖像經過一定的處理,將結果寫入輸出圖像。此處原始圖像和結果圖像的大小完全一致。具體流程參考下面的代碼以及裏面的註釋部分。

#include "gdal_priv.h"

bool ImageProcess(const char* pszSrcFile, const char* pszDstFile, const char* pszFormat)
{
    //註冊GDAL驅動
    GDALAllRegister();

    //獲取輸出圖像驅動
    GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
    if (poDriver == NULL)   //輸出文件格式錯誤
        return false;

    //打開輸入圖像
    GDALDataset *poSrcDS = (GDALDataset*)GDALOpen(pszSrcFile, GA_ReadOnly);
    if (poSrcDS == NULL)    //輸入文件打開失敗
        return false;

    //獲取輸入圖像的寬高波段書
    int nXSize = poSrcDS->GetRasterXSize();
    int nYSize = poSrcDS->GetRasterYSize();
    int nBands = poSrcDS->GetRasterCount();

    //獲取輸入圖像仿射變換參數
    double adfGeotransform[6] = { 0 };
    poSrcDS->GetGeoTransform(adfGeotransform);
    //獲取輸入圖像空間參考
    const char* pszProj = poSrcDS->GetProjectionRef();

    GDALRasterBand *poBand = poSrcDS->GetRasterBand(1);
    if (poBand == NULL)    //獲取輸入文件中的波段失敗
    {
        GDALClose((GDALDatasetH)poSrcDS);
        return false;
    }

    //創建輸出圖像,輸出圖像是1個波段
    GDALDataset *poDstDS = poDriver->Create(pszDstFile, nXSize, nYSize, 1, GDT_Byte, NULL);
    if (poDstDS == NULL)    //創建輸出文件失敗
    {
        GDALClose((GDALDatasetH)poSrcDS);
        return false;
    }

    //設置輸出圖像仿射變換參數,與原圖一致
    poDstDS->SetGeoTransform(adfGeotransform);
    //設置輸出圖像空間參考,與原圖一致
    poDstDS->SetProjection(pszProj);

    int nBlockSize = 256;     //分塊大小

    //分配輸入分塊緩存
    unsigned char *pSrcData = new unsigned char[nBlockSize*nBlockSize*nBands];
    //分配輸出分塊緩存
    unsigned char *pDstData = new unsigned char[nBlockSize*nBlockSize];

    //定義讀取輸入圖像波段順序
    int *pBandMaps = new int[nBands];
    for (int b = 0; b < nBands; b++)
        pBandMaps[b] = b + 1;

    //循環分塊並進行處理
    for (int i = 0; i < nYSize; i += nBlockSize)
    {
        for (int j = 0; j < nXSize; j += nBlockSize)
        {
            //定義兩個變量來保存分塊大小
            int nXBK = nBlockSize;
            int nYBK = nBlockSize;

            //如果最下面和最右邊的塊不夠256,剩下多少讀取多少
            if (i + nBlockSize > nYSize)     //最下面的剩餘塊
                nYBK = nYSize - i;
            if (j + nBlockSize > nXSize)     //最右側的剩餘塊
                nXBK = nXSize - j;

            //讀取原始圖像塊
            poSrcDS->RasterIO(GF_Read, j, i, nXBK, nYBK, pSrcData, nXBK, nYBK, GDT_Byte, nBands, pBandMaps, 0, 0, 0, NULL);

            //再這裏填寫你自己的處理算法
            //pSrcData 就是讀取到的分塊數據,存儲順序爲,先行後列,最後波段
            //pDstData 就是處理後的二值圖數據,存儲順序爲先行後列

            memcpy(pDstData, pSrcData, sizeof(unsigned char)*nXBK*nYBK);
            //上面這句是一個測試,將原始圖像的第一個波段數據複製到輸出的圖像裏面

            //寫到結果圖像
            poDstDS->RasterIO(GF_Write, j, i, nXBK, nYBK, pDstData, nXBK, nYBK, GDT_Byte, 1, pBandMaps, 0, 0, 0, NULL);
        }
    }

    //釋放申請的內存
    delete[]pSrcData;
    delete[]pDstData;
    delete[]pBandMaps;

    //關閉原始圖像和結果圖像
    GDALClose((GDALDatasetH)poSrcDS);
    GDALClose((GDALDatasetH)poDstDS);

    return true;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章