Tkinter不在Heroku服务器上运行,但在本地主机上运行良好

时间:2020-04-23 09:50:27

标签: python flask heroku tkinter

我正在开发使用烧瓶的Web应用程序,类似于虚拟更衣室,用户可以在其中试穿衣服。我正在使用dlib执行所有界标检测,以便可以找到叠加图像的位置,从而使人看起来好像穿着那块衣服。 我正在使用Tkinter在单个GUI窗口中提供相机和图像,请参见下面的图像 Tkinter GUI window

在本地主机上一切正常,但是当我在Heroku上部署它时,tkinter没有运行,它将网站重定向到本地主机地址。所有逻辑都在test.py文件中,请查看此文件->

from tkinter_scroll import *
from tkinter import *
from PIL import Image
from PIL import ImageTk
import cv2, threading, os, time
from threading import Thread
from os import listdir
from os.path import isfile, join
import dlib
from imutils import face_utils, rotate_bound
import math

ACTIVE_IMAGES=[0 for i in range(100)]
def put_sprite(num, k):
    global SPRITES, BTNS
    SPRITES[num] = (1 - SPRITES[num]) 
    if SPRITES[num]:
        ACTIVE_IMAGES[num] = k
        BTNS[num].config(relief=SUNKEN)
    else:
        BTNS[num].config(relief=RAISED)

def draw_sprite(frame, sprite, x_offset, y_offset):
    (h,w) = (sprite.shape[0], sprite.shape[1])
    (imgH,imgW) = (frame.shape[0], frame.shape[1])
    if y_offset+h >= imgH:
        sprite = sprite[0:imgH-y_offset,:,:]
    if x_offset+w >= imgW:
        sprite = sprite[:,0:imgW-x_offset,:]
    if x_offset < 0: 
        sprite = sprite[:,abs(x_offset)::,:]
        w = sprite.shape[1]
        x_offset = 0
    for c in range(3):
            frame[y_offset:y_offset+h, x_offset:x_offset+w, c] =  \
            sprite[:,:,c] * (sprite[:,:,3]/255.0) +  frame[y_offset:y_offset+h, x_offset:x_offset+w, c] * (1.0 - sprite[:,:,3]/255.0)
    return frame

def adjust_sprite2head(sprite, head_width, head_ypos, ontop = True):
    (h_sprite,w_sprite) = (sprite.shape[0], sprite.shape[1])
    factor = 1.0*head_width/w_sprite
    sprite = cv2.resize(sprite, (0,0), fx=factor, fy=factor)
    (h_sprite,w_sprite) = (sprite.shape[0], sprite.shape[1])
    y_orig =  head_ypos-h_sprite if ontop else head_ypos 
    if (y_orig < 0):
            sprite = sprite[abs(y_orig)::,:,:] 
            y_orig = 0
    return (sprite, y_orig)

