Я думаю, что проблема в том, что ваш код рекурсивно вызывает себя без завершения предыдущей функции, что приводит к увеличению количества копий вашей функции, находящихся в стеке, до тех пор, пока у вас не закончится память (что вызывает ошибку сегментации).Каждый раз, когда Python вызывает новую функцию и помещает ее в стек, создается кадр стека, который занимает немного памяти, даже если вы не создаете никаких новых объектов в рамках вызова этой функции.Когда функция возвращается, сборщик мусора в python освобождает память, но если в вашем изображении много значений со значением 0
, то вы можете получить много копий floodfill
, работающих одновременно,Это немного старый и очень глубокий и технический материал, но если вы хотите узнать больше, , это хорошее обсуждение .
Чтобы увидеть альтернативный подход к решению проблемы с использованием списковактивные узлы, посмотрите здесь:
https://rosettacode.org/wiki/Bitmap/Flood_fill#Python
Кроме того, у вас есть другая проблема, которая может быть преднамеренной, в том смысле, что ваш код рассматривает изображение как сферу, в том смысле,что, когда он попадает на границу, он переходит на другую сторону изображения и заполняет там тоже.Это потому, что python поддерживает отрицательные индексы, поэтому, когда x=0
и вы переходите к x-1
, вы смотрите на индекс -1
, который является последним индексом в массиве.Чтобы решить эту проблему, вы можете добавить несколько проверок:
if x > 0: # left
floodfill(x - 1, y, oldColor, newColor) # left
if y > 0: # up
floodfill(x, y - 1, oldColor, newColor) # up
if x < surface.shape[0] - 1: # right
floodfill(x + 1, y, oldColor, newColor) # right
if y < surface.shape[1] - 1: # down
floodfill(x, y + 1, oldColor, newColor) # down
Ваш код в целом работает нормально.Если вы попробуете это на маленьком игрушечном примере, вы можете увидеть его в действии (это с исправлением выше):
surface_array = [[0 for i in range (0,10)] for j in range(0,10)]
surface_array[1][1] = 1
surface_array[0][1] = 1
surface_array[2][0] = 1
surface = np.array(surface_array)
print(surface)
floodfill(0, 0, 0, 100)
print(surface)