我正在做一个自我调用的函数,但是我遇到了错误:RecursionError:调用Python对象时超出了最大递归深度,有没有办法解决?更具体地说,我在第35行得到它,好了,frame = cap.read() 由于程序中的.after功能,我无法放置while循环。
import cv2
from tkinter import *
import PIL
from PIL import Image, ImageTk
root = Tk()
root.bind('<Escape>', lambda e: root.quit())
lmain = Label(root)
lmain.pack()
print("[INFO] Making variables")
ImageSource = 0
window_name = "AutoCam"
width = 600
height = 800
cap = cv2.VideoCapture(ImageSource)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
print("[INFO] Made variables ")
def ShowFrame(frame):
print("[INFO] making image.")
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = PIL.Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
print("[INFO] After 10 initializing")
lmain.after(10, CheckSource)
print("[INFO] Showed image")
def CheckSource():
ok, frame = cap.read()
if ok:
print("[INFO] Ok is triggered")
if cv2.waitKey(1) & 0xFF == ord('q'):
cv2.destroyAllWindows()
cv2.waitKey(0)
print("[INFO] Exiting app after command")
ShowFrame(frame)
else:
lmain.after(10, CheckSource())
CheckSource()
root.mainloop()
任何人和所有帮助将不胜感激。 有人还能解释一下如何避免这种情况以备将来使用吗?
[编辑]
the error message is:
Traceback (most recent call last):
File "C:/Users/Gotta/Documents/AutoCamPy.py", line 52, in <module>
CheckSource()
File "C:/Users/Gotta/Documents/AutoCamPy.py", line 49, in CheckSource
lmain.after(10, CheckSource())
File "C:/Users/Gotta/Documents/AutoCamPy.py", line 49, in CheckSource
lmain.after(10, CheckSource())
File "C:/Users/Gotta/Documents/AutoCamPy.py", line 49, in CheckSource
lmain.after(10, CheckSource())
[Previous line repeated 995 more times]
File "C:/Users/Gotta/Documents/AutoCamPy.py", line 35, in CheckSource
ok, frame = cap.read()
RecursionError: maximum recursion depth exceeded while calling a Python
object
答案 0 :(得分:1)
要以简单的方式处理此问题,可以编写try / except语句来捕获此错误。直到您确切知道错误是什么,您都可以使用全部捕获,但是我建议您在知道具体错误之后再处理具体错误。
那就是说,我对您的代码进行了一些更改,以对其进行一些清理并更严格地遵循PEP8标准。
您确实应该执行import tkinter as tk
而不是使用*
。这将有助于防止覆盖已导入的方法。
接下来,您的lambda会被杀死,而只需执行root.quit
。我们想保存对命令的引用而不是执行它,我们通过删除括号来做到这一点。您的after after语句存在相同的问题。
最后,您导入PIL
,然后专门从PIL导入。您不需要两者都做。如果您只需要Image
和ImageTk
,则只需执行from PIL import Image, ImageTk
,如果您需要PIL的许多功能,则可以简单地执行import PIL
并使用PIL.
前缀从那里。
这是带有try / except语句的清理代码。如果您有任何问题,请告诉我。
import tkinter as tk
from PIL import Image, ImageTk
import cv2
root = tk.Tk()
root.bind('<Escape>', root.quit)
lmain = tk.Label(root)
lmain.pack()
ImageSource = 0
window_name = "AutoCam"
width = 600
height = 800
cap = cv2.VideoCapture(ImageSource)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
def show_frame(frame):
cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
img = Image.fromarray(cv2image)
imgtk = ImageTk.PhotoImage(image=img)
lmain.imgtk = imgtk
lmain.configure(image=imgtk)
lmain.after(10, check_source)
def check_source():
try:
ok, frame = cap.read()
if ok:
if cv2.waitKey(1) & 0xFF == ord('q'):
cv2.destroyAllWindows()
cv2.waitKey(0)
show_frame(frame)
else:
lmain.after(10, check_source)
except:
print('Connection failed for some reason!')
check_source()
root.mainloop()
答案 1 :(得分:1)
通过堆栈跟踪,您可以确定递归发生在第49行(该行已执行多次)
File "C:/Users/Gotta/Documents/AutoCamPy.py", line 49, in CheckSource
lmain.after(10, CheckSource())
File "C:/Users/Gotta/Documents/AutoCamPy.py", line 49, in CheckSource
lmain.after(10, CheckSource())
File "C:/Users/Gotta/Documents/AutoCamPy.py", line 49, in CheckSource
lmain.after(10, CheckSource())
[Previous line repeated 995 more times]
它达到递归限制的原因是因为.after
函数(https://effbot.org/tkinterbook/widget.htm#Tkinter.Widget.after-method)希望将回调函数作为第二个参数,但是您正在传递结果而是调用CheckSource
。您应该传递CheckSource
而不是CheckSource()
作为第二个参数:
lmain.after(10, CheckSource)