使用cartopy和pyresample投影卫星图像的区别
我写了一个Python脚本,用来处理和叠加来自邓迪大学的静止卫星图像,这样生成的图像可以用来让xplanet渲染地球表面。这个工具的源代码可以在这里找到:https://github.com/jmozmoz/cloudmap/tree/cartopy(这是支持cartopy的分支)
这个工具支持两种不同的Python库来将静止图像投影到平面地图上:pyresample和cartopy。
我发现了以下几个不同之处和问题:
- pyresample的速度比cartopy快很多(根据输出图像的大小,快的可以达到10倍)
- 输出的图像效果不同:使用pyresample的结果对比度更强。具体例子可以查看调试目录:https://github.com/jmozmoz/cloudmap/tree/cartopy/debug
如果使用多进程库来并行处理投影,cartopy版本会崩溃,并显示以下错误信息:
Fatal Python error: PyEval_RestoreThread: NULL tstate
那么,为什么cartopy会这么慢呢?是pyresample在用C语言做处理吗?cartopy应该支持多进程吗?还有,怎么解决对比度的问题?
谢谢你的帮助!
1 个回答
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的一个bug,或者更可能的是遇到了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')
最终得到的图像看起来大概是这样的:
这个功能有很多优化的可能性——创建kdtree的过程需要做大量的工作(可以考虑缓存),而从原始图像计算索引又是另一大块工作(同样可以很好地缓存),这基本上可以将重复的重投影问题简化为numpy索引问题。
如果你想研究性能优化或对比度问题(我不确定我的解决方案是否能解决这个问题),欢迎在github仓库上提个问题,我们可以讨论一些选项。
谢谢你的提问,希望对你有帮助!