python получает ошибку сегментации: 11 на ОС 10.13 - PullRequest
0 голосов
/ 26 октября 2018

Я получаю Segmentation fault: 11 ошибку на моем компьютере Mac*

img = cv2.imread(image,1)
surface = cv2.Canny(img,100,200)

def floodfill(x, y, oldColor, newColor):

    # assume surface is a 2D image and surface[x][y] is the color at x, y.

    if surface[x][y] != oldColor: # the base case

        return

    surface[x][y] = newColor

    floodfill(x + 1, y, oldColor, newColor) # right

    floodfill(x - 1, y, oldColor, newColor) # left

    floodfill(x, y + 1, oldColor, newColor) # down

    floodfill(x, y - 1, oldColor, newColor) # up

floodfill(0, 0, 0, 100)
plt.imshow(edges, cmap='gray')
plt.show()

есть предложения?

Ответы [ 2 ]

0 голосов
/ 29 октября 2018

Вот вариант, как сделать то же самое без рекурсии для всех, кто заинтересован. от http://inventwithpython.com/blog/2011/08/11/recursion-explained-with-the-flood-fill-algorithm-and-zombies-and-cats/

def floodfill(x, y, oldColor, newColor):

    # assume surface is a 2D image and surface[x][y] is the color at x, y.

    theStack = [ (x, y) ]
    while (len(theStack) > 0):

        x, y = theStack.pop()

        if (x == 224):
            continue
        if (x == -1):
            continue
        if (y == -1):
            continue
        if (y == 224):
            continue


        if edges[x][y] != oldColor:
            continue

        edges[x][y] = newColor


        theStack.append( (x + 1, y) )  # right
        theStack.append( (x - 1, y) )  # left
        theStack.append( (x, y + 1) )  # down
        theStack.append( (x, y - 1) )  # up
0 голосов
/ 26 октября 2018

Я думаю, что проблема в том, что ваш код рекурсивно вызывает себя без завершения предыдущей функции, что приводит к увеличению количества копий вашей функции, находящихся в стеке, до тех пор, пока у вас не закончится память (что вызывает ошибку сегментации).Каждый раз, когда 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)

enter image description here

...