zoukankan      html  css  js  c++  java
  • COG云原生优化遥感影像,瓦片切分的最佳实践

    摘要:云上遥感影像文件Cloud optimized GeoTIFF(COG)格式的详细介绍,大量数据上云面临的挑战,并分享了获得云原生影像最佳性能的实践经验。

    本文分享自华为云社区《COG云原生优化遥感影像,瓦片切分的最佳实践》,作者: tsjsdbd 。

    1 遥感影像文件格式

    遥感影像就是地球自拍照,一般文件很大,一张文件5GB左右。

    这些影像文件大多数都保存为 TIFF 格式(而不是JPEG),因为TIFF格式记录的内容是比较原始的多个波段的信息,也不会因为压缩丢失信息。

    1.1 TIFF格式

    这里分享一下 TIFF文件的格式:

    TIFF是一个灵活适应性强的文件格式,能够在一个文件中保存多幅图像。然后每幅影像带一个标签目录(多个标签),记录它的像素深度、每像素波段信息,RGB编码等详细信息。

    注意:上图属性之间没有顺序要求,都通过offset查找。实际上是链表的形式:

    因此,TIFF文件内部各Block块之间的顺序可以很灵活自由。

    1.2 TIFF标签目录格式

    每幅影像,带有一组标签目录,记录该图形的各种属性。

    标签目录的格式如下:

    每个标签(属性),由于信息内容不一样,其值大小有区别。有些信息小,它的标签值(Value)直接在标签里面。有些信息量比较大的,它的标签值(Value),在标签里放不下,需要记录在文件的其他位置上,通过offset便宜对应。

    1.3 TIFF单标签格式

    1个标签,就是记录图片的一个属性。主要是:属性名+属性值。

    具体格式如下:

    一般一幅图片,大概10几个属性。

    可以看到,整个TIFF文件,是分块分散的记录图像数据的。所有信息之间都是通过offset偏移量关联。

    ps:这里我先给“分块分散”标个粗。 这是它灵活性的优势,也是后续主题要讨论的。

    关于TIFF详细格式,可参考:

    1.4 GeoTIFF格式

    正是因为TIFF这种标签化的格式,非常的好扩展,为图片添加地理信息也很方便。 所以GeoTIFF就在TIFF的标签规范里面,增加一系列(地理信息相关的)扩展标签,用来记录一幅影像的地理坐标信息。

    可以看到,一个GeoTIFF,也是正常的TIFF文件。所以它的内容,也是分散分块在文件内保存的。只是多了一系列的地理信息标签。

    所有标签解释,见:

    1.5 TIFF格式灵活

    由于TIFF文件内部都是链表的形式,所以文件标准中并没有要求各Block块之间彼此的顺序。

    有时候它是这样的:

    更常见的则是这样的:

    少数还有可能是这样的:

    无论哪种组织形式,都是符合标准的TIFF文件。

    1.6 TIFF文件调试

    由于我个人的编程语言是GO语言,所以这里我选用了

    这个包(谷歌开源的TIFF文件解析包),函数调用使用 tiff.Parse() 就行。

    解析完打个断点,就可以看到TIFF文件的各种属性啦:

    上图可以看到,当前分析的这个TIFF文件里面,有5幅图片。

    如上图,第一幅图片,有21个属性。这是原始图片,带有地理信息属性(标签ID值大于3000),各属性如下:

    其余的4幅,都只有15个属性。是 overview,没有地理信息,单纯的图片(不带Geo地理属性,标签ID都是 2xx~3xx的),如下:

    我们打开其中一个标签,看它的值:

    这里看到这个属性ID是256,查询规范:

    得知这个表示图片的宽度,然后大小端属性,我们算出:第2个字节是28,第1个字节是174,实际值等于:28 * 256 + 174 = 7342 像素的宽度。

    可以查看实际图片的像素,就是 7342。

    其余属性,都可以按照这个方式一一查看。

    2 遥感影像上云面临的问题

    遥感影像的特点,主要是大。一般一张图片在5~10GB,单卫星每天增加TB级,全球每天增加PB级。随着卫星传感器精度增加,单个影像文件越来越大。

    大,带来的问题就是不容易保存,本地数据中心存不下,就得上云。但是大量的遥感数据上云后,面临不少挑战:

    1. 大量的既有软件,无法远程读取云上的(特别是对象存储,如S3)影像文件。必须先Download到本地,然后才能打开分析。
    2. 即使为软件增加S3驱动。远程分析一个文件,也不得不全量读取文件内容(因为它是链表式的文件)。注意这个是通过网络进行的,所以很影响效率。
    3. 单独取影像文件中的部分区域(瓦片,或者缩略图),也不得不全量下载or访问整个文件。即使瓦片仅占全影像的1/N。

    所以,能不能在访问云上的遥感影像数据的时候,只访问部分(尽可能小的)内容呢?

    2.1 GeoTIFF适合云的优化

    要达成这个目的,需要有以下能力:

    1. 云存储协议上支持以 Range方式读取云上的文件。
    2. GeoTIFF影像文件,支持先读取“所有标签数据”,然后以Offset偏移读取目标数据。

    这2个条件里面的第1个,目前各大云厂商的对象存储(如S3)都已经支持。

    关键是第2个条件。首先,能不能把GeoTIFF的“元数据”,全部放到文件头部,把实际Data数据放到文件尾部。

    即:

    这样的话,访问一个超大的GeoTIFF遥感影像,只需先发送HTTP GET获取文件头部16K字节,然后文件中剩余内容位置就都知道了。接下来想要访问什么,再根据偏移,发送HTTP GET访问目标XX字节的影像数据,就够了。

    然后,将图像切成小片,可以根据“瓦片”的方式访问目标区域。因为已经有了头部的标签信息,所以再访问具体区域,只需要根据Offset,直接读取云上文件的指定偏移就行。

    即:

    在这种模式下,该遥感影像文件,还是一个标准的GeoTIFF格式,只是它更适应云化访问。

    2.2 COG格式(Cloud optimized GeoTIFF)

    为了让云优化的GeoTIFF格式更加的普及,专门成立了COG(Cloud optimized GeoTIFF)标准。规范可以参考:

    介绍文章可以参考:

    目前该标准得到了业界很多公司的认可:

    重要的是,一个COG影像文件,也是一个标准的 GeoTIFF文件,可以兼容已有的各种软件生态。

    TIFF 和 GeoTIFF和COG 这三种文件格式之间的关系。

    3 COG文件最佳实践

    有了COG文件格式的背景介绍,接下里我们详细分析一下一个COG文件,怎么样才能做到云化性能最优?

    3.1 取文件头字节数

    一幅影像文件,目前远程读取的最常用的底层库就是 gdal了。它在第一次访问文件的时候,默认是先取 16KB的内容。大多数的GeoTIFF文件头,取16KB肯定是够了的,如下(取1次头就可以Open):

    但是也有些GeoTIFF文件信息太多,使得文件头很大。gdal就会不得不再次取一次文件头,如下图(取了2次头才能Open):

    2次HTTP请求,才能获得完整的TIFF文件头,显然访问效率大打折扣。

    这个时候,就得通过底层 gdal库的配置,来控制首次获取文件头的字节数了。

    环境变量:GDAL_INGESTED_BYTES_AT_OPEN=2000

    可以使得首次请求的时候,获取更大的文件头,如下图:

    但是如果影像文件的实际头都很小,你首次取太大肯定也浪费。

    所以请根据自己的影像规格,以及影像的属性,恰当的选择首次取文件头的字节数。避免每次都额外发送一次HTTP请求,浪费效率。

    3.2 瓦片大小的影响

    一图影像,举个例子,原始像素是 512*512的图片。

    如果我们按照 256*256的Tile(瓦片)进行保存,那么就会有4个瓦片。

    如果按照 512*512的Tile(瓦片)保存,那么只有1个瓦片。

    这2种保存方式,会导致文件头需要记录的“信息量”不一样。4个瓦片,就得记录4个偏移量。1个瓦片则只需要记1个偏移量。

    这里以一个5GB左右大小的GeoTIFF文件举例,按照128*128像素进行瓦片,那么所有的瓦片偏移值如下:

    (标签ID=324,代表TileOffsets,值为8字节的整型。)

    所以为了记录所有瓦片信息:65905(瓦片数) * 8(字节) = 527240,就要520KB。

    如果按照256*256的瓦片保存,则可以直接减少到1/4,记录所有瓦片的偏移信息只需要520KB / 4 = 130KB。可见适当加大瓦片面积,可以缩小TIFF文件头大小。

    但是瓦片又不能太大,因为这会影响取局部区域的像素效率问题。

    如下图举例:

    如果目标区域在一个小瓦片范围内,则瓦片大小为256*256的话,取回的文件内容,就很小。 而512*512的话,一次取回就得整个大瓦片。显然网络传输效率会降低很多。

    4 瓦片大小性能分析

    下面我们详细分析性能vs瓦片大小的影响,分别以:

    • gdal默认tile大小256*256。
    • rio默认tile大小 512*512。见:

    gdal命令:

    gdal_translate input.tiff output.tiff \
    -co TILED=YES -co COPY_SRC_OVERVIEWS=YES -co COMPRESS=LZW

    rio命令:

    rio cogeo create input.tif output.tif

    如果你仅有gdal,也可以通过以下命令:

    gdal_translate input.tif output.tif \
    -co TILED=YES -co COMPRESS=LZW -co COPY_SRC_OVERVIEWS=YES \
    -co BLOCKXSIZE=256 -co BLOCKYSIZE=256 \
    --config GDAL_TIFF_OVR_BLOCKSIZE 256

    来控制瓦片大小。

    gdal命令,可以通过docker直接获得:

    docker pull osgeo/gdal

    启动gdal容器的时候,只需要使用 -v 将主机目录,挂载到容器内就行。例如我的:

    docker run -it -v /home/tsjsdbd/cog/:/tmp/cog/ osgeo/gdal /bin/bash

    这样容器里面的/tmp/cog目录下,就可以看到主机/home/tsjsdbd里的tiff文件了。

    下面来对2种做对比,详细操作如下:

    4.1 取一个像素

    512*512瓦片:

    第2次通过HTTP响应取回来:105119744-105840639 = 720,895 字节

    256*256瓦片:

    可以看到,第2次请求的内容,小很多:139476992-139722751 = 245,759 字节

    对比发现,256的瓦片,第2次HTTP响应只有1/3,延时也是优势明显。

    4.2 取一块区域

    512*512瓦片:

    第2次通过HTTP响应取回来:32522240-33095679 = 573,439 字节

    256*256瓦片:

    同样的,第2次取的内容,小很多:41402368-41533439 = 131,071 字节

    同样,256的瓦片,第2次HTTP响应大小只有1/3,延时也是优势明显。

    4.3 512瓦片性能

    官方测试报告里面(见: )

    显示 512*512 的瓦片大小,性能更优,是因为,

    256*256的小瓦片,导致TIFF文件头太大了。第1次16KB取不完,又取了1次导致的。

    Ps:首次取的字节数,是可以通过配置控制的。

    所以实际业务场景下,具体以多大的瓦片划分,要根据项目影像图片特征适当的调整。

    4.4 性能小结

    性能对比看,256*256的小瓦片,在做局部在线Web预览加载时,性能更优异。

    但是 256*256 的瓦片,意味着瓦片数量更多,TIFF文件头更大,因此需要适当控制“首次取文件头字节”配置。

    上述GDAL操作步骤可以参考:

    其他GADL配置调优可参考:

    5 COG的未来

    分享了GeoTIFF影像文件上云后的一系列最佳实践后,我们探讨一下,未来在COG性能方面,有没有云厂商提供更加深度优化方式呢?

    可以想到的有:快速的获得COG文件头大小,使得首次HTTP请求,精确取想要的数据,不浪费额外的网络报文。不过这种就需要对象存储提供一些定制能力了。

    COG已经是业界普遍认可的云原生的遥感影像数据格式,未来一定可以更加的普及,并且发挥更大的价值。其他有好的想法,也欢迎探讨分享。

    华为云地理遥感平台GeoGenius,经过多年的技术项目积累,采用了业界最佳的云原生的遥感影像管理实践,并且提供端到端最优的性能体验,欢迎领域同行了解使用。

    详见:

     

    点击关注,第一时间了解华为云新鲜技术~

  • 相关阅读:
    python 慕名函数
    python 不定长参数
    python 关键字参数
    python 传递参数
    python 函数的返回值
    python 函数的参数
    python 最简单的函数(无参无返回值)
    python 迭代器
    python 迭代器案例
    在 android 上运行 python 的方法
  • 原文地址:https://www.cnblogs.com/huaweiyun/p/15710163.html
Copyright © 2011-2022 走看看