如何一起打开openCV窗口和tkinter窗口?

时间:2015-12-02 15:56:01

标签: python opencv tkinter

我想通过从openCV窗口移动检测到的面来控制tkinter窗口中的某些内容。对于tkinter窗口,这是我的设置:

def run(width=300, height=300):
    root = Tk()

    def redrawAllWrapper(canvas, data):
        canvas.delete(ALL)
        redrawAll(canvas, data)
        canvas.update()    

    def mousePressedWrapper(event, canvas, data):
        mousePressed(event, data)
        redrawAllWrapper(canvas, data)

    def mouseMovedWrapper(event, canvas, data):
        mouseMoved(event, data)
        redrawAllWrapper(canvas, data)

    def keyPressedWrapper(event, canvas, data):
        keyPressed(event, data)
        redrawAllWrapper(canvas, data)

    def timerFiredWrapper(canvas, data):
        timerFired(data)
        redrawAllWrapper(canvas, data)
        # pause, then call timerFired again
        canvas.after(data.timerDelay, timerFiredWrapper, canvas, data)

    # Set up data and call init
    class Struct(object): pass
    data = Struct()
    data.width = width
    data.height = height
    data.timerDelay = 50 # milliseconds
    init(data)
    # create the root and the canvas
    # root = Tk()
    canvas = Canvas(root, width=data.width, height=data.height)
    canvas.pack()
    # set up events

    root.bind("<B1-Motion>", lambda event: mouseMovedWrapper(event, canvas, data))
    timerFiredWrapper(canvas, data)
    root.bind("<Button-1>", lambda event:
                            mousePressedWrapper(event, canvas, data))

    root.bind("<Key>", lambda event:
                            keyPressedWrapper(event, canvas, data))

    # and launch the app
    root.mainloop()  # blocks until window is closed
    print("bye!")

run(1000, 750) 

关于openCV部分是这样的:

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eyeCascade = cv2.CascadeClassifier('haarcascade_eye.xml')
video_capture = cv2.VideoCapture(0)

while True:
    # Capture frame-by-frame
    ret, frame = video_capture.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30),
                                        flags=cv2.cv.CV_HAAR_SCALE_IMAGE)


    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        # cv2.imread('face2.jpg',1)
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
        # img = cv2.imread('face2.jpg',1)
        # img = cv2.resize(img, (x,y), fx=0.1, fy=0.1)
        # cv2.imshow('img', img)

        roi_gray = gray[y:y+h, x:x+w]
        roi_color = frame[y:y+h, x:x+w]
        eyes = eyeCascade.detectMultiScale(roi_gray, 1.1, 2, minSize=(70, 70), flags=cv2.cv.CV_HAAR_SCALE_IMAGE)

        for (x1, y1, w1, h1) in eyes:
            cv2.rectangle(roi_color, (x1, y1), (x1+w1, y1+h1), (0, 0, 255), 2)


    # Display the resulting frame
    cv2.imshow('Video', frame)


    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()

那我该如何实现呢?有人能帮助我吗?

1 个答案:

答案 0 :(得分:0)

您可以让openCV脚本将(x,y,w,h)写入文件,并从该文件中读取tkinter脚本,然后在一个文件中运行这两个程序。或者,您可以在同一程序中运行,但使用tkinter画布显示openCV图像。我编写了第一个,它适用于我。

Tkinter代码

import Tkinter as tk
import time
import re

root = tk.Tk()
# Canvas to display the rectangle
w = tk.Canvas(root, width=640, height=480)
w.pack()
global rect 
rect = None

def UpdateRectangle():
    global rect
    # Read the rectangle data
    fid = open('rect.txt','r')
    boundstr = fid.read()
    fid.close()
    tmp = tuple(int(v) for v in re.findall("[0-9]+", boundstr))
    # Rearrange since bbox should be (x1, y1, x2, y2)
    bbox = (tmp[0],tmp[1],tmp[0]+tmp[2],tmp[1]+tmp[3],)

    # Delete old rectangle
    if rect is not None:
        w.delete(rect)

    # Draw new one
    rect = w.create_rectangle(bbox, fill='', outline='blue', width=2)
    root.after(200, UpdateRectangle) # every 0.2 seconds...

UpdateRectangle()
root.mainloop()

OpenCV代码

import cv2

faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
eyeCascade = cv2.CascadeClassifier('haarcascade_eye.xml')
video_capture = cv2.VideoCapture(0)

while True:
    # Capture frame-by-frame
    ret, frame = video_capture.read()

    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)

    faces = faceCascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=5, minSize=(30, 30),flags=cv2.CASCADE_SCALE_IMAGE)


    # Draw a rectangle around the faces
    for (x, y, w, h) in faces:
        # cv2.imread('face2.jpg',1)
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
        # img = cv2.imread('face2.jpg',1)
        # img = cv2.resize(img, (x,y), fx=0.1, fy=0.1)
        # cv2.imshow('img', img)

        roi_gray = gray[y:y+h, x:x+w]
        roi_color = frame[y:y+h, x:x+w]
        eyes = eyeCascade.detectMultiScale(roi_gray, 1.1, 2, minSize=(70, 70),flags=cv2.CASCADE_SCALE_IMAGE)

        for (x1, y1, w1, h1) in eyes:
            cv2.rectangle(roi_color, (x1, y1), (x1+w1, y1+h1), (0, 0, 255), 2)

        # Write the rectangle data
        fid = open('rect.txt','w')
        rect = "%d %d %d %d" % (x, y, w, h)
        fid.write(rect)
        fid.close()


    # Display the resulting frame
    cv2.imshow('Video', frame)


    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# When everything is done, release the capture
video_capture.release()
cv2.destroyAllWindows()

在Tkinter画布中查看要显示的Read an image with OpenCV and display it with Tkinter ff和openCV图像文件。您也可以使用相同的root.after(command,delay)来更新此画布。