2

I want to control something in a tkinter window by the movement of the detected face from a openCV window. For tkinter window, here is my settings:

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) 

About the openCV part is like this:

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()

So how can I achieve like that? Can anybody help me?

turtletree
  • 93
  • 1
  • 2
  • 5
  • All I need to do is to relate the x,y,w,h from my face-detection to the move ment of my rectangle in the tkinter window. Now I can't get the two window work together, they must be first come first go order. How to deal with that? Is there something about multithreading? – turtletree Dec 02 '15 at 15:57

1 Answers1

0

You can have the openCV script write the (x, y, w, h) to a file and the tkinter script read from that file, and then run both programs at one. Alternatively, you could run both in the same program, but display the openCV images using a tkinter canvas. I coded up the first one, it works for me.

Tkinter code

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 code

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()

See Read an image with OpenCV and display it with Tkinter ff you want to display and openCV image file in a Tkinter canvas. You can use the same root.after(command,delay) to make this canvas update as well.

Community
  • 1
  • 1
Zack Knopp
  • 2,765
  • 2
  • 13
  • 14