cartopy:在NOAA APT图像上叠加地图

时间:2018-06-16 12:02:04

标签: matplotlib-basemap cartopy noaa

我正在研究一个试图解码NOAA APT图像的项目,到目前为止,我已经到了可以从RTLSDR的原始IQ记录中获取图像的阶段。这是解码图像之一, Decoded NOAA APT image此图片将用作代码的输入(此处显示为m3.png)

现在我正在研究在图像上叠加地图边界(注意:仅在上图的左半部分)

我们知道,拍摄图像的时间和卫星信息:位置,方向等因此,我使用卫星的位置来获取地图投影的中心和卫星的方向以适当地旋转图像

首先我在Basemap中尝试过,这是代码

import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
import numpy as np
from scipy import ndimage

im = plt.imread('m3.png')
im = im[:,85:995] # crop only the first part of whole image

rot = 198.3913296679117 # degrees, direction of sat movement
center = (50.83550180700588, 16.430852851867176) # lat long

rotated_img = ndimage.rotate(im, rot) # rotate image

w = rotated_img.shape[1]*4000*0.81 # in meters, spec says 4km per pixel, but I had to make it 81% less to get better image
h = rotated_img.shape[0]*4000*0.81 # in meters, spec says 4km per pixel, but I had to make it 81% less to get better image

m = Basemap(projection='cass',lon_0 = center[1],lat_0 = center[0],width = w,height = h, resolution = "i")
m.drawcoastlines(color='yellow')
m.drawcountries(color='yellow')

im = plt.imshow(rotated_img, cmap='gray', extent=(*plt.xlim(), *plt.ylim()))
plt.show()

结果我得到了this image,这似乎很不错

我想将代码移到Cartopy,因为它更容易安装并且正在积极开发。我无法找到类似的方法来设置边界,即以米为单位的宽度和高度。所以,我修改了most similar example。我发现了一个函数,它可以为长度和拉特添加米,并用它来设置边界。

以下是Cartopy中的代码,

import matplotlib.pyplot as plt
import numpy as np
import cartopy.crs as ccrs
from scipy import ndimage
import cartopy.feature

im = plt.imread('m3.png')
im = im[:,85:995] # crop only the first part of whole image

rot = 198.3913296679117 # degrees, direction of sat movement
center = (50.83550180700588, 16.430852851867176) # lat long

def add_m(center, dx, dy):
    # source: https://stackoverflow.com/questions/7477003/calculating-new-longitude-latitude-from-old-n-meters
    new_latitude  = center[0] + (dy / 6371000.0) * (180 / np.pi)
    new_longitude = center[1] + (dx / 6371000.0) * (180 / np.pi) / np.cos(center[0] * np.pi/180)
    return [new_latitude, new_longitude]

fig = plt.figure()

img = ndimage.rotate(im, rot)

dx = img.shape[0]*4000/2*0.81 # in meters
dy = img.shape[1]*4000/2*0.81 # in meters

leftbot = add_m(center, -1*dx, -1*dy)
righttop = add_m(center, dx, dy)

img_extent = (leftbot[1], righttop[1], leftbot[0], righttop[0])

ax = plt.axes(projection=ccrs.PlateCarree())
ax.imshow(img, origin='upper', cmap='gray', extent=img_extent, transform=ccrs.PlateCarree())
ax.coastlines(resolution='50m', color='yellow', linewidth=1)
ax.add_feature(cartopy.feature.BORDERS, linestyle='-', edgecolor='yellow')

plt.show()
来自Cartopy的

Here is the result,它不如Basemap的结果好。

我有以下问题:

  1. 我发现无法旋转地图而不是图像 底图和图表。因此,我使用旋转图像,是 有办法旋转地图吗?
  2. 如何提高纸箱的产量?我认为这是方式 我正在计算一个问题的程度。我有办法吗?     提供米来设置图像的边界?
  3. 有没有更好的方法来做我想做的事情?任何特定于这类应用的投影?
  4. 我正在手动调整比例(我决定每像素的kms数的部分),有没有办法做到这一点     上             卫星的高度?
  5. 任何形式的输入都将受到高度赞赏。非常感谢你的时间!

    如果您有兴趣,可以找到项目here

1 个答案:

答案 0 :(得分:2)

据我所知,底层Proj.4无法定义具有旋转视角的卫星投影(很高兴以其他方式显示 - 我没有专家!)(注意:也许是通过{{ 1}}?)。这是你在" native"中做到这一点的主要原因。坐标/方向与底图或手抄本。

这个问题实际上归结为地理配准问题,我无法在https://www.cder.dz/download/Art7-1_1.pdf这样的地方找到足够的信息。

我的解决方案完全是一种软糖,但确实让你非常接近引用这个图像。我将软糖因子翻倍,实际上是通用的,如果你想编写通用代码,这有点问题。

我必须做出的一些捏造(反复试验):

  • 将卫星方位调整3.2度
  • 通过沿着卫星轨迹移动10km
  • 来调整图像中心的位置
  • 通过沿着卫星轨迹垂直移动10km
  • 来调整图像中心的位置
  • 将x和y像素大小分别缩放0.62和0.65
  • 使用"近侧视角"投射在一个不切实际的satellite_height

结果似乎是一张相对良好的注册图像,但正如我所说,似乎不太适用于所有收到的图像:

Registered image

生成此图像的代码(相当复杂但完整):

ob_tran

正如你可能会说的那样,我对这个问题感到有点担忧。这是一个非常有趣的问题,但实际上并不是真正的一个载体/底图。

希望有所帮助!