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 相关文章:

掌握深度学习,为什么要用PyTorch、TensorFlow框架?
作者 | Martin Heller译者 | 弯月责编 | 屠敏来源 | CSDN(ID:CSDNnews)【导读】如果你需要深度学习模型,那么 PyTorch 和 TensorFlow 都是不错的选择。并非每个回归或分类问题都需要通过深度学习来解决。甚至可以说,并…

ICANN敦促业界使用DNSSEC,应对DNS劫持攻击
HTTPS加密 可以有效帮助服务器应对DNS欺骗、DNS劫持、ARP攻击等安全威胁。DNS是什么?DNS如何被利用?HTTPS如何防止DNS欺骗? DNS如何工作? 如果您想访问www.example.com,您的浏览器需要找到该特定Web服务器的IP地址。它…

Lucene.net: the main concepts
2019独角兽企业重金招聘Python工程师标准>>> In the previous post you learnt how to get a copy of Lucene.net and where to go in order to look for more information. As you noticed the documentation is far from being complete and easy to read. So in …

einsum,一个函数走天下
作者 | 永远在你身后转载自知乎【导读】einsum 全称 Einstein summation convention(爱因斯坦求和约定),又称为爱因斯坦标记法,是爱因斯坦 1916 年提出的一种标记约定,本文主要介绍了einsum 的应用。简单的说ÿ…
常用排序算法的C++实现
排序是将一组”无序”的记录序列调整为”有序”的记录序列。假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,rirj,且ri在rj之前࿰…

4.65FTP服务4.66测试登录FTP
2019独角兽企业重金招聘Python工程师标准>>> FTP服务 测试登录FTP 4.65FTP服务 文件传输协议(FTP),可以上传和下载文件。比如我们可以把Windows上的文件shan上传到Linux,也可以把Linux上的文件下载到Windows上。 Cent…

JavaScript的应用
DOM, BOM, XMLHttpRequest, Framework, Tool (Functionality) Performance (Caching, Combine, Minify, JSLint) ---------------- 人工做不了,交给程序去做,这样可以流程化。 Maintainability (Pattern) http://www.jmarshall.com/easy/http/ http://dj…

miniz库简介及使用
miniz:Google开源库,它是单一的C源文件,紧缩/膨胀压缩库,使用zlib兼容API,ZIP归档读写,PNG写方式。关于miniz的更详细介绍可以参考:https://code.google.com/archive/p/miniz/miniz.c is a loss…

iOS之runtime详解api(三)
第一篇我们讲了关于Class和Category的api,第二篇讲了关于Method的api,这一篇来讲关于Ivar和Property。 4.objc_ivar or Ivar 首先,我们还是先找到能打印出Ivar信息的函数: const char * _Nullable ivar_getName(Ivar _Nonnull v) …

亚马逊首席科学家李沐「实训营」国内独家直播,马上报名 !
开学了,别人家的学校都开始人工智能专业的学习之旅了,你呢?近年来,国内外顶尖科技企业的 AI 人才抢夺战愈演愈烈。华为开出200万年薪吸引 AI 人才,今年又有 35 所高校新增人工智能本科专业,众多新生即将开展…
人脸检测库libfacedetection介绍
libfacedetection是于仕琪老师放到GitHub上的二进制库,没有源码,它的License是MIT,可以商用。目前只提供了windows 32和64位的release动态库,主页为https://github.com/ShiqiYu/libfacedetection,采用的算法好像是Mult…

倒计时1天 | 2019 AI ProCon报名通道即将关闭(附参会指南)
2019年9月5-7日,面向AI技术人的年度盛会—— 2019 AI开发者大会 AI ProCon,震撼来袭!2018 年由 CSDN 成功举办 AI 开发者大会一年之后,全球 AI 市场正发生着巨大的变化。顶尖科技企业和创新力量不断地进行着技术的更迭和应用的推…

法院判决:优步无罪,无人车安全员可能面临过失杀人控诉
据路透社报道,负责优步无人车在亚利桑那州致人死亡事件调查的律师事务所发布公开信宣布,优步在事故中“不承担刑事责任”,但是当时在车上的安全员Rafaela Vasquez要接受进一步调查,可能面临车辆过失杀人罪指控。2018年3月…

09 Storage Structure and Relationships
目标:存储结构:Segments分类:Extents介绍:Blocks介绍:转载于:https://blog.51cto.com/eread/1333894

边界框的回归策略搞不懂?算法太多分不清?看这篇就够了
作者 | fivetrees来源 | https://zhuanlan.zhihu.com/p/76477248本文已由作者授权,未经允许,不得二次转载【导读】目标检测包括目标分类和目标定位 2 个任务,目标定位一般是用一个矩形的边界框来框出物体所在的位置,关于边界框的回…
人脸识别引擎SeetaFaceEngine简介及在windows7 vs2013下的编译
SeetaFaceEngine是开源的C人脸识别引擎,无需第三方库,它是由中科院计算所山世光老师团队研发。它的License是BSD-2.SeetaFaceEngine库包括三个模块:人脸检测(detection)、面部特征点定位(alignment)、人脸特征提取与比对(identification)。人…

