我试图从数据集中分离沿海网格。我能够通过单独检查陆地网格的每个邻居来做到这一点,如果8个邻居中的一个是海洋网格,那么我将保存网格。这是我写的功能:
def coastalGrids(ds):
grid=~out[0,:,:].mask #out is a 3D masked array (time,lat,lon)
#At each grid where there is land, check all its 8 neighbors,
#and if any of them are ocean, save the grid to the dataset
coastline=np.zeros(grid.shape, dtype=bool)
for i in range(1,len(lat)-1):
for j in range(1,len(lon)-1):
if grid[i,j]==True:
if (grid[i+1,j+1]!=True):
coastline[i,j]= grid[i,j]
elif (grid[i+1,j]!=True):
coastline[i,j]= grid[i,j]
elif (grid[i+1,j-1]!=True):
coastline[i,j]= grid[i,j]
elif (grid[i,j+1]!=True):
coastline[i,j]= grid[i,j]
elif (grid[i,j-1]!=True):
coastline[i,j]= grid[i,j]
elif (grid[i-1,j+1]!=True):
coastline[i,j]= grid[i,j]
elif (grid[i-1,j]!=True):
coastline[i,j]= grid[i,j]
elif (grid[i-1,j-1]!=True):
coastline[i,j]= grid[i,j]
return coastline
我想知道是否:
谢谢!
答案 0 :(得分:4)
您目前正在做的是等同于原始布尔数组与其binary erosion之间的差异。
这与morphological gradient密切相关,但定义略有不同。
无论如何,假设我们有一个非常简单的岛屿:
import numpy as np
import matplotlib.pyplot as plt
y, x = np.mgrid[-10:10:20j, -10:10:20j]
land = np.hypot(x, y) < 7
fig, ax = plt.subplots()
ax.pcolormesh(land, cmap='gray', edgecolor='gray', antialiased=True)
plt.show()
我们可以通过侵蚀岛屿来计算海岸线:
import scipy.ndimage
erosion = scipy.ndimage.binary_erosion(land)
然后看看哪里有任何差异:
coast = land != erosion
默认情况下,它使用“方形”连接。换句话说,它不会将对角线视为触摸。默认结构(a.k.a。“footprint”)如下所示:
[[0, 1, 0],
[1, 1, 1],
[0, 1, 0]]
在你的代码中,你假设对角线正在触摸。在这种情况下,您需要“完整”连接,以及看起来像这样的结构:
[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]
为此,我们指定类似于:
的内容erosion = scipy.ndimage.binary_erosion(land, structure=np.ones((3,3)))
作为一个完整的例子:
import numpy as np
import matplotlib.pyplot as plt
import scipy.ndimage
y, x = np.mgrid[-10:10:20j, -10:10:20j]
land = np.hypot(x, y) < 7
erosion = scipy.ndimage.binary_erosion(land, structure=np.ones((3,3)))
coast = land != erosion
fig, ax = plt.subplots()
ax.pcolormesh(coast, cmap='gray', edgecolor='gray', antialiased=True)
plt.show()
您也可以考虑使用形态渐变算子。这是给定输入和连接足迹的二进制扩张和二进制侵蚀之间的差异。
在你的情况下,它还包括与陆地接壤的海洋像素,以及与海洋接壤的陆地像素。实际上,它会给你更厚的边框。
举个例子:
import numpy as np
import matplotlib.pyplot as plt
import scipy.ndimage
y, x = np.mgrid[-10:10:20j, -10:10:20j]
land = np.hypot(x, y) < 7
coast = scipy.ndimage.morphological_gradient(land,
footprint=[[0, 1, 0],
[1, 1, 1],
[0, 1, 0]])
fig, ax = plt.subplots()
ax.pcolormesh(coast, cmap='gray', edgecolor='gray', antialiased=True)
plt.show()
答案 1 :(得分:1)
我不确定scipy的卷积功能,但上面的一个版本是有点terser循环位移索引:
neighbours = [(1,1), (1,0), (1,-1), (0,1),
(0,1), (-1,1), (-1, 0), (-1,-1)]
for i in range(1,len(lat)-1):
for j in range(1,len(lon)-1):
if grid[i,j]==True:
for (di, dj) in neighbours:
if (grid[i+di,j+dj] != True:
coastline[i,j]= grid[i,j]
break