def apply_sprite2feature(image, sprite_path, haar_filter, x_offset, y_offset, y_offset_image, adjust2feature, desired_width, x, y, w, h):
    sprite = cv2.imread(sprite_path,-1)
    (h_sprite,w_sprite) = (sprite.shape[0], sprite.shape[1])

    xpos = x + x_offset
    ypos = y + y_offset
    factor = 1.0*desired_width/w_sprite

    sub_img = image[y + y_offset_image:y+h,x:x+w,:]

    feature = apply_Haar_filter(sub_img, haar_filter, 1.3 , 10, 10)
    if len(feature)!=0:
        xpos, ypos = x, y + feature[0,1] #adjust only to feature in y axis (eyes)

        if adjust2feature:
            size_mustache = 1.2 #how many times bigger than mouth
            factor = 1.0*(feature[0,2]*size_mustache)/w_sprite
            xpos =  x + feature[0,0] - int(feature[0,2]*(size_mustache-1)//2) #centered respect to width
            ypos = y + y_offset_image + feature[0,1] - int(h_sprite*factor) #right on top

    sprite = cv2.resize(sprite, (0,0), fx=factor, fy=factor)
    image = draw_sprite(image,sprite,xpos,ypos)

def apply_sprite(image, path2sprite,w,x,y, angle, ontop = True):
    sprite = cv2.imread(path2sprite,-1)
    sprite = rotate_bound(sprite, angle)
    (sprite, y_final) = adjust_sprite2head(sprite, w, y, ontop)
    image = draw_sprite(image,sprite,x, y_final)

def calculate_inclination(point1, point2):
    x1,x2,y1,y2 = point1[0], point2[0], point1[1], point2[1]
    incl = 180/math.pi*math.atan((float(y2-y1))/(x2-x1))
    return incl

def calculate_boundbox(list_coordinates):
    x = min(list_coordinates[:,0])
    y = min(list_coordinates[:,1])
    w = max(list_coordinates[:,0]) - x
    h = max(list_coordinates[:,1]) - y
    return (x,y,w,h)

def apply_Haar_filter(img, haar_cascade,scaleFact = 1.05, minNeigh = 3, minSizeW = 30):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    features = haar_cascade.detectMultiScale(
        gray,
        scaleFactor=scaleFact,
        minNeighbors=minNeigh,
        minSize=(minSizeW, minSizeW),
        flags=cv2.CASCADE_SCALE_IMAGE
    )
    return features


def get_face_boundbox(points, face_part):
    if face_part == 1:
        (x,y,w,h) = calculate_boundbox(points[17:22])
    elif face_part == 2:
        (x,y,w,h) = calculate_boundbox(points[22:27]) 
    elif face_part == 3:
        (x,y,w,h) = calculate_boundbox(points[36:42])
    elif face_part == 4:
        (x,y,w,h) = calculate_boundbox(points[42:48])
    elif face_part == 5:
        (x,y,w,h) = calculate_boundbox(points[29:36])
    elif face_part == 6:  
        (x,y,w,h) = calculate_boundbox(points[1:17])
    elif face_part == 7:
         (x,y,w,h) = calculate_boundbox(points[0:6])
    elif face_part == 8:
        (x,y,w,h) = calculate_boundbox(points[11:17])
    return (x,y,w,h)

def cvloop(run_event):
    global ctr_mid
    global SPRITES
    i = 0
    video_capture = cv2.VideoCapture(0)
    video_capture.set(3,2048)
    video_capture.set(4,2048)
    (x,y,w,h) = (0,0,10,10) 
    detector = dlib.get_frontal_face_detector()
    fullbody = cv2.CascadeClassifier('data/haarcascade_fullbody.xml')
    model = "data/shape_predictor_68_face_landmarks.dat"
    predictor = dlib.shape_predictor(model) # link to model: http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2
    while run_event.is_set(): 
        ret, image = video_capture.read()
        gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
        faces = detector(gray, 0)
        for face in faces: 
            (x,y,w,h) = (face.left(), face.top(), face.width(), face.height())
            shape = predictor(gray, face)
            shape = face_utils.shape_to_np(shape)
            incl = calculate_inclination(shape[17], shape[26])
            is_mouth_open = (shape[66][1] -shape[62][1]) >= 10

            if SPRITES[3]:#Tiara
                apply_sprite(image, IMAGES[3][ACTIVE_IMAGES[3]],w+45,x-20,y+20, incl, ontop = True)

            #Necklaces
            if SPRITES[1]:
                (x1,y1,w1,h1) = get_face_boundbox(shape, 6)
                apply_sprite(image, IMAGES[1][ACTIVE_IMAGES[1]],w1,x1,y1+150, incl,  ontop = False)

            #Goggles
            if SPRITES[6]:
                (x3,y3,_,h3) = get_face_boundbox(shape, 1)
                apply_sprite(image, IMAGES[6][ACTIVE_IMAGES[6]],w,x,y3-10, incl, ontop = False)

            #Earrings
            (x0,y0,w0,h0) = get_face_boundbox(shape, 6) #bound box of mouth
            if SPRITES[2]:
                (x3,y3,w3,h3) = get_face_boundbox(shape, 7) #nose
                apply_sprite(image, IMAGES[2][ACTIVE_IMAGES[2]],w3,x3-40,y3+30, incl,ontop=False)
                (x3,y3,w3,h3) = get_face_boundbox(shape, 8) #nose
                apply_sprite(image, IMAGES[2][ACTIVE_IMAGES[2]],w3,x3+40,y3+75, incl) 

#            if SPRITES[5]:
#                apply_sprite(image, IMAGES[5][ACTIVE_IMAGES[5]],w,x,y, incl, ontop = True)

            #Frocks
            if SPRITES[5]:
                (x1,y1,w1,h1) = get_face_boundbox(shape, 8)
                apply_sprite(image, IMAGES[5][ACTIVE_IMAGES[5]],w1+580,x1-350,y1+80, incl,  ontop = False)

            #Tops
            if SPRITES[4]:
                # (x,y,w,h) = (0,0,10,10)
                # apply_sprite2feature(image, IMAGES[7][ACTIVE_IMAGES[7]], fullbody, w//4, 2*h//3, h//2, True, w//2, x, y, w, h)
                (x1,y1,w1,h1) = get_face_boundbox(shape, 8)
                apply_sprite(image, IMAGES[4][ACTIVE_IMAGES[4]],w1+350,x1-230,y1+100, incl,  ontop = False)

        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
        image = Image.fromarray(image)
        image = ImageTk.PhotoImage(image)
        ctr_mid.configure(image=image)
        ctr_mid.image = image

    video_capture.release()

root = Tk()
root.title('TryOn')
app=FullScreenApp(root)

top_frame = Frame(root, bg='#077bd4', width=50, height=50, pady=3)
center = Frame(root, bg='white', width=50, height=40, padx=3, pady=3)
btm_frame = Frame(root, bg='#077bd4', width=50, height=50, pady=3)

root.grid_rowconfigure(1, weight=1)
root.grid_columnconfigure(0, weight=1)

top_frame.grid(row=0, sticky="ew")
center.grid(row=1, sticky="nsew")
btm_frame.grid(row=4, sticky="ew")
logo = ImageTk.PhotoImage(Image.open('logo.png').resize((120,60)))
model_label = Label(top_frame,image=logo)

model_label.grid(row=0, columnspan=3)

center.grid_rowconfigure(0, weight=1)
center.grid_columnconfigure(1, weight=1)

ctr_left = Label(center,bg='white', width=50, height=190)
ctr_mid = Label(center,bg='white',width=100, height=160, padx=0, pady=0)

ctr_left.grid(row=0, column=0, sticky="ns")
ctr_mid.grid(row=0, column=1, sticky="nsew")

scrollable_body = Scrollable(ctr_left, width=15)
SPRITES=[0 for i in range(10)]
BTNS=[]
IMAGES ={i:[] for i in range(10)}
PHOTOS ={i:[] for i in range(10)}
for img in sys.argv[1:]:
    print(img.rsplit('/',1)[0][-1])
    IMAGES[int(img.rsplit('/',1)[0][-1])].append(img)
    image=ImageTk.PhotoImage(Image.open(img).resize((150,100)))
    PHOTOS[int(img.rsplit('/',1)[0][-1])].append(image)
for index in range(9):
    if len(PHOTOS[index]) > 0:
        for k,photo in enumerate(PHOTOS[index]):
            btn= Button(scrollable_body, highlightbackground='white', text=IMAGES[index][k].rsplit('/',1)[1].replace('.png','')[:-1],bg='white', image=photo, command = lambda index=index, k=k: put_sprite(index,k), compound=LEFT, width='300', height='200')
            btn.pack(side="top", fill="both", expand="no", padx="5", pady="5")
            BTNS.append(btn)
scrollable_body.update()

run_event = threading.Event()
run_event.set()
action = Thread(target=cvloop, args=(run_event,))
action.setDaemon(True)
action.start()

def terminate():
        global root, run_event, action
        run_event.clear()
        time.sleep(1)
        root.destroy()
root.protocol("WM_DELETE_WINDOW", terminate)
root.mainloop()

我想解决此问题,如果无法在服务器上运行tkinter,请告诉我其他实现此功能的方法。

0 个答案:

没有答案