【问题标题】:Show webcam sequence TkInter显示网络摄像头序列 TkInter
【发布时间】:2013-04-28 07:49:39
【问题描述】:

我用 python 做了一个程序,导入 OpenCV 的库。现在,我在 Tkinter 中做 GUI。我试图在 GUI 中显示网络摄像头,但我做不到。我将代码放在函数中,因为我想通过按钮查看我的网络摄像头。

我的代码是:

def webcam():
   img= cv.QueryFrame(cap)
   cam= PhotoImage(img)
   label1 = Label(root, image=cam)
   label1.image = cam
   label1.pack()
   label1.place(x=0, y=400)

另外,我不知道如何在没有一段时间循环的情况下不断更新,因为我还有另一个按钮可以退出程序。

【问题讨论】:

    标签: python opencv tkinter


    【解决方案1】:

    试试这个代码:

    from collections import deque
    import cv2
    from PIL import Image, ImageTk
    import time
    import Tkinter as tk
    
    def quit_(root):
        root.destroy()
    
    def update_image(image_label, cam):
        (readsuccessful, f) = cam.read()
        gray_im = cv2.cvtColor(f, cv2.COLOR_BGR2GRAY)
        a = Image.fromarray(gray_im)
        b = ImageTk.PhotoImage(image=a)
        image_label.configure(image=b)
        image_label._image_cache = b  # avoid garbage collection
        root.update()
    
    
    def update_fps(fps_label):
        frame_times = fps_label._frame_times
        frame_times.rotate()
        frame_times[0] = time.time()
        sum_of_deltas = frame_times[0] - frame_times[-1]
        count_of_deltas = len(frame_times) - 1
        try:
            fps = int(float(count_of_deltas) / sum_of_deltas)
        except ZeroDivisionError:
            fps = 0
        fps_label.configure(text='FPS: {}'.format(fps))
    
    
    def update_all(root, image_label, cam, fps_label):
        update_image(image_label, cam)
        update_fps(fps_label)
        root.after(20, func=lambda: update_all(root, image_label, cam, fps_label))
    
    
    if __name__ == '__main__':
        root = tk.Tk() 
        image_label = tk.Label(master=root)# label for the video frame
        image_label.pack()
        cam = cv2.VideoCapture(1) 
        fps_label = tk.Label(master=root)# label for fps
        fps_label._frame_times = deque([0]*5)  # arbitrary 5 frame average FPS
        fps_label.pack()
        # quit button
        quit_button = tk.Button(master=root, text='Quit',command=lambda: quit_(root))
        quit_button.pack()
        # setup the update callback
        root.after(0, func=lambda: update_all(root, image_label, cam, fps_label))
        root.mainloop()
    

    【讨论】:

      【解决方案2】:

      使用 OpenCv 和 Tkinter 的简单版本的相机捕获:

      import Tkinter as tk
      import cv2
      from PIL import Image, ImageTk
      
      width, height = 800, 600
      cap = cv2.VideoCapture(0)
      cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
      cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
      
      root = tk.Tk()
      root.bind('<Escape>', lambda e: root.quit())
      lmain = tk.Label(root)
      lmain.pack()
      
      def show_frame():
          _, frame = cap.read()
          frame = cv2.flip(frame, 1)
          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, show_frame)
      
      show_frame()
      root.mainloop()
      

      您需要下载并安装 PIL...

      更新:

      ... 和 OpenCV 一起工作。

      要安装 PIL,请在终端/命令提示符中运行以下命令:

      pip install Pillowpython -m pip install Pillow

      要安装 OpenCV,请在终端/命令提示符中运行以下命令:

      pip install opencv-pythonpython -m pip install opencv-python

      【讨论】:

        【解决方案3】:

        我已经完成并且成功地工作了。 这是Link

        我没有分配按钮来显示框架,但您可以分配一个按钮并运行以获得您的答案。我知道使用全局变量是一种不好的做法,但我仍然在使用它。希望对您有所帮助。

        【讨论】:

          【解决方案4】:

          Kieleth 更新的 py3.7 代码

          import PIL
          from PIL import Image,ImageTk
          import pytesseract
          import cv2
          from tkinter import *
          width, height = 800, 600
          cap = cv2.VideoCapture(0)
          cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
          cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
          
          root = Tk()
          root.bind('<Escape>', lambda e: root.quit())
          lmain = Label(root)
          lmain.pack()
          
          def show_frame():
              _, frame = cap.read()
              frame = cv2.flip(frame, 1)
              cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
              img = PIL.Image.fromarray(cv2image)
              imgtk = ImageTk.PhotoImage(image=img)
              lmain.imgtk = imgtk
              lmain.configure(image=imgtk)
              lmain.after(10, show_frame)
          
          show_frame()
          root.mainloop()
          

          【讨论】:

            【解决方案5】:

            Kieleth 提出的解决方案在 Jupyter 笔记本中对我来说效果很好。 但是,我建议您在主循环之后销毁根并释放上限。 如果不这样做,每次都必须重置内核。

            【讨论】:

              猜你喜欢
              • 2015-06-13
              • 1970-01-01
              • 2020-03-06
              • 2020-10-15
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-12-02
              • 2012-08-08
              相关资源
              最近更新 更多