GDAL中GDALDataset::RasterIO分块读取的实现
生活随笔
收集整理的這篇文章主要介紹了
GDAL中GDALDataset::RasterIO分块读取的实现
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
GDALDataset類中的RasterIO函數能夠對圖像任意指定區域、任意波段的數據按指定數據類型、指定排列方式讀入內存和寫入文件中,因此可以實現對大影像的分塊讀、寫運算操作。針對特大的影像圖像,有時為了減少內存消耗,對圖像進行分塊讀取很有必要。在以下的測試代碼中,給出了3種方式,每種方式的最終結果都是完全相同的,從內存占用情況來看:第一種大于第二種,第二種大于第三種。第三種消耗內存最小。
測試代碼如下:
int test_gdal_GDALDataset()
{const char* image_name = "E:/GitCode/GDAL_Test/test_images/3.jpg";GDALAllRegister();GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);if (poDataset == nullptr) {std::cout << "input image error" << std::endl;return -1;}int width = poDataset->GetRasterXSize();int height = poDataset->GetRasterYSize();int band_count = poDataset->GetRasterCount();size_t length = width * height * band_count;GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);//fprintf(stderr, "depth: %d\n", depth);assert(depth == 8 || depth == 16);int size_byte = 1;if (depth == 16) size_byte = 2;void* data1 = nullptr;void* data2 = nullptr;void* data3 = nullptr;if (depth == 8) {data1 = new unsigned char[length];memset(data1, 0, length);data2 = new unsigned char[length];memset(data2, 0, length);data3 = new unsigned char[length];memset(data3, 0, length);} else {data1 = new unsigned short[length];memset(data1, 0, length * 2);data2 = new unsigned short[length];memset(data2, 0, length * 2);data3 = new unsigned short[length];memset(data3, 0, length * 2);}GDALClose((GDALDatasetH)poDataset);{ // mode1GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);int band_count = poDataset->GetRasterCount();fprintf(stderr, "mode=1: band_count = %d\n", band_count);int* pBandMap = new int[band_count];for (int i = 0; i < band_count; i++) {pBandMap[i] = i + 1;}GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);void* poSrcData = nullptr;if (depth == 8)poSrcData = new unsigned char[width * height * band_count];elsepoSrcData = new unsigned short[width * height * band_count];poDataset->RasterIO(GF_Read, 0, 0, width, height,poSrcData, width, height, gdal_data_type, band_count, pBandMap, 0, 0, 0);if (depth == 8) {unsigned char* p1 = (unsigned char*)poSrcData;for (int y = 0; y < height; y++) {unsigned char* p2 = (unsigned char*)data1 + width * band_count * y;for (int x = 0; x < width; x++) {for (int band = 0; band < band_count; band++) {p2[x * band_count + band] = p1[band * width * height + y * width + x];;}}}} else {unsigned short* p1 = (unsigned short*)poSrcData;for (int y = 0; y < height; y++) {unsigned short* p2 = (unsigned short*)data1 + width * band_count * y;for (int x = 0; x < width; x++) {for (int band = 0; band < band_count; band++) {p2[x * band_count + band] = p1[band * width * height + y * width + x];;}}}}GDALClose((GDALDatasetH)poDataset);delete[] pBandMap;delete[] poSrcData;}{ // mode2GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);int crop_width = 200;int crop_height = 200;int loops_y = height / crop_height;int loops_x = width / crop_width;for (int y = 0; y < loops_y; y++) {for (int x = 0; x < loops_x; x++) {int band_count = poDataset->GetRasterCount();fprintf(stderr, "mode=2: band_count = %d\n", band_count);int* pBandMap = new int[band_count];for (int i = 0; i < band_count; i++) {pBandMap[i] = i + 1;}GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);void* poSrcData = nullptr;if (depth == 8)poSrcData = new unsigned char[crop_width * crop_height * band_count];elsepoSrcData = new unsigned short[crop_width * crop_height * band_count];int xOff = crop_width * x;int yOff = crop_height * y;poDataset->RasterIO(GF_Read, xOff, yOff, crop_width, crop_height,poSrcData, crop_width, crop_height, gdal_data_type, band_count, pBandMap, 0, 0, 0);if (depth == 8) {unsigned char* p1 = (unsigned char*)poSrcData;unsigned char* p2 = (unsigned char*)data2 + width * band_count * y * crop_height;for (int m = 0; m < crop_height; m++) {unsigned char* p3 = p2 + width * band_count * m + x * crop_width * band_count;for (int n = 0; n < crop_width; n++) {for (int band = 0; band < band_count; band++) {p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];}}}}else {unsigned short* p1 = (unsigned short*)poSrcData;unsigned short* p2 = (unsigned short*)data2 + width * band_count * y * crop_height;for (int m = 0; m < crop_height; m++) {unsigned short* p3 = p2 + width * band_count * m + x * crop_width * band_count;for (int n = 0; n < crop_width; n++) {for (int band = 0; band < band_count; band++) {p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];}}}}delete[] pBandMap;delete[] poSrcData;}}GDALClose((GDALDatasetH)poDataset);}{ // mode3int crop_width = 200;int crop_height = 200;int loops_y = height / crop_height;int loops_x = width / crop_width;for (int y = 0; y < loops_y; y++) {for (int x = 0; x < loops_x; x++) {GDALDataset* poDataset = (GDALDataset*)GDALOpen(image_name, GA_ReadOnly);int band_count = poDataset->GetRasterCount();fprintf(stderr, "mode=3: band_count = %d\n", band_count);int* pBandMap = new int[band_count];for (int i = 0; i < band_count; i++) {pBandMap[i] = i + 1;}GDALDataType gdal_data_type = poDataset->GetRasterBand(1)->GetRasterDataType();int depth = GDALGetDataTypeSize((GDALDataType)gdal_data_type);void* poSrcData = nullptr;if (depth == 8)poSrcData = new unsigned char[crop_width * crop_height * band_count];elsepoSrcData = new unsigned short[crop_width * crop_height * band_count];int xOff = crop_width * x;int yOff = crop_height * y;poDataset->RasterIO(GF_Read, xOff, yOff, crop_width, crop_height,poSrcData, crop_width, crop_height, gdal_data_type, band_count, pBandMap, 0, 0, 0);if (depth == 8) {unsigned char* p1 = (unsigned char*)poSrcData;unsigned char* p2 = (unsigned char*)data3 + width * band_count * y * crop_height;for (int m = 0; m < crop_height; m++) {unsigned char* p3 = p2 + width * band_count * m + x * crop_width * band_count;for (int n = 0; n < crop_width; n++) {for (int band = 0; band < band_count; band++) {p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];}}}} else {unsigned short* p1 = (unsigned short*)poSrcData;unsigned short* p2 = (unsigned short*)data3 + width * band_count * y * crop_height;for (int m = 0; m < crop_height; m++) {unsigned short* p3 = p2 + width * band_count * m + x * crop_width * band_count;for (int n = 0; n < crop_width; n++) {for (int band = 0; band < band_count; band++) {p3[n * band_count + band] = p1[band * crop_width * crop_height + m * crop_width + n];}}}}GDALClose((GDALDatasetH)poDataset);delete[] pBandMap;delete[] poSrcData;}}}for (int i = 0; i < length * size_byte; i++) {unsigned char* p1 = (unsigned char*)data1;unsigned char* p2 = (unsigned char*)data2;unsigned char* p3 = (unsigned char*)data3;if (p1[i] != p2[i] || p1[i] != p3[i]) {fprintf(stderr, "error: data1 != data2 or data1 != data3\n");return -1;}}delete[] data1;delete[] data2;delete[] data3;return 0;
}
GitHub:
https://github.com/fengbingchun/GDAL_Test
總結
以上是生活随笔為你收集整理的GDAL中GDALDataset::RasterIO分块读取的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GDAL2.1.1库在Ubuntu14.
- 下一篇: 常用排序算法的C++实现