【问题标题】:Using cv2.VideoCapture() inside a function OpenCV在函数 OpenCV 中使用 cv2.VideoCapture()
【发布时间】:2021-11-13 22:22:37
【问题描述】:

我正在尝试使用 tkinter 和 opencv 制作基于 GUI 的人脸识别程序。我之前使用过函数 cv2.VideoCapture(),但通常不在函数内部并且它成功地工作。

不过,这一次,我想在函数中使用它,但程序就是无法运行。我在终端中没有错误,窗口只是冻结了。

这是我的代码(我还没有添加人脸识别功能)

import tkinter as tk
from PIL import Image, ImageTk

root = tk.Tk()
root.configure(bg='#3d3d3d')
f1 = tk.LabelFrame(root, bg='#3d3d3d')
f1.place(relx=0.5, rely=0.53, anchor=tk.CENTER)
feed = tk.Label(f1)
feed.pack()

cap = cv2.VideoCapture(0)

def capture():    
    while cap.isOpened():
        img = cap.read()[1]  
        img = cv2.flip(img, 1)
        img1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # changing color to RGB
        img = ImageTk.PhotoImage(Image.fromarray(img1)) 
        feed['image'] = img  # putting the webcam feed in the 'feed' LabelFrame

capture()

root.mainloop()

我尝试为 VideoCapture() 函数输入值 0、1、-1,但问题仍然存在

请注意,这不是我的完整代码,我只是包含了重要部分。我问这个问题是因为我想在通过单击按钮打开的 Toplevel() 窗口上实现此功能。 Toplevel() 窗口的代码位于函数内部。

提前致谢!

【问题讨论】:

  • 另一个问题是您使用了 while 循环,这将阻止 root.mainloop() 执行。
  • 我之前已经检查过该链接,但它并没有解决问题
  • 据我测试,问题在于 VideoCapture() 函数而不是 tkinter
  • No feed['image'] 用于更改标签的image 选项,而feed.image = img 使用的是名为“image”的属性 存储图像的参考。正如我所说,root.mainloop() 由于 while 循环而被阻止执行,所以你根本看不到窗口。

标签: python opencv tkinter


【解决方案1】:

你的代码主要有两个问题:

  • 使用 while 循环将阻止 root.mainloop() 执行。请改用after()
  • 如果在函数中创建的图像没有保存其引用,则会被垃圾回收

以下是修复上述问题的修改代码:

import tkinter as tk
from PIL import Image, ImageTk
import cv2

root = tk.Tk()
root.configure(bg='#3d3d3d')
root.geometry('800x600')

f1 = tk.LabelFrame(root, bg='#3d3d3d')
f1.place(relx=0.5, rely=0.53, anchor=tk.CENTER)

feed = tk.Label(f1)
feed.pack()

cap = cv2.VideoCapture(0)

# used after() instead of while loop
def capture():
    if cap.isOpened():
        ret, img = cap.read()
        if ret:
            img = cv2.flip(img, 1)
            img1 = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)  # changing color to RGB
            img = ImageTk.PhotoImage(Image.fromarray(img1))
            feed['image'] = img  # putting the webcam feed in the 'feed' LabelFrame
            feed.image = img # save reference of the image
    root.after(10, capture)

capture()

root.mainloop()

【讨论】:

  • "[...] inside a function will be GC'd" 具有误导性。如果您的意思是说 feed['image'] = img 只会导致 weak 引用,请这么说(“在函数内部”会是一种误导性的解释)。不知道有没有。
  • @Christoph 我有一个 if 条件,但并非总是如此。
  • 你错过了我的意思
  • 嘿!您的解决方案完美运行。非常感谢
猜你喜欢
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-21
  • 2019-06-12
  • 2021-12-20
  • 2013-03-05
  • 1970-01-01
相关资源
最近更新 更多