人脸检测OpenCV Python GUI

时间:2016-11-22 17:00:02

标签: python windows user-interface opencv tkinter

我是Python GUI世界的新手。我正在开发一个Python项目来检测网络摄像头中的面部并拍摄面部照片,该部分已经设置好。我一直在搜索和测试GUI部分的代码,我尝试使用PyQt和PySide,但我没有成功。我在PyImageSearch找到了Adrian的代码,它有一个用于摄像头的框架和一个用于捕获图像的按钮,并使用Tkinter作为GUI。

from __future__ import print_function
from PIL import Image
from PIL import ImageTk
import Tkinter as tki
import threading
import datetime
import imutils
import cv2
import os

class PhotoBoothApp:
  def __init__(self, vs, outputPath):
    # store the video stream object and output path, then initialize
    # the most recently read frame, thread for reading frames, and
    # the thread stop event
    self.vs = vs
    self.outputPath = outputPath
    self.frame = None
    self.thread = None
    self.stopEvent = None

    # initialize the root window and image panel
    self.root = tki.Tk()
    self.panel = None

    # create a button, that when pressed, will take the current
    # frame and save it to file
    btn = tki.Button(self.root, text="Snapshot!",
        command=self.takeSnapshot)
    btn.pack(side="bottom", fill="both", expand="yes", padx=10,
        pady=10)

    # start a thread that constantly pools the video sensor for
    # the most recently read frame
    self.stopEvent = threading.Event()
    self.thread = threading.Thread(target=self.videoLoop, args=())
    self.thread.start()

    # set a callback to handle when the window is closed
    self.root.wm_title("PyImageSearch PhotoBooth")
    self.root.wm_protocol("WM_DELETE_WINDOW", self.onClose)

  def videoLoop(self):
    # DISCLAIMER:
    # I'm not a GUI developer, nor do I even pretend to be. This
    # try/except statement is a pretty ugly hack to get around
    # a RunTime error that Tkinter throws due to threading
    try:
        # keep looping over frames until we are instructed to stop
        while not self.stopEvent.is_set():
            # grab the frame from the video stream and resize it to
            # have a maximum width of 300 pixels
            self.frame = self.vs.read()
            self.frame = imutils.resize(self.frame, width=300)

            # OpenCV represents images in BGR order; however PIL
            # represents images in RGB order, so we need to swap
            # the channels, then convert to PIL and ImageTk format
            image = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)
            image = Image.fromarray(image)
            image = ImageTk.PhotoImage(image)

            # if the panel is not None, we need to initialize it
            if self.panel is None:
                self.panel = tki.Label(image=image)
                self.panel.image = image
                self.panel.pack(side="left", padx=10, pady=10)

            # otherwise, simply update the panel
            else:
                self.panel.configure(image=image)
                self.panel.image = image

    except RuntimeError, e:
        print("[INFO] caught a RuntimeError")

  def takeSnapshot(self):
    # grab the current timestamp and use it to construct the
    # output path
    ts = datetime.datetime.now()
    filename = "{}.jpg".format(ts.strftime("%Y-%m-%d_%H-%M-%S"))
    p = os.path.sep.join((self.outputPath, filename))

    # save the file
    cv2.imwrite(p, self.frame.copy())
    print("[INFO] saved {}".format(filename))

  def onClose(self):
    # set the stop event, cleanup the camera, and allow the rest of
    # the quit process to continue
    print("[INFO] closing...")
    self.stopEvent.set()
    self.vs.stop()
    self.root.quit()

现在检测面的部分我认为它应该放在videoLoop函数中,我添加了面部检测代码,所以函数看起来像这样

try:
        # keep looping over frames until we are instructed to stop
        while not self.stopEvent.is_set():
            # grab the frame from the video stream and resize it to
            # have a maximum width of 300 pixels
            self.frame = self.vs.read()
            self.frame = imutils.resize(self.frame, width=300)

            # OpenCV represents images in BGR order; however PIL
            # represents images in RGB order, so we need to swap
            # the channels, then convert to PIL and ImageTk format
            detector = cv2.CascadeClassifier("C:\Proyectos\Python\GUI\tkinter-photo-booth\haarcascade_frontalface_default.xml")
            image = cv2.cvtColor(self.frame, cv2.COLOR_BGR2RGB)


            # load the cat detector Haar cascade, then detect cat faces
            # in the input image

            rects = detector.detectMultiScale(image, scaleFactor=1.5,
                minNeighbors=5, minSize=(30, 30))
            # loop over the cat faces and draw a rectangle surrounding each
            for (i, (x, y, w, h)) in rects:
                cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
            image = Image.fromarray(image)
            image = ImageTk.PhotoImage(image)

            # if the panel is not None, we need to initialize it
            if self.panel is None:
                self.panel = tki.Label(image=image)
                self.panel.image = image
                self.panel.pack(side="left", padx=10, pady=10)

            # otherwise, simply update the panel
            else:
                self.panel.configure(image=image)
                self.panel.image = image

但是当我运行代码时,框架面部的矩形不会出现。我真的不知道检测面的代码是应该进入voidLoop函数还是应该进入快照函数。我已经在他的网页上问过Adrian,但我正在寻找额外的帮助。提前致谢

0 个答案:

没有答案