使用 cartopy 和 Pyresample 投影卫星图像的差异

jhe*_*erb 3 python matplotlib cartopy pyresample

我编写了一个 python 脚本来投影和覆盖邓迪大学的对地静止卫星图像,因此生成的图像可用于 xplanet 渲染地球表面。该工具的源代码可以在https://github.com/jmozmoz/cloudmap/tree/cartopy找到(这是支持cartopy的分支)

该工具支持两个不同的 python 库将地球静止图像投影到平面地图上:pyresample 和 cartopy。

我发现以下差异/问题:

  1. pyresample 比 cartopy 快得多(取决于输出图像的大小,最多可达 10 倍)
  2. 输出图像不同:使用pyresample 的结果显示出更强的对比度。有关示例,请参阅调试目录https://github.com/jmozmoz/cloudmap/tree/cartopy/debug
  3. 如果使用多处理库并行进行投影,则 cartopy 版本会崩溃并显示以下错误消息:

    Fatal Python error: PyEval_RestoreThread: NULL tstate
    
    Run Code Online (Sandbox Code Playgroud)

那么为什么 cartopy 这么慢呢?Pyresample 是用 C 代码完成这项工作吗?cartopy 应该支持多处理吗?如何解决对比度问题?

感谢您的帮助

pel*_*son 5

1.pyresample比cartopy快得多(取决于输出图像的大小,最多可达10倍)

cartopy 重投影功能尚未以任何方式进行优化,尽管它在底层使用 scipy ckdtree 功能,但算法本身是用 Python 编写的。我似乎记得一个快速的胜利是使用https://pypi.python.org/pypi/kdtree,从记忆中它给出了相当合理的加速,几乎不需要做任何工作,这cartopy.img_transform将是需要更改的地方。

Cartopy 的重投影功能可能也付出了非常通用的代价——您可以在任何投影中提供图像,它会将其放入任何其他投影中,毫无问题地处理不连续性和撕裂。不过,如果能够连接到pyresample的功能(以及GDAL的功能),让用户有机会在某些情况下加速重新投影,那就真的很酷了。

2. 输出图像不同:使用pyresample的结果显示出更强的对比度。

看起来您正在创建一个 matplotlib 图来重新采样图像并使用 mpl 的 savefig 功能。此过程可能会导致对比度丢失。我建议只使用 cartopy 的重投影功能,而不将图像添加到图形并保存图形(最后的示例)。

3. 如果使用多处理库并行进行投影,cartopy 版本会崩溃并显示以下错误消息:

这真的让我感到惊讶,因为 cartopy 中没有 C 代码来进行重新投影。因此,您要么发现了 scipy 的错误,要么更有可能遇到了 numpy/matplotlib 的问题(谷歌会显示一些带有异常和 matplotlib 和/或 numpy 的结果,例如https://github.com/numpy /numpy/issues/1270)。

好的,下面是我在不使用 matplotlib 的情况下进行重投影的方法:

import cartopy.crs as ccrs
from cartopy.img_transform import warp_array
import numpy as np    
import PIL.Image


# I've downloaded the file from https://github.com/jmozmoz/cloudmap/blob/78923d15ad906eaa6d1dcab168a6364643d3fc94/debug/2014_8_7_1800_GOES15_4_S1.jpeg
# and clipped the image. 
fname = '2014_8_7_1800_GOES15_4_S1.jpeg'
img = PIL.Image.open(fname)

result_array, extent = warp_array(np.array(img),
                                  source_proj=ccrs.Geostationary(),
                                  target_proj=ccrs.PlateCarree(),
                                  target_res=(4000, 2000))

result = PIL.Image.fromarray(result_array)
result.save('reprojected.jpeg')
Run Code Online (Sandbox Code Playgroud)

生成的图像(最终)看起来像这样:

重投影图像

使用此功能进行一些优化确实有可能 - 首先需要完成大量工作来创建 kdtree(可能会被缓存),而另一大部分工作是从原始图像计算索引(再次,缓存非常好),这将从本质上减少和重复对 numpy 索引问题的重新投影。

如果您想研究性能可能性或对比度问题(我不确定我的解决方案是否可以解决),请随时在 github 存储库上提出问题,我们可以讨论一些选项。

感谢您的询问,HTH!