我有一个 ndarray,其中每个单元格要么是陆地(1),要么是水(0)。在这个ndarray中,背景和边界都是陆地(1),里面有湖泊。其中一些湖泊内有岛屿。 在这里,岛屿是完全包含在水中的一些相连的陆地像素。是否有一种算法可以用来自动将任何岛屿的值更改为“0”,以便所有岛屿都完全被水填满,同时忽略背景未包含的土地?
到目前为止,我已经尝试了一些基于 dfs 的方法,但我的递归非常生疏。我编写了一些代码,试图将像素分类为岛屿或非岛屿。它通过递归地迭代陆地像素直到确认它们完全被水包围来实现这一点,然后递归展开并理想地为每个岛屿陆地像素产生“True”。我认为问题在于我的基本案例是错误的。我认为问题出在“#已访问过并且土地是否返回true”步骤中。我的愿景是,一旦我们到达一个岛屿,当且仅当最后一个检查的单元格完全被水包围并且已经访问过陆地时,源自第一个岛屿像素的递归迭代才会导致“内部”分类。我还想让边界上的任何陆地单元自动返回 false,因为我不关心延伸到屏幕外的岛屿。 代码如下:
#1是水,0是陆地 def isInside(img,x,y): #img[:][:][1] 是一个与 img 大小相同的数组,其中 0 未访问,1 已访问 暗淡 = img[:,:,0].shape
#if its outside the border, return false
if(x<0 or x>=dim[1] or y<0 or y>=dim[0]):
return False
#has been visisted and is land returns true
if(img[y][x][1] == 1 and img[y][x][0] == 0):
return True
#is water is true
if (img[y][x][0] == 1):
#mark visisted
img[y][x][1] = 1
return True
#if its land and on the border return false
if ((x==0 or x == dim[1]-1 or y == 0 or y == dim[0]-1) and (img[y][x][0] == 0)):
img[y][x][1] = 1
return False
#is land and unvisited
if img[y][x][0] == 0:
#mark visited
img[y][x][1] = 1
#if all adjacent nodes are water or also inside land, return true
if(isInside(img,x+1,y) and
isInside(img,x-1,y) and
isInside(img,x,y+1) and
isInside(img,x,y-1)):
return True
return False
我使用了一些我制作的人工阵列,以及我实际的哨兵图像本身,但是,结果很不稳定。非常感谢任何帮助。
Copy input array to output array
Loop P over all land pixels
If there is a path from P to the border stepping over ONLY land pixels
// P is part of the land
continue to next land pixel
else
// P is an island
set pixel in output array to 0