当移动数据分析需求遇到Quick BI
我叫洞幺,是一名大型婚恋网站“我在这等你”的资深老员工,虽然在公司五六年,还在一线搬砖。“我在这等你”成立15年,目前积累注册用户高达2亿多,在我们网站成功牵手的用户达2千多万。目前我们的公司在CEO的英名带领下&…

为什么选择数据分析师这个职业?
我为什么选择做数据分析师? 我大学专业是物流管理,学习内容偏向于管理学和经济学,但其实最感兴趣的还是心理学,即人在各种刺激下反应的机制以及原理。做数据分析师,某种意义上是对群体行为的研究和量化,两者…
人脸识别引擎SeetaFaceEngine中Detection模块使用的测试代码
人脸识别引擎SeetaFaceEngine中Detection模块用于人脸检测,以下是测试代码:int test_detection() {std::vector<std::string> images{ "1.jpg", "2.jpg", "3.jpg", "4.jpeg", "5.jpeg", "…

基于Pygame写的翻译方法
发布时间:2018-11-01技术:pygameeasygui概述 实现一个翻译功能,中英文的互相转换。并可以播放翻译后的内容。 翻译接口调用的是百度翻译的api接口。详细 代码下载:http://www.demodashi.com/demo/14326.html 一、需求分析 使用pyg…

冠军奖3万元!CSDN×易观算法大赛开赛啦
伴随着5G、物联网与大数据形成的后互联网格局的逐步形成,日益多样化的用户触点、庞杂的行为数据和沉重的业务体量也给我们的数据资产管理带来了不容忽视的挑战。为了建立更加精准的数据挖掘形式和更加智能的机器学习算法,对不断生成的用户行为事件和各类…

快速把web项目部署到weblogic上
weblogic简介 BEA WebLogic是用于开发、集成、部署和管理大型分布式Web应用、网络应用和数据库应 用的Java应用服务器。将Java的动态功能和Java Enterprise标准的安全性引入大型网络应用的开发、集成、部署和管理之中。 BEA WebLogic Server拥有处理关键Web应用系统问题所需的性…
使GDAL库支持中文路径或中文文件名的处理方法
之前生成的gdal 2.1.1动态库,在通过命令行执行时,遇到有中文路径或中文图像名时,GDALOpen函数不能正确的被调用,如下图:解决方法:1. 在所有使用GDALAllRegister();语句后面加上一句CPLSetConfigOption…

创新工场论文入选NeurIPS 2019,研发最强“AI蒙汗药”
9月4日,被誉为机器学习和神经网络领域的顶级会议之一的 NeurIPS 2019 揭晓收录论文名单,创新工场人工智能工程院的论文《Learning to Confuse: Generating Training Time Adversarial Data with Auto-Encoder》被接收在列。这篇论文围绕现阶段人工智能系…

Flutter环境搭建(Windows)
SDK获取 去官方网站下载最新的安装包 ,或者在Github中的Flutter项目去 下载 。 将下载的安装包解压 注意:不要将Flutter安装到高权限路径,例如 C:\Program Files\ 配置环境变量,在Path中添加flutter\bin的全路径(如:D…
Android在eoe分享一篇推荐开发组件或者框架的文章
http://www.eoeandroid.com/thread-311194-1-1.html y4078275315 主题 62 帖子 352 e币实习版主 积分314发消息电梯直达楼主 回复 发表于 2013-11-7 09:58:45 | 只看该作者 |只看大图 34本帖最后由 y407827531 于 2013-11-28 15:07 编辑感谢版主推荐,本贴会持续更新…

如何打造高质量的机器学习数据集?这份超详指南不可错过
作者 | 周岩,夕小瑶,霍华德,留德华叫兽转载自知乎博主『运筹OR帷幄』导读:随着计算机行业的发展,人工智能和数据科学近几年成为了学术和工业界关注的热点。特别是这些年人工智能的发展日新月异,每天都有新的…
人脸识别引擎SeetaFaceEngine中Alignment模块使用的测试代码
人脸识别引擎SeetaFaceEngine中Alignment模块用于检测人脸关键点,包括5个点,两个眼的中心、鼻尖、两个嘴角,以下是测试代码:int test_alignment() {std::vector<std::string> images{ "1.jpg", "2.jpg"…

微软宣布 Win10 设备数突破8亿,距离10亿还远吗?
开发四年只会写业务代码,分布式高并发都不会还做程序员? >>> 微软高管 Yusuf Mehdi 昨天在推特发布了一条推文,宣布运行 Windows 10 的设备数已突破 8 亿,比半年前增加了 1 亿。 根据之前的报道,两个月前 W…