首页 > 解决方案 > python得到分段错误:OS 10.13上的11

问题描述

Segmentation fault: 11我的 Mac 10.13.6 出现错误

我正在使用 Python 3.6.5 Anaconda 运行 virtualenv

我正在运行像素洪水填充脚本

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

有什么建议么?

标签: python-3.xmacossegmentation-faultvirtualenv

解决方案


我认为问题在于您的代码在没有前一个函数结束的情况下递归调用自身,导致在堆栈上的函数副本数量增加,直到内存不足(这会触发分段错误)。每次 Python 调用一个新函数并将其放入堆栈时,都会创建一个堆栈帧,它会占用一些内存,即使您没有在该函数调用中创建任何新对象。当函数返回时,python 中的垃圾收集器会释放内存,但如果您的图像中有很多带有 value 的值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)

在此处输入图像描述


推荐阅读