使用卷积窗口(python)隔离海岸网格
我正在尝试从数据集中隔离海岸网格。我可以通过单独检查陆地网格的每个邻居来完成,如果8个邻居中有一个是海洋网格,那么我正在保存网格。以下是我编写的函数:使用卷积窗口(python)隔离海岸网格,python,numpy,image-processing,scipy,Python,Numpy,Image Processing,Scipy,我正在尝试从数据集中隔离海岸网格。我可以通过单独检查陆地网格的每个邻居来完成,如果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 o
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
我想知道:
谢谢 我不确定scipy的卷积功能,但上面的一个版本更简洁,它可以循环置换索引:
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
我不确定scipy的卷积功能,但上面的一个版本更简洁一些,就是循环置换索引:
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
使用图像形态学算子
您当前所做的操作相当于原始布尔数组与其属性之间的差异
这与定义密切相关,但定义略有不同
无论如何,假设我们有一个非常简单的岛:
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()
然后看看有什么不同:
coast = land != erosion
正方形与对角连通性 默认情况下,这使用“方形”连接。换句话说,对角线不算是接触。默认结构(也称为“footprint”)如下所示:
[[0, 1, 0],
[1, 1, 1],
[0, 1, 0]]
[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]
在您的代码中,假设对角线相接触。在这种情况下,您需要“完全”连接,并且结构如下所示:
[[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()
将numpy导入为np
将matplotlib.pyplot作为plt导入
导入scipy.ndimage
y、 x=np.mgrid[-10:10:20j,-10:10:20j]
陆面=np.hypot(x,y)<7
侵蚀=scipy.ndimage.binary_侵蚀(土地,结构=np.one((3,3)))
海岸=陆地!=腐蚀
图,ax=plt.子批次()
ax.pcolormesh(coast,cmap='gray',edgecolor='gray',抗锯齿=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()
将numpy导入为np
将matplotlib.pyplot作为plt导入
导入scipy.ndimage
y、 x=np.mgrid[-10:10:20j,-10:10:20j]
陆面=np.hypot(x,y)<7
海岸=scipy.ndimage.形态梯度(陆地,
footprint=[[0,1,0],
[1, 1, 1],
[0, 1, 0]])
图,ax=plt.子批次()
ax.pcolormesh(coast,cmap='gray',edgecolor='gray',抗锯齿=True)
plt.show()
使用图像形态学操作符
您当前所做的操作相当于原始布尔数组与其属性之间的差异
这与定义密切相关,但定义略有不同
无论如何,假设我们有一个非常简单的岛:
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()
然后看看有什么不同:
coast = land != erosion
正方形与对角连通性 默认情况下,这使用“方形”连接。换句话说,对角线不算是接触。默认结构(也称为“footprint”)如下所示:
[[0, 1, 0],
[1, 1, 1],
[0, 1, 0]]
[[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]
在您的代码中,假设对角线相接触。在这种情况下,您需要“完全”连接,并且结构如下所示:
[[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()
将numpy导入为np
将matplotlib.pyplot作为plt导入
导入scipy.ndimage
y、 x=np.mgrid[-10:10:20j,-10:10:20j]
陆面=np.hypot(x,y)<7
侵蚀=scipy.ndimage.binary_侵蚀(土地,结构=np.one((3,3)))
海岸=陆地!=腐蚀
图,ax=plt.子批次()
ax.pcolormesh(coast,cmap='gray',edgecolor='gray',抗锯齿=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()
将numpy导入为np
将matplotlib.pyplot作为plt导入
导入scipy.ndimage
y、 x=np.mgrid[-10:10:20j,-10:10:20j]
陆面=np.hypot(x,y)<7
海岸=scipy.ndimage.形态梯度(陆地,
footprint=[[0,1,0],
[1, 1, 1],
[0, 1, 0]])
图,ax=plt.子批次()
ax.pcolormesh(coast,cmap='gray',edgecolor='gray',抗锯齿=True)
plt.show()
谢谢你,乔,不仅为我的问题提供了完美的解决方案,而且还为我介绍了数学形态学这一领域。增加scipy.ndimage.binary_corporation()函数中的“structure”窗口,也解决了我的第二个问题(将内陆网格与海岸线隔离到一定半径)!谢谢你,乔,不仅为我的问题提供了一个完美的解决方案,而且还为我介绍了数学形态学这个领域。增加scipy.ndimage.binary_corporation()函数中的“structure”窗口,也解决了我的第二个问题(将内陆网格与海岸线隔离到一定半径)!