Skip to main content
 首页 » 编程设计

python之使用卷积窗口(python)隔离沿海网格

2025年05月04日32over140

我正在尝试从数据集中分离沿海网格。我可以通过单独检查陆地网格的每个邻居来做到这一点,如果 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 

我想知道是否:

  1. 有一种不那么丑陋的方法,比如使用 scipy 的卷积窗口函数?
  2. 扩展这样的功能,有没有一种方法可以将陆地网格与海岸线隔离开 10 个网格?

谢谢!

请您参考如下方法:

使用图像形态学算子

你当前所做的相当于原始 bool 数组与其 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() 

我们可以通过侵 eclipse 岛屿来计算您定义的海岸线:

import scipy.ndimage 
erosion = scipy.ndimage.binary_erosion(land) 

然后看看哪里有什么不同:

coast = land != erosion 


方形与对角线连通性

默认情况下,这使用“方形”连接。换句话说,它不认为对角线是接触的。默认结构(又名“足迹”)如下所示:

[[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() 

使用形态梯度

您也可以考虑使用形态梯度运算符。这是给定输入和连接足迹的二元扩张和二元腐 eclipse 之间的差异。

在您的情况下,它还包括与陆地接壤的海洋像素,以及与海洋接壤的陆地像素。实际上,它会给你更粗的边框。

举个例子:

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()