tkinter + opencv + socket + thread

24577 ワード

これは深さ訓練を利用したまばたきテストです.コードは次のとおりです.残念ながらとても遅いですこれは2回の深走りのためだと思います.
import cv2, dlib
import tkinter as tk
from PIL import Image, ImageTk
import threading
import RPi.GPIO as gp
import time
from imutils import face_utils
from tensorflow.keras.models import load_model
import numpy as np
import socket
import sys

# set socket param
print("setting client parameter")
SERVER_IP = '127.0.0.1'
SERVER_PORT = 5050
SIZE = 1024
SERVER_ADDR = (SERVER_IP, SERVER_PORT)
client = socket.socket()
client.connect(SERVER_ADDR)
# if sending stop loop, client.send(''.encode())
# if sending start buzzer, client.send(''.encode())

# set param for crop eyes
IMG_SIZE = (34,26)

# buzzer buz or stop
buzzer = None

def crop_eye(img, eye_points):
    global IMG_SIZE, buzzer
    x1, y1 = np.amin(eye_points, axis=0)
    x2, y2 = np.amax(eye_points, axis=0)
    cx, cy = (x1+x2)/2, (y1+y2)/2
    w = (x2-x1)*1.2
    h = w * IMG_SIZE[1] / IMG_SIZE[0]

    margin_x, margin_y = w/2, h/2

    min_x, min_y = int(cx-margin_x), int(cy-margin_y)
    max_x, max_y = int(cx+margin_x), int(cy+margin_y)

    eye_rect = np.rint([min_x, min_y, max_x, max_y]).astype(np.int)
    eye_img = img[eye_rect[1]: eye_rect[3], eye_rect[0]:eye_rect[2]]

    return eye_img, eye_rect

def camThread():
    global IMG_SIZE
    cap = cv2.VideoCapture(0)
    panel = None

    dlib_model_path = '../dlib-models/shape_predictor_68_face_landmarks.dat'
    net_model_path = '../dlib-models/Mymodel3.h5'

    detector = dlib.get_frontal_face_detector()
    predictor = dlib.shape_predictor(dlib_model_path)

    model = load_model(net_model_path)
    model.summary()

    if not cap.isOpened():
        print("cant read image")
    
    timer_start = time.time()
    time_sum = 0
    delta = 0

    while True:
        _, img = cap.read()
        img = cv2.resize(img, dsize=(0,0), fx=0.5, fy = 0.5)
        img = cv2.flip(img, 0)
        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

        faces = detector(gray)
        if faces == None:
            print("no")

        for face in faces:
            shapes = predictor(gray, face)
            shapes = face_utils.shape_to_np(shapes)
            eye_img_l, eye_rect_l = crop_eye(gray, eye_points=shapes[36:42])
            eye_img_r, eye_rect_r = crop_eye(gray, eye_points=shapes[42:48])

            eye_img_l = cv2.resize(eye_img_l, dsize=IMG_SIZE)
            eye_img_r = cv2.resize(eye_img_r, dsize=IMG_SIZE)
            eye_img_r = cv2.flip(eye_img_r, flipCode=1)

            eye_input_l = eye_img_l.copy().reshape((1, IMG_SIZE[1], IMG_SIZE[0], 1)).astype(np.float32)/255.
            eye_input_r = eye_img_r.copy().reshape((1, IMG_SIZE[1], IMG_SIZE[0], 1)).astype(np.float32)/255.

            pred_l = model.predict(eye_input_l)
            pred_r = model.predict(eye_input_r)

            if pred_l <= 0.1 or pred_r <= 0.1:
                timer_end = time.time() # 
                delta = timer_end - timer_start
                time_sum += delta
                timer_start = timer_end
                buzzer = 'buz' if time_sum > 4. else 'none'
                print("delay_time = %.2f"%time_sum, " buz state = ", buzzer)
                client.send(buzzer.encode())

            else :
                time_sum = 0
                delta = 0
                timer_start = time.time()
                print("else, time reset", time_sum)

        # show image in tkinter
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        img = Image.fromarray(img)
        img = ImageTk.PhotoImage(img)

        if panel is None:
            panel = tk.Label(image=img)
            panel.image = img
            panel.pack(side="top")
        else :
            panel.configure(image=img)
            panel.image = img

        cv2.waitKey(1)

def buzzerButton():
    global buzzer
    buzzer = 'stop'
    client.send(buzzer.encode())
    time.sleep(2)
    sys.exit(-1)

if __name__ == "__main__":
    thread_img = threading.Thread(target=camThread, args=())
    thread_img.daemon = True
    thread_img.start()

    
    root = tk.Tk()
    button = tk.Button(root, text="buzzerStopButton", command=buzzerButton)
    button.pack(side="bottom")
    root.mainloop()