一种适用于分布式计算环境的大型遥感影像重构方法
技术领域
本发明涉及地球空间信息技术领域的大型遥感影像存储技术,具体的说是一种在Hadoop分布式系统上存储文件较大(数百兆乃至更大)的影像文件的方法,该方法使得HDFS(Hadoop Distribute File System)在对文件进行分块存储时依旧保持每个文件块内部像元对应的元信息的完整性,解决了使用Hadoop平台处理大型影像文件时由于被切分的文件块中元信息缺失而导致的无法识别及处理影像文件分块的问题。
背景技术
经过数十年的高速发展,遥感技术已经在国防、农业、国土、海洋、军事、测绘、水利、气象、地质、生态环境、矿产、旅游、考古等领域有着广泛地应用,它为人类提供了从多维和宏观角度去认识世界的新方法与新手段。遥感技术本身更是迅猛发展,多样化的影像获取途径、迅速提升的遥感影像质量带来的是海量的需要存储和处理的影像文件,从最初MB级、GB级发展到现在的TB级甚至PB级。相关从业人员开始尝试使用Hadoop分布式系统来存储和处理这些遥感影像,使用HDFS分布式文件系统存储影像文件、MapReduce分布式计算框架来对存储在HDFS中的遥感影像做并行计算。
然而,由于HDFS在对原本完整的影像文件切割成不同的文件块存储在不同的节点上的特性,导致了大部分的节点在读取影像文件块时由于丢图像失元信息而导致无法正常识别图像。针对这一问题,目前业内常用的应对方案是人为改变Hadoop 128M的默认分块阀值,将其值提升至超过单幅影像文件的大小以使得影像文件不被切割。然而随着遥感影像获取方式的越来越先进,现阶段单个高分辨率、多波段的影像文件大小动辄需要GB级别的存储空间,而一味的扩大Hadoop默认分块的阀值大小又将对Hadoop分布式计算的性能优势带来制约,是不可持续的解决方案。此外,学界还有相关人员采用在MapReduce的计算任务启动前强制合并被分割的影像文件、集群运行前使用主节点Namenode预先读取全部影像文件等方法来应对大影像被分割导致的元信息无法获取的问题,但这些应对方法均对Hadoop系统的分布式存储/处理的核心设计理念带来了限制,以至于影响到平台整体的性能及稳定性。
因此,目前相关领域内亟需一种既保证Hadoop平台对大影像文件正常分块存储、并行计算又不影响整体性能和稳定性的方法,以解决上述存在的问题。
发明内容
本发明的目的是提供一种大影像文件的内部切割和重构方法,用于在Hadoop云计算平台上处理大型遥感影像时,在HDFS平台上输入影像文件的过程中对影像文件进行内部切割与重新构建,以及其复原方法。该方法能够确保大型的影像文件在被切割分块存储后,每一部分保留了其对应图像的元信息,使得MapReduce分布式计算框架可以相互独立地识别并处理每一个影像文件块,同时不对Hadoop系统整体的运行速度和稳定性带来影响,且全过程无需依赖数据库软件。
本发明在HDFS的基础上在大影像文件进行分块前预处理,根据HDFS分块大小对影像文件内部进行切片的重构。HDFS是当下使用最广泛的云计算平台——Hadoop的主要组成部分,与MapReduce一同构成了Hadoop系统的分布式存储与分布式计算基础。根据Hadoop的工作模式,待处理的文件在被上传至HDFS时会被按照特定的大小切割成多个文件块并以一定的冗余度分别存储在集群中不同的计算节点上。针对影像文件的处理任务启动时,系统依据“本地计算”的原则调度计算资源,即各节点优先处理存储于本节点上的数据。通常情况下,Hadoop默认为每一个文件块启动单独的进程进行计算,这就决定了适宜的文件块大小对集群运行的重要性,过大的文件块或过多的小文件块都会对整体性能带来影响。而本发明主要解决的问题就是在不影响文件分块的基础上实现大影像文件在Hadoop上的存储和处理。
本发明要解决的技术问题可分解为三个方面:要解决影像文件的定量裁剪问题,确保对影像进行行列裁剪后获得的影像切片大小小于并尽量接近设定的固定值;要解决裁剪后的影像文件切片重新构建为新文件的问题,使得HDFS在对新文件进行分块存储式不破坏内部切片结构;要解决将构建的新文件完整复原为原影像文件结构的问题。
本发明所采用的具体技术方案是:一种适用于分布式计算环境的大型遥感影像存储方法,该方法首先过滤出准备上传至HDFS的文件中的影像文件。接着将过滤得到的影像文件通过计算以一定的重叠度裁剪为多个影像切片。然后在每一个影像切片首部添加该切片的描述信息,并对除最后一个切片外的影像切片进行大小补齐,使其占用存储空间的大小等于以HDFS分块阀值大小,形成标准的文件块。再按顺序将文件块合并,并在尾部追加文件整体描述信息,由此得到重构后的影像文件并交由HDFS进行后续操作。最后是在使用过程中MapReduce处理任务从文件块中提取影像切片的方法以及将重构后的文件恢复为原影像文件的方法。
本发明包括以下具体步骤:
步骤1:首先读取Hadoop集群配置信息中的HDFS文件分块大小的值,并依据该值对比筛选出超过该大小的文件,然后根据文件后缀名提取出其中的影像文件,并将获取到的文件作为需要进行后续处理的目标影像文件;
步骤2:读取目标影像文件,将单个大型影像文件以横向形式裁剪为数个大小接近但不超过一个HDFS文件分块大小的影像切片文件,最后一个切片文件只需小于HDFS分块大小即可,此外裁剪时在相邻的影像切片之间保持一定的上下重叠;
步骤3:在各个影像切片文件的头部添加60个字节大小的切片文件的描述信息,并根据计算在文件尾部填充对应长度的空白内容,以确保除最后一个影像切片文件外的其它切片文件大小均等于HDFS文件分块大小;
步骤4:按顺序合并各个影像切片文件并在尾部添加对重构的新文件的11个字节整体描述信息,至此完成大型影像文件的重构并得到适用于分布式处理环境的新文件。
所述步骤2中,读取目标影像文件的同时即提取影像基本信息,包括图像的像素宽度、像素高度、像元数据类型、波段数,以及遥感影像空间信息,如左上角起始坐标、分辨率、空间投影,并写入至对应的影像切片文件在中;通过改变切片的裁剪高度h来控制得到的切片文件大小,控制影像切片大小的公式为:
且splitSize<=blockSize;
其中w为影像切片宽度,等于原影像短边,h为影像切片高度,小于原影像长边H,overPixel为重叠影像切片间的重叠宽度,datatypeSize为每个影像的像元数据类型,bandsCount为影像的波段数,imgMetaSize为影像文件的元信息需要占用的存储空间,splitMetaSize是为后续写入切片描述信息预留的空间大小,固定为60个字节,splitSize为裁剪所得影像切片文件大小,n表示影像切片的序号,N则为对当前影像裁剪后得到的影像切片总数量,blockSize则表示HDFS文件分块的大小;
使用重叠裁剪的方式,保持上下影像切片间存在重叠范围,以减少影像切割对领域相关影像计算中边缘像元的影响,原影像高度H与各个影像切片之间的高度关系如下:
normalSplitHeight×(N–1)+lastSplitHeight+overPixel×2×(N-1)=H;
其中N则为对当前影像裁剪后得到的影像切片总数量,normalSplitHeight为前N-1个切片的高度,lastSplitHeight为最后一个切片高度;最后一个影像切片文件大小小于HDFS文件分块大小,但不再受到应尽量接近于HDFS分块大小的限制。
步骤3中所述各个影像切片文件的头部添加60个字节大小的切片文件的描述信息的具体位置及记录的内容为1-48个字节记录原完整影像文件的文件名称,49-50个字节记录该影像切割后产生的影像切片数量,51-54个字节记录当前影像切片的序号,55-56个字节记录重叠像元宽度,57-60个字节记录了该文件块中包含影像切片文件的实际长度;
文件尾部需要添加的空白填充长度为HDFS文件块大小减去切片文件本身长度,再减去添加在切片文件头的描述信息的长度,即
blanksAppend=blockSize-splitSize–splitMetaSize;
其中blanksAppend为需要填充区域大小,splitSize为切片文件大小,splitMetaSize为文件头部写入的60直接描述信息,blockSize为HDFS文件分块大小。
所述步骤4具体为:对前述添加了附件内容的切片文件按顺序以首尾相接的形式合并为一个新的文件;新文件尾部添加的11个字节的文件整体描述信息由5部分组成,分别是1字节记录影像的波段数量,2-3字节记录原始影像的宽度,4-5字节记录原始影像的高度,6-7字节记录相邻影像切片间的重叠像素宽度,8-11字节记录该文件内部切片对应的HDFS文件块大小。
本发明产生的有益效果是:
本发明提供了一种大影像文件的内部切割和重构方法,使得无需对Hadoop平台本身进行改变的情况下,能够将Hadoop平台直接用于大型影像文件的处理,解决了大型影像文件被HDFS文件系统分块存储时无法读取影像元信息的问题。
同时本发明的实现过程简单、自动性高,对各种影像文件具有普适性。充分利用HDFS文件系统上传海量文件时的网络瓶颈,在上传文件时的排队时间对大型影像文件进行预先处理的设计,避免了带来明显的额外时间消耗,且防止了对平台本身的运行效率及稳定性带来影响。本发明的出现有助于进一步推广分布式处理模式在数据量庞大的遥感影像处理领域的应用,并为更深层次的遥感影像分布式计算打下了一定的基础。
附图说明
图1为本发明的操作流程示意图,图中,是切片头描述信息,是影像文件内元数据,是像元数据,是空白填充,是重构文件的整体描述信息;
图2为本发明生成影像切片的裁剪方法示意图;
图3为本发明重构后的文件上传到HDFS中后文件块在节点上的分布示意;
图4是本发明的实施例与HDFS及用户的交互关系示意图。
具体实施方式
下面结合附图和具体实施方式对本发明作进一步详细的说明。
参阅图1所示,本发明在选取目标影像文件后,按照图2所示将影像文件裁剪为多个影像切片,然后补齐各个影像切片文件的描述信息和空白填充部分,最后按顺序合并影像切片文件并在尾部添加整体描述信息。本发明可在微机平台下采用Java语言开发实现,对影像文件的读取和操作可用GDAL开源栅格影像库实现,具体步骤如下:
第一步从目标文件中筛选出符合条件的文件
首先拦截待上传至HDFS分布式文件系统的文件。然后读取Hadoop集群配置文件hdfs-site.conf中的dfs.block.size属性获取HDFS文件分块大小的值,再以该值为标准,筛选出文件大小超过该值的文件,最后依据文件后缀名从中提取出通用的影像文件,如TIFF、Geo-Tiff、HDF、PNG、JPEG、BMP等格式。
由此得到需要处理的目标文件,并将其记录于“待重构文件”队列中作为下一步骤的输入。同时将筛选后的非目标文件的控制权直接归还HDFS进行上传操作。
第二步将影像裁剪为影像切片
使用GDAL Java库提供的Dataset.getRasterXSize()、Dataset.getRasterYSize()、Dataset.GetRasterBand().getDataType()、Dataset.getRasterCount()、Dataset.GetGeoTransform()、Dataset.GetProjection()方法从“待重构文件”队列中读取对应的影像基本信息,如图像的像素宽度、像素高度、像元数据类型、波段数,以及遥感影像空间信息,如左上角起始坐标、分辨率、空间投影,用于后续将此类信息写入至每个影像切片文件的元信息中。
裁剪影像时,设定原影像长边为H,短边为W。裁剪影像时,固定裁剪的切片宽度等于W,通过改变切片影像高度来控制得到的切片文件大小。同时根据用户的输入获取相邻的影像切片间的重叠像素。以下为本发明中控制影像切片大小的公式:
且splitSize<=blockSize;
其中w为影像切片宽度,等于原影像短边。h为影像切片高度,作为控制控制影像切片大小的关键变量。overPixel为重叠影像切片间的重叠宽度,根据用户的输入值确定。datatypeSize为每个影像的像元数据类型,描述了每个像元占用的存储空间大小,如uint16_t类型为2字节。bandsCount为影像的波段数。imgMetaSize为影像文件的元信息需要占用的存储空间。splitMetaSize是为后续写入切片描述信息预留的空间大小,固定为60个字节。splitSize为裁剪所得影像切片文件大小。n表示影像切片的序号,N则为对当前影像裁剪后得到的影像切片总数量。blockSize则表示HDFS文件分块的大小。
公式中除变量h外均为已知值,且h始终为正整数,本发明通过对h取临界值,来使得影像切片占用的存储空间尽可能地接近或等于HDFS文件块大小,即该临界值满足如果该值再加1则会直接导致blockSize小于影像切片所需的存储空间。同时最后一个切片的height值在该基础上满足不超出原影像边界的限制。
参阅图2所示,图中H为原影像高度,w为影像切片宽度,h为影像切片自身高度,其表示的范围即为当某切片上下重叠像素为0时的影像切片包含的纵向影像范围,o为影像切片与上方切片的重叠像素,o’为影像切片与下方切片重叠像素。因此某一影像切片包含的实际高度为其本身高度与上下重叠高度之和,即o+h+o’。
同时,由于影像裁剪时相邻的影像切片之间保留了一定的重叠宽度,原影像高度H与各个影像切片之间的高度关系如下:
normalSplitHeight×(N–1)+lastSplitHeight+overPixel×2×(N–1)=H;
其中N则为对当前影像裁剪后得到的影像切片总数量,normalSplitHeight为前N-1个切片的高度,lastSplitHeight为最后一个切片高度。
将裁剪所得各个影像切片以临时文件的形式进行存储。使用GDAL库中driver.Create()创建裁剪的影像切片,并写入源文件分辨率、投影方式等空间信息后,将影像切片保存为临时文件,参阅图1裁剪操作后的文件形态所示。
第三步添加影像切片描述信息及尾部空缺补齐
上一步骤获得裁剪后的影像切片文件后,将其重新读入内存。并在内存中对切片文件进行进一步完善,以辅助集群处理HDFS文件块时从中提取出影像切片。该步骤由在切片文件头部写入当前切片的描述信息和在切片文件尾部进行空白填充两部分操作组成,获得的切片文件参阅图1添加描述信息和空白填充操作后的形态所示。
添加至切片文件头部的切片描述信息占用空间为60字节,即上一步骤中预留的splitMetaSize大小。这60个字节由5部分组成,以下为每部分中记录的内容及其具体位置:
1-48个字节记录原完整影像文件的文件名称;
49-50个字节记录该影像切割后产生的影像切片数量;
51-54个字节记录当前影像切片的序号;
55-56个字节记录重叠像元宽度,即overPixel;
57-60个字节记录了该文件块中包含影像切片文件的实际长度,即splitSize。
其中影像切片序号均为正整数,从1开始计算;影像切片文件的实际长度指该影像切片文件未添加当前头部的60字节的描述信息及尾部的空白填充时的文件长度。
对于除最后一个切片外的其它切片文件而言,本发明采用在切片文件尾部填充一定长度空白的方法确保切片文件的块大小等于一个HDFS文件块大小。其长度为HDFS文件块大小减去切片文件本身长度,再减去添加在切片文件头的描述信息的长度,即:
blanksAppend=blockSize-splitSize–splitMetaSize;
blanksAppend表示需要填充区域大小,当满足splitSize与splitMetaSize之和恰好等于blockSize时,则blanksAppend为0,即此时因切片文件及其文件头所占用的存储空间刚好达到一个HDFS文件分块的大小而无需再进行空白填充。
第四步合并影像文件块并追加文件全局描述信息
基于前述步骤对裁剪所得切片文件的进行首尾内容填充后,除最后一个影像切片外所有影像切片文件的大小均等同于HDFS文件分块的大小。此时创建一个新文件并将内存中的第一个影像切片文件写入磁盘,再使用RandomAccessFile.write()的方式将后续影像切片按顺序追加至文件尾部。
随后,继续使用RandomAccessFile.write()在得到的新文件尾部追加对于新文件内部切片组织结构的描述信息,用于为将得到的新文件恢复为原影像文件的操作提供辅助信息。尾部描述信息的占用空间为11个字节,其组成内容如下:
1号字节——描述影像的波段数量;
2-3号字节——描述原始影像的宽度;
4-5号字节——描述原始影像的高度;
6-7号字节——描述相邻影像切片间的重叠像素宽度,即overPixel;
8-11号字节——描述该文件内部切片对应的HDFS文件块大小,即blockSize值。
至此完成了原大影像文件的重构,并得到一个新的文件,其形态参阅图1合并及追加描述操作后的形态所示。随后将控制权归还至HDFS进行文件分块及上传工作。文件在上传至HDFS分布式文件系统后分布状态如图3所示,根据HDFS的冗余设计每份个文件块均被多份存储,同时每个文件块恰好包含了前述一个影像切片。此时的新文件可以在Hadoop分布式系统下进行读写及计算操作,且优于HDFS上传文件I/O瓶颈的存在,并且前述全部处理步骤不会对HDFS文件上传带来明显的效率影响。
重构后的影像读取及重构文件的复原
在使用Hadoop平台的MapReduce分布式处理框架处理文件时,每个Map任务均是以文件块的形式读取文件,由于前述对影像文件的重构,Map任务读取到的文件块均为一个影像切片文件。因此,获取切片文件内的影像时,需要根据构建影像切片文件的方法,先读取文件块头部60个字节的描述信息,再根据描述信息获取影像文件在文件块中的位置范围,并以此读取到影像切片内容。
重构后的影像文件还可与原影像相互转换。在将重构后的影像文件转换为原影像文件时,根据本发明在构建影像时设计的结构,首先读取文件尾部大小为11个字节的重构文件全局描述信息,获取该重构文件内部的文件块大小——blockSize、切片间重叠像素宽度——overPixel等信息。然后按照内部文件块大小将文件整体拆分为多个文件块,即除最后一个文件块外,从第一个字节起第n个blockSize的长度范围内即为文件中的第n个文件块。最后一个文件块的启示位置为blockSize×(n-1),截止位置为文件的最后一个字节。
再从文件块头部存储的60个字节的影像切片描述信息中获取影像切片文件的大小——splitSize,以得知切片文件在该文件块中所处的位置范围,即61字节至(60+splitSize)字节之间。最后将读取到的各个影像切片按裁剪顺序及进行拼接,同时拼接过程中相邻影像切片间的重叠度根据描述信息中存储的overPixel确定。
实施例
在微机平台环境下使用Java语言开发了一个HDFS文件上传插件程序并使用GDAL栅格影像库读取和操作常见的影像格式。该程序与HDFS及用户的交互关系参阅图4所示,程序在文件上传至HDFS分布式文件系统的同时,自动截取大小超过HDFS文件分块大小的影像文件,读取影像文件信息并进行裁剪、文件填充等操作,快速、批量地实现对目标影像文件的内部重构,然后将文件转交给HDFS分布式文件系统继续文件上传操作。并且在用户从HDFS上下载经过重构操作的影像文件时,自动对文件进行逆重构操作,恢复影像文件上传时的格式。
插件程序主要由两个模块组成,一是影像文件重构模块,二是重构文件复原模块,即逆重构。只需将插件程序源码加入HDFS并重新编译,即可在HDFS分布式文件系统中加入对大型影像文件重构及逆重构的功能,并在MapReduce中根据文件块头部的描述信息读取影像切片。
用户在将大型影像文件上传至HDFS时,只需在原上传命令中增加参数overPixel值,即影像切片间重叠像素个数即可,若未输入则默认值为0。随后插件程序会自动筛选需要处理的影像文件,并根据重叠像素个数、HDFS文件块大小等设置对影像进行裁剪及文件重构,然后再转由HDFS自身上传至HDFS分布式文件系统。
用户使用MapReduce分布式计算框架对影像进行目标计算时,需要从文件块头部60个字节的描述信息中获取文件块内影像切片文件的大小——splitSize,即可得知影像切片文件在文件块内的存储位置为61字节至(60+splitSize)字节。然后再按原影像文件格式读取影像切片即可,并进行所需要的影像处理即可。
用户在从HDFS分布式文件系统取回影像文件时,无需进行额外的操作,插件程序会在文件从HDFS上下载回本地的同时检测文件是否为经过重构的影像文件,若是则自动进行逆重构,并返回原始影像格式的文件至客户端。