python 脚本在执行过程中停止,没有错误

python script stops in the middle of execution without errors

我有一个使用 python 显示 dfs 的简单脚本,它没有完全执行就停止了

脚本只是输入一个图像,将其转换为只有 2 种颜色的图像(类似于 dfs 的岛屿和水问题)。

它以空白图像(背景)开始,然后显示一个动画,其中岛屿(前景色)一个接一个地变得可见。

它工作到某个点,然后完全停止。我检查了while循环停止时不满足条件

连 atexit 消息都没有打印出来。

这是脚本

import imageFilters as imf
import imutils
import cv2
import numpy as np
import random
import sys
import atexit

sys.setrecursionlimit(1000000000)

atexit.register(print, "exited ")


background = [255, 255, 255] #white
foreground = [0,0,0] #black

img_path = input("ENTER IMAGE PATH:")

img = cv2.imread(img_path)

 #imf.createLineDrawing: resizes with height = 600 and creates an image with only two colors;
img = imf.createLineDrawing(img, foreground, background)
(height, width, channel) = img.shape

blank_image = np.ndarray([height, width, channel], img.dtype)
blank_image.fill(255)

done = np.ndarray([height, width], img.dtype)
countDone = 0

def searchNeighbour(x, y):

    global done,countDone

    done[y, x] = 1
    countDone += 1
    if list(img[y, x]) == foreground:
        blank_image[y, x] = foreground
    else:
        return

    cv2.imshow("o", blank_image)
    cv2.waitKey(1)

    if x - 1 >= 0 and not(done[y, x - 1]):
        searchNeighbour(x - 1, y)
    if x + 1 <= width - 1 and not(done[y, x + 1]):
        searchNeighbour(x + 1, y)
    if y - 1 >= 0 and not(done[y - 1, x]):
        searchNeighbour(x, y - 1)
    if y + 1 <= height - 1 and not(done[y + 1, x]):
        searchNeighbour(x, y + 1)


while countDone < height*width:
    x = random.randrange(0, width - 1)
    y = random.randrange(0, height - 1)
    if not(done[y, x]):
        searchNeighbour(x, y)

把这个贴在某个地方:

import pdb; pdb.set_trace()

然后输入h当它停下来获取指令。你可以逐行逐行找出每一步的值


此外,完成后,也许可以尝试键入 echo $? 以查看它是否因错误而退出。 (如果你使用的是 unixy 的东西) (0 表示事情已经完成,任何其他数字通常表示出现问题)


或者也许只是在项目底部写一行

print("DONE PROGRAM %s" % countDone)

100% 不只是完成循环

我得到了解决方案。这是 python 的主要缺点。 Python 不是函数式语言,因此无法进行大型递归。

实际上默认的递归限制(10000) 不是任意的,而是因为小堆栈大小而设置的。所以即使你增加递归限制,它也会导致堆栈溢出。

但是我使用多线程得到了解决方案;

我只是将它包装在一个函数中,然后 运行 它在另一个线程中增加了堆栈限制;

在 PYTHON

中实现 运行 大递归的步骤
  1. 在代码开头添加以下行
import sys

sys.setrecursionlimit(10**9)
threading.stack_size(10**8)
  1. 将递归函数包装在父函数中

  2. 在代码末尾添加下一行 -

threading.Thread(target=<your_parent_function>).start()

其中 <your_parent_function> 是您的父函数的名称

我的最终代码-

import imageFilters as imf
import cv2
import numpy as np
from random import randrange
import threading
import sys

sys.setrecursionlimit(10**9)
threading.stack_size(10**8)


background = [255, 255, 255]
foreground = [56, 50, 36]

img_path = input("ENTER IMAGE PATH:")

img = cv2.imread(img_path)
img = imf.createLineDrawing(img, foreground, background)
(height, width, channel) = img.shape

blank_image = np.ndarray([height, width, channel], img.dtype)
blank_image.fill(255)

done = np.ndarray([height, width], img.dtype)
countDone = 0


def searchNeighbour(x, y):

    global done, countDone
    print(countDone)
    countDone += 1
    done[y, x] = 1

    if list(img[y, x]) == foreground:
        blank_image[y, x] = foreground
    else:
        print("returning")
        return 0

    cv2.imshow("O", blank_image)
    cv2.waitKey(1)

    if x - 1 >= 0 and not(done[y, x - 1]):
        searchNeighbour(x - 1, y)
    if x + 1 <= width - 1 and not(done[y, x + 1]):
        searchNeighbour(x + 1, y)
    if y - 1 >= 0 and not(done[y - 1, x]):
        searchNeighbour(x, y - 1)
    if y + 1 <= height - 1 and not(done[y + 1, x]):
        searchNeighbour(x, y + 1)


def showAllForegrounds():
    while countDone < height*width:
        x = randrange(0, width - 1)
        y = randrange(0, height - 1)
        if not(done[y, x]):
            searchNeighbour(x, y)


threading.Thread(target=showAllForegrounds).start()

print("DONE PROGRAM %s" % countDone)