【问题标题】:How to create a thread to take a picture after 3 seconds?如何创建一个线程在 3 秒后拍照?
【发布时间】:2019-09-09 06:52:15
【问题描述】:

我创建了一个类来在 Tkinter 屏幕上显示我的网络摄像头视频,我想在按下 Tkinter 按钮后拍摄 3 张照片(每张照片拍摄后等待 3 秒)。

这是我的代码(简化),我的拍照逻辑已经完成。我应该使用线程来解决这个问题吗?我是 Python 新手。

import tkinter, cv2, time, dlib, numpy as np, time, threading
from PIL import Image, ImageTk

class Tela:
def __init__(self, janela):
    self.janela = janela
    self.janela.title("Reconhecimento Facial")
    self.janela.config(background="#FFFFFF")
    self.image = None

    self.cam = cv2.VideoCapture(0)
    self.detector = dlib.get_frontal_face_detector()

    self.delay = 15
    self.update()
    self.janela.mainloop()

def update(self): # display image on gui
    ret, frame = self.cam.read()
    if ret:
        faces, confianca, idx = self.detector.run(frame)
        for i, face in enumerate(faces):
            e, t, d, b = (int(face.left()), int(face.top()), int(face.right()), int(face.bottom()))
            cv2.rectangle(frame, (e, t), (d, b), (0, 255, 255), 2)
        cv2image = cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
        self.image = Image.fromarray(cv2image)
        imgtk = ImageTk.PhotoImage(image=self.image)
        self.painel.imgtk = imgtk
        self.painel.config(image=imgtk)
        self.janela.after(self.delay, self.update)

def take_picture(self):
    cou = 1  # counter of pictures
    start = time.clock()  # starts the time
    ret, frame = self.cam.read()
    if ret:
        faces, confianca, idx = self.detector.run(frame)
        secs = (time.clock() - start)  # count seconds
        for i, face in enumerate(faces):
            e, t, d, b = (int(face.left()), int(face.top()), int(face.right()), int(face.bottom()))
            cv2.rectangle(frame, (e, t), (d, b), (0, 255, 255), 2)
            if secs > 3:
                imgfinal = cv2.resize(frame, (750, 600))
                cv2.imwrite("fotos/pessoa." + str(id[0][0]) + "." + str(cou) + ".jpg", imgfinal)
                print("Foto " + str(cou) + " tirada")
                cou += 1
                start = time.clock()  # reset the counter of seconds
        if cou > 3:
            # here is where the thread should stop


     # Creates the window
     Tela(tkinter.Tk())

【问题讨论】:

    标签: python multithreading opencv tkinter


    【解决方案1】:

    使用time.sleep()冻结您的 gui,使用 tkinter 您可以使用after(),它将在 x 秒后调用您的方法,下面是如何每 2 次调用 4 次函数的示例秒,你可以在你的应用程序中使用这个想法

    import tkinter as tk
    
    class App():
        def __init__(self):
            self.root = tk.Tk()
            self.label = tk.Label(text="Anything")
            self.label.pack()
    
            self.counter = 0
            self.take_picture(repeates=4, seconds=2)  # our desired function
    
            self.root.mainloop()
    
    
        def take_picture(self, repeates=0, seconds=1):
            if repeates:
                self.counter = repeates
    
            if self.counter == 0:
                print('no more execution')
                self.label.configure(text='Done, no more execution')
                return
    
            # doing stuff    
            text = f'function counting down # {self.counter}'
            self.label.configure(text=text)
    
            # schedule another call to this func using after()
            self.root.after(seconds * 1000, self.take_picture, 0, seconds)
            self.counter -= 1  # our tracker
    
    app=App()
    

    感谢this answer

    【讨论】:

      【解决方案2】:

      您应该使用time.sleep()。它接受一个整数作为参数并等待那么多秒,然后代码继续运行。

      【讨论】:

      • 我尝试在我的 take_picture 方法中使用 time.sleep,但屏幕冻结了。
      • 那么它是完全卡住还是在三秒钟后继续工作?
      • 三秒后继续工作。我应该为这个任务调用一个线程吗?如果是这样,我该怎么做?
      • 我认为time.sleep() 足以增加延迟。
      • time.sleep() 函数正在停止整个程序。我会尝试使用 2 个线程。一个用于更新屏幕,另一个用于拍照
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-03
      • 1970-01-01
      相关资源
      最近更新 更多