Beispiel #1
0
    def __init__(self, master, image, name, enhancer, lo, hi):
        Frame.__init__(self, master)

        # set up the image
        self.tkim = ImageTk.PhotoImage(image.mode, image.size)
        self.enhancer = enhancer(image)
        self.update("1.0")  # normalize

        # image window
        Label(self, image=self.tkim).pack()

        # scale
        s = Scale(self, label=name, orient=HORIZONTAL, from_=lo, to=hi, resolution=0.01, command=self.update)
        s.set(self.value)
        s.pack()
Beispiel #2
0
    def __init__(self, master, image, name, enhancer, lo, hi):
        Frame.__init__(self, master)

        # set up the image
        self.tkim = ImageTk.PhotoImage(image.mode, image.size)
        self.enhancer = enhancer(image)
        self.update("1.0")  # normalize

        # image window
        Label(self, image=self.tkim).pack()

        # scale
        s = Scale(self,
                  label=name,
                  orient=HORIZONTAL,
                  from_=lo,
                  to=hi,
                  resolution=0.01,
                  command=self.update)
        s.set(self.value)
        s.pack()
    def __init__(self, master, image, image_name):
        Frame.__init__(self, master)
        self.image = image
        self.image_name = image_name

        # make a blank image for the text, initialized to transparent text color
        self.blank_image = Image.new('RGBA', self.image.size, (255,255,255,0))
        self.fnt = ImageFont.truetype('fonts/MontereyFLF.ttf', 50)
        self.d = ImageDraw.Draw(self.blank_image)

        #default watermark
        self.name = "watermark"
        self.loc_x = 0
        self.loc_y = 225
        self.rgbo = (0,0,0,200)
        self.d.text((self.loc_x, self.loc_y), self.name, font=self.fnt, fill=self.rgbo)

        self.out = Image.alpha_composite(self.image, self.blank_image)
        self.tkim = ImageTk.PhotoImage(self.out)

        #display image
        Label(root, image=self.tkim).pack()

        # opacity scale
        s_opacity = Scale(self, label="Opacity", orient=HORIZONTAL, from_=0, to=255, resolution=1, command=self.update_opacity)
        s_opacity.set(200)
        s_opacity.pack(pady = 10)


        #update text
        self.textbox = Entry()
        self.textbox.pack(pady = 10)
        b_text = Button(master, text="update text", command=self.update_text)
        b_text.pack()

        b_color = Button(master, text="black/white", command=self.update_color)
        b_color.pack()
        
        b_save = Button(master, text="save image", command=self.save_image)
        b_save.pack()
Beispiel #4
0
class Gui(Frame):
    #==============================================================================
    #     Metodos Basicos
    #==============================================================================
    def __init__(self, parent=None):
        Frame.__init__(self, parent)
        # Atributos GUI
        self.parent = parent
        self.file_opt = self.flopt = {}
        w, h = self.parent.winfo_screenwidth(), self.parent.winfo_screenheight(
        )
        self.largura = w - 20
        self.altura = h - 20

        # Atributos funcionais
        self.img = None
        self.imgOld = None
        self.arqImg = StringVar()
        self.arqImg.set('')

        self.formatos = {}
        self.formatos['gif'] = 'GIF'
        self.formatos['jpg'] = 'JPEG'
        self.formatos['jpeg'] = 'JPEG'
        self.formatos['png'] = 'PNG'
        self.formatos['bmp'] = 'BMP'
        self.formatos['tif'] = 'TIFF'
        self.formatos['tiff'] = 'TIFF'
        self.formatos['ppm'] = 'PPM'
        self.formatos['pbm'] = 'PPM'
        self.formatos['pgm'] = 'PPM'

        self.tipos = [('Imagens', ('*.jpg', '*.png', '*.gif', '*.bmp', '*.ppm',
                                   '*.pgm', '*.pbm')), ('JPEG', '*.jpg'),
                      ('PNG', '*.png'), ('GIF', '*.gif'), ('BMP', '*.bmp'),
                      ('PPM', '*.ppm'), ('PGM', '*.pgm'), ('PBM', '*.pbm'),
                      ('Todos arquivos', '*')]

        # Cria/atualiza GUI
        self.createWidgets()
        self.update_idletasks()

#==============================================================================
#     Metodos relacionados ao comportamento da GUI
#==============================================================================

    def createWidgets(self):
        self.canvas = Canvas(self.parent, width=1366, height=768)
        self.scroll = Scrollbar(self.parent,
                                orient="vertical",
                                command=self.canvas.yview)
        self.canvas.configure(yscrollcommand=self.scroll.set)
        self.scroll.pack(side="right", fill="y")
        self.canvas.pack(side="left", fill="both", expand=True)

        # Configura barra de menus
        self.menubar = Menu(self.parent)
        self.parent.config(menu=self.menubar)

        # Menu arquivo e suas opcoes
        self.menuArquivo = Menu(self.menubar)
        self.menuArquivo.add_command(label='Abrir',
                                     underline=0,
                                     command=self.abrir)
        self.menuArquivo.add_separator()
        self.menuArquivo.add_command(label='Salvar',
                                     underline=0,
                                     command=self.salvar)
        self.menuArquivo.add_command(label='Salvar Como...',
                                     underline=0,
                                     command=self.salvarComo)
        self.menuArquivo.add_separator()
        self.menuArquivo.add_command(label='Fechar imagem(ns)',
                                     underline=0,
                                     command=self.fecharArquivo)
        self.menuArquivo.add_command(label="Sair",
                                     underline=3,
                                     command=self.onExit)
        self.menubar.add_cascade(label="Arquivo",
                                 underline=0,
                                 menu=self.menuArquivo)

        # Menu editar e suas opcoes
        self.menuEditar = Menu(self.menubar)
        self.menuEditar.add_command(label='Desfazer',
                                    underline=0,
                                    command=self.desfazer)
        self.menubar.add_cascade(label="Editar",
                                 underline=0,
                                 menu=self.menuEditar)

        # Menu Imagem e suas opcoes
        self.menuImagem = Menu(self.menubar)

        self.submenuConverte = Menu(self.menuImagem)
        self.submenuConverte.add_command(label='Colorido RGB',
                                         underline=0,
                                         command=lambda: self.converte('RGB'))
        self.submenuConverte.add_command(label='Colorido RGBA',
                                         underline=0,
                                         command=lambda: self.converte('RGBA'))
        self.submenuConverte.add_command(label='Escala de cinza',
                                         underline=0,
                                         command=lambda: self.converte('L'))
        self.submenuConverte.add_command(label='Binario',
                                         underline=0,
                                         command=lambda: self.converte('1'))

        self.menuImagem.add_command(label='Informacoes gerais',
                                    underline=0,
                                    command=self.info)
        self.menuImagem.add_separator()
        self.menuImagem.add_cascade(label='Converter',
                                    underline=0,
                                    menu=self.submenuConverte)
        self.menubar.add_cascade(label="Imagem",
                                 underline=0,
                                 menu=self.menuImagem)

        # Menu de operacoes sobre cores e suas opcoes
        self.menuCores = Menu(self.menubar)

        self.submenuCinza = Menu(self.menuCores)
        self.submenuCinza.add_command(label='Decomposicao de Maximo',
                                      underline=18,
                                      command=self.emConstrucao)
        self.submenuCinza.add_command(label='Decomposicao de Minimo',
                                      underline=18,
                                      command=self.emConstrucao)
        self.submenuCinza.add_command(label='Average',
                                      underline=0,
                                      command=lambda: self.mudaCor('average'))
        self.submenuCinza.add_command(label='Lightness',
                                      underline=0,
                                      command=self.emConstrucao)
        self.submenuCinza.add_command(label='Luminosity',
                                      underline=0,
                                      command=self.emConstrucao)
        self.submenuCinza.add_command(label='Componente R',
                                      underline=11,
                                      command=lambda: self.mudaCor('r'))
        self.submenuCinza.add_command(label='Componente G',
                                      underline=11,
                                      command=self.emConstrucao)
        self.submenuCinza.add_command(label='Componente B',
                                      underline=11,
                                      command=self.emConstrucao)
        self.submenuCinza.add_command(label='Quantidade arbitraria de tons',
                                      underline=0,
                                      command=self.emConstrucao)

        self.submenuHalftone = Menu(self.menuCores)
        self.submenuHalftone.add_command(
            label='Bayer 2x2',
            underline=6,
            command=lambda: self.halftoning('bayer2'))
        self.submenuHalftone.add_command(label='Bayer 5x5',
                                         underline=6,
                                         command=self.emConstrucao)
        self.submenuHalftone.add_command(label='Atkinson',
                                         underline=0,
                                         command=self.emConstrucao)
        self.submenuHalftone.add_command(label='Sierra Lite',
                                         underline=0,
                                         command=self.emConstrucao)
        self.submenuHalftone.add_command(label='Jarvis, Judice, and Ninke',
                                         underline=0,
                                         command=self.emConstrucao)
        self.submenuHalftone.add_command(
            label='Floyd-Steinberg',
            underline=0,
            command=lambda: self.halftoning('floyd'))

        self.menuCores.add_cascade(label='Tons de cinza',
                                   underline=0,
                                   menu=self.submenuCinza)
        self.menuCores.add_command(label='Inverter',
                                   underline=0,
                                   command=lambda: self.mudaCor('inv'))
        self.menuCores.add_command(label='Sepia',
                                   underline=0,
                                   command=self.emConstrucao)
        self.menuCores.add_separator()
        self.menuCores.add_command(label='Pseudo Binaria',
                                   underline=0,
                                   command=self.binaria)
        self.menuCores.add_cascade(label='Halftoning',
                                   underline=0,
                                   menu=self.submenuHalftone)
        self.menuCores.add_separator()
        self.menuCores.add_command(label='Cisalhamento de Cor',
                                   underline=0,
                                   command=self.emConstrucao)
        self.menuCores.add_command(label='Balanco de cores',
                                   underline=0,
                                   command=self.balancoCor)
        self.menuCores.add_command(label='Quantizacao de cores',
                                   underline=0,
                                   command=self.emConstrucao)
        self.menubar.add_cascade(label="Cores",
                                 underline=0,
                                 menu=self.menuCores)

        # Menu de operacoes topologicas e suas opcoes
        self.menuTopologia = Menu(self.menubar)
        self.menuTopologia.add_command(label='Rotular Componentes',
                                       underline=0,
                                       command=self.emConstrucao)
        self.menuTopologia.add_command(label='Transformada da Distancia',
                                       underline=0,
                                       command=self.emConstrucao)
        self.menuTopologia.add_command(label='Esqueletizacao',
                                       underline=0,
                                       command=self.emConstrucao)
        self.menubar.add_cascade(label="Topologia",
                                 underline=0,
                                 menu=self.menuTopologia)

        # Menu do trabalho e suas opcoes
        self.trabalho = Menu(self.menubar)
        self.trabalho.add_command(label='Tarefa 01',
                                  underline=20,
                                  command=self.abrir)

        # Grupo principal, onde serao atualizados os widgets
        self.grupoPrincipal = Frame(self.canvas,
                                    width=self.largura,
                                    height=self.altura,
                                    bd=1,
                                    padx=10,
                                    pady=10)
        self.grupoPrincipal.pack()
        #self.grupoPrincipal.grid_propagate(False) # Faz com que o Frame nao seja redimensionado com a mudanca dos widgets
        self.canvas.create_window((4, 20),
                                  window=self.grupoPrincipal,
                                  anchor="nw",
                                  tags="self.grupoPrincipal")
        self.grupoPrincipal.bind("<Configure>", self.OnFrameConfigure)

    def OnFrameConfigure(self, event):
        '''Reset the scroll region to encompass the inner frame'''
        self.canvas.configure(scrollregion=self.canvas.bbox("all"))

    def onExit(self):
        self.parent.destroy()

    def limpaTela(self):
        for widget in self.grupoPrincipal.winfo_children():
            widget.destroy()

    def emConstrucao(self):
        tkm.showinfo(title="Em construcao", message="Recurso em Construcao...")

    def load_file(self, titulo, varFile, tipos):
        if os.path.isfile(varFile.get()):
            path = os.path.dirname(varFile.get())
            self.flopt['initialdir'] = path
        else:
            self.flopt['initialdir'] = os.path.curdir
        self.flopt['filetypes'] = tipos
        arquivo = tkf.askopenfilename(title=titulo, **self.flopt)
        if arquivo:
            varFile.set(arquivo)

    def widgetFile(self, master, titulo, texto, varFile, tuplaFiletype):
        esteFrame = LabelFrame(master, text=titulo, padx=5, pady=5)

        j = 0
        varFile.set("Nenhum arquivo informado")
        labelRotulo = Label(esteFrame, text=texto)
        labelRotulo.grid(row=j, column=0, sticky=cte.E)

        botao = Button(
            esteFrame,
            text="Procurar",
            command=lambda: self.load_file(texto, varFile, tuplaFiletype),
            width=10)
        botao.grid(row=j, column=1, pady=5, sticky=cte.W)

        j += 1

        labelArq = Label(esteFrame, textvariable=varFile, bg='white')
        labelArq.grid(row=j, column=0, columnspan=2)

        return esteFrame

    def refreshImg(self):
        try:
            self.grupoPrincipal.photo = ImageTk.PhotoImage(self.img.img)
            if hasattr(self.grupoPrincipal, 'canvas'):
                self.grupoPrincipal.canvas.destroy()
            self.grupoPrincipal.canvas = Canvas(self.grupoPrincipal)
            self.grupoPrincipal.canvas.create_image(
                0, 0, image=self.grupoPrincipal.photo, anchor=cte.NW)
            self.grupoPrincipal.canvas.config(bg='white',
                                              width=self.img.altura,
                                              height=self.img.largura)
            #self.grupoPrincipal.canvas.place(x=self.parent.winfo_screenwidth()/2, y=self.parent.winfo_screenheight()/2, anchor=cte.CENTER)
            self.grupoPrincipal.canvas.place(x=0, y=0, anchor=cte.NW)
            self.grupoPrincipal.update_idletasks()
        except Exception as e:
            tkm.showerror('Erro', 'O seguinte erro ocorreu: %s' % str(e.args))

#==============================================================================
#   Metodos relacionados ao meno Arquivo
#==============================================================================

    def abrir(self):
        try:
            self.limpaTela()
            self.load_file('Arquivos de Imagem', self.arqImg, self.tipos)
            self.img = Imagem(self.arqImg.get())
            self.refreshImg()
        except Exception as e:
            tkm.showerror('Erro', 'O seguinte erro ocorreu: %s' % str(e.args))

    def saveFile(self):
        try:
            nome, extensao = os.path.splitext(self.arqImg.get())
            extensao = extensao.replace('.', '')
            self.img.salva(self.arqImg.get(), self.formatos[extensao.lower()])
            tkm.showinfo(
                'Sucesso', 'Arquivo %s salvo com sucesso' %
                os.path.basename(self.arqImg.get()))
        except Exception as e:
            tkm.showerror('Erro', 'O seguinte erro ocorreu: %s' % str(e.args))

    def salvar(self):
        if self.arqImg.get() == '':
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto para ser salvo')
        else:
            try:
                self.saveFile()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

    def salvarComo(self):
        if self.arqImg.get() == '':
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto para ser salvo')
        else:
            try:
                if os.path.isfile(self.arqImg.get()):
                    path = os.path.dirname(self.arqImg.get())
                    self.flopt['initialdir'] = path
                else:
                    self.flopt['initialdir'] = os.path.curdir
                self.flopt['filetypes'] = self.tipos
                nomeArq = tkf.asksaveasfilename(title='Salvar imagem como...',
                                                **self.flopt)
                if nomeArq:
                    self.arqImg.set(nomeArq)
                    self.saveFile()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

    def fecharArquivo(self):
        if not hasattr(
                self.grupoPrincipal,
                'canvas') or self.grupoPrincipal.canvas.find_all() == ():
            tkm.showwarning('Aviso', 'Nao ha imagens abertas')
        else:
            try:
                self.img = self.imgOld = None
                self.grupoPrincipal.canvas.delete('all')
                self.grupoPrincipal.update_idletasks()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

#==============================================================================
#  Metodos relacionados ao menu Editar
#==============================================================================

    def desfazer(self):
        if self.arqImg.get() == '' or self.img is None:
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto')
        elif self.imgOld is None:
            tkm.showwarning('Aviso', 'Impossivel Desfazer')
        else:
            try:
                temp = self.img
                self.img = self.imgOld
                self.imgOld = temp
                self.refreshImg()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

#==============================================================================
#   Metodos relacionados ao menu Cores
#==============================================================================

    def mudaCor(self, metodo):
        if self.arqImg.get() == '' or self.img is None:
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto')
        else:
            try:
                self.imgOld = self.img
                self.img = cor.mudaCor(self.imgOld, metodo)
                self.refreshImg()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

    def binaria(self):
        if self.arqImg.get() == '' or self.img is None:
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto')
        else:
            try:
                self.imgOld = self.img
                self.img = cor.binaria(self.imgOld)
                self.refreshImg()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

    def getFatoresBalanco(self):
        self.fatores = [float(self.escalaFatorR.get())]
        self.fatores.append(float(self.escalaFatorG.get()))
        self.fatores.append(float(self.escalaFatorB.get()))

        self.w.destroy()

    def formBalanco(self):
        self.fator = None
        self.fatores = None

        self.w = Toplevel(self)
        self.w.wm_title("Informar os fatores de ajuste")

        self.w.geometry("+%d+%d" %
                        (self.winfo_rootx() + 50, self.winfo_rooty() + 50))
        self.w.focus_set()

        i = 0

        self.labelFatorR = Label(self.w, text='Ajuste em R', width=25)
        self.labelFatorR.grid(row=i, column=0)
        self.escalaFatorR = Scale(self.w,
                                  from_=0,
                                  to=2,
                                  resolution=0.05,
                                  length=350,
                                  orient=cte.HORIZONTAL)
        self.escalaFatorR.set(0.5)
        self.escalaFatorR.grid(row=i, column=1)
        i += 1

        self.labelFatorG = Label(self.w, text='Ajuste em G', width=25)
        self.labelFatorG.grid(row=i, column=0)
        self.escalaFatorG = Scale(self.w,
                                  from_=0,
                                  to=2,
                                  resolution=0.05,
                                  length=350,
                                  orient=cte.HORIZONTAL)
        self.escalaFatorG.set(0.5)
        self.escalaFatorG.grid(row=i, column=1)
        i += 1

        self.labelFatorB = Label(self.w, text='Ajuste em B', width=25)
        self.labelFatorB.grid(row=i, column=0)
        self.escalaFatorB = Scale(self.w,
                                  from_=0,
                                  to=2,
                                  resolution=0.05,
                                  length=350,
                                  orient=cte.HORIZONTAL)
        self.escalaFatorB.set(0.5)
        self.escalaFatorB.grid(row=i, column=1)
        i += 1

        self.botaoFator = Button(self.w,
                                 text='Ok',
                                 command=self.getFatoresBalanco,
                                 width=10)
        self.botaoFator.grid(row=i, column=0, columnspan=2)

        self.w.grid()

    def balancoCor(self):
        if self.arqImg.get() == '' or self.img is None:
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto')
        else:
            try:
                self.formBalanco()
                self.wait_window(self.w)
                if self.fatores is not None:
                    self.imgOld = self.img
                    self.img = cor.balanco(self.imgOld, self.fatores[0],
                                           self.fatores[1], self.fatores[2])
                    self.refreshImg()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

    def halftoning(self, metodo='bayer2'):
        if self.arqImg.get() == '' or self.img is None:
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto')
        else:
            try:
                self.imgOld = self.img
                if metodo == 'bayer2':
                    self.img = cor.bayer(self.imgOld)
                elif metodo == 'floyd':
                    self.img = cor.floyd(self.imgOld)
                else:
                    raise Exception('Metodo de halftoning desconhecido')
                self.refreshImg()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

#==============================================================================
#   Metodos relacionados ao menu Imagem
#==============================================================================

    def converte(self, modo='RGB'):
        if self.arqImg.get() == '' or self.img is None:
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto')
        else:
            try:
                self.imgOld = self.img.copia()
                self.img.converte(modo)
                self.refreshImg()
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))

    def info(self):
        if self.arqImg.get() == '':
            tkm.showwarning('Aviso', 'Nao ha arquivo aberto')
        else:
            try:
                texto = 'Imagem %s, modo: %s (%d x %d pixels)' % (
                    self.img.img.format, self.img.img.mode,
                    self.img.img.size[0], self.img.img.size[1])
                tkm.showinfo('Aviso', texto)
            except Exception as e:
                tkm.showerror('Erro',
                              'O seguinte erro ocorreu: %s' % str(e.args))
class TelloUI:
    """Wrapper class to enable the GUI."""
    def __init__(self, tello, outputpath):
        """
        Initial all the element of the GUI,support by Tkinter

        :param tello: class interacts with the Tello drone.

        Raises:
            RuntimeError: If the Tello rejects the attempt to enter command mode.
        """

        self.tello = tello  # videostream device
        self.outputPath = outputpath  # the path that save pictures created by clicking the takeSnapshot button
        self.frame = None  # frame read from h264decoder and used for pose recognition
        self.thread = None  # thread of the Tkinter mainloop
        self.stopEvent = None

        # control variables
        self.distance = 0.1  # default distance for 'move' cmd
        self.degree = 30  # default degree for 'cw' or 'ccw' cmd
        # if the pose recognition mode is opened
        self.pose_mode = False
        # if the flag is TRUE,the auto-takeoff thread will stop waiting for the response from tello
        self.quit_waiting_flag = False

        # if the flag is TRUE,the pose recognition skeleton will be drawn on the GUI picture
        self.draw_skeleton_flag = False
        # pose recognition
        self.my_tello_pose = Tello_Pose()

        # record the coordinates of the nodes in the pose recognition skeleton
        self.points = []
        #list of all the possible connections between skeleton nodes
        self.POSE_PAIRS = [[0, 1], [1, 2], [2, 3], [3, 4], [1, 5], [5, 6],
                           [6, 7], [1, 14], [14, 8], [8, 9], [9, 10], [14, 11],
                           [11, 12], [12, 13]]

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

        # create buttons
        self.btn_snapshot = tki.Button(self.root,
                                       text="Snapshot!",
                                       command=self.takeSnapshot)
        self.btn_snapshot.pack(side="bottom",
                               fill="both",
                               expand="yes",
                               padx=10,
                               pady=5)

        self.btn_pose = tki.Button(self.root,
                                   text="Pose Recognition Status: Off",
                                   command=self.setPoseMode)
        self.btn_pose.pack(side="bottom",
                           fill="both",
                           expand="yes",
                           padx=10,
                           pady=5)

        self.btn_pause = tki.Button(self.root,
                                    text="Pause",
                                    relief="raised",
                                    command=self.pauseVideo)
        self.btn_pause.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

        self.btn_landing = tki.Button(self.root,
                                      text="Open Command Panel",
                                      relief="raised",
                                      command=self.openCmdWindow)
        self.btn_landing.pack(side="bottom",
                              fill="both",
                              expand="yes",
                              padx=10,
                              pady=5)

        # 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("TELLO Controller")
        self.root.wm_protocol("WM_DELETE_WINDOW", self.onClose)

        # the auto-takeoff thread will start if the 'takeoff' button on command window is clicked
        self.auto_takeoff_thread = threading.Thread(target=self._autoTakeoff)
        # the sending_command will send command to tello every 5 seconds
        self.sending_command_thread = threading.Thread(
            target=self._sendingCommand)
        self.get_GUI_Image_thread = threading.Thread(target=self._getGUIImage)

    def videoLoop(self):
        """
        The mainloop thread of Tkinter 
        Raises:
            RuntimeError: To get around a RunTime error that Tkinter throws due to threading.
        """
        try:
            # start the thread that get GUI image and drwa skeleton
            time.sleep(0.5)
            self.get_GUI_Image_thread.start()
            while not self.stopEvent.is_set():
                # read the frame for pose recognition
                self.frame = self.tello.read()
                if self.frame is None or self.frame.size == 0:
                    continue
                # smoothing filter
                self.frame = cv2.bilateralFilter(self.frame, 5, 50, 100)

                cmd = ''
                self.points.append(None)
                # process pose-recognition
                if self.pose_mode:
                    cmd, self.draw_skeleton_flag, self.points = self.my_tello_pose.detect(
                        self.frame)

                # process command - map your motion to whatever Tello movement you want!
                if cmd == 'moveback':
                    self.telloMoveBackward(0.50)
                elif cmd == 'moveforward':
                    self.telloMoveForward(0.50)
                elif cmd == 'land':
                    self.telloLanding()

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

    def _getGUIImage(self):
        """
        Main operation to read frames from h264decoder and draw skeleton on 
        frames if the pose mode is opened
        """
        # read the system of your computer
        system = platform.system()
        while not self.stopEvent.is_set():
            # read the frame for GUI show
            frame = self.tello.read()
            if frame is None or frame.size == 0:
                continue
            if self.pose_mode:
                # Draw the detected skeleton points
                for i in range(15):
                    if self.draw_skeleton_flag == True:
                        cv2.circle(frame,
                                   self.points[i],
                                   8, (0, 255, 255),
                                   thickness=-1,
                                   lineType=cv2.FILLED)
                        cv2.putText(frame,
                                    "{}".format(i),
                                    self.points[i],
                                    cv2.FONT_HERSHEY_SIMPLEX,
                                    1, (0, 0, 255),
                                    2,
                                    lineType=cv2.LINE_AA)
                # Draw Skeleton
                for pair in self.POSE_PAIRS:
                    partA = pair[0]
                    partB = pair[1]
                    if self.points[partA] and self.points[partB]:
                        cv2.line(frame, self.points[partA], self.points[partB],
                                 (0, 255, 255), 2)
                        cv2.circle(frame,
                                   self.points[partA],
                                   8, (0, 0, 255),
                                   thickness=-1,
                                   lineType=cv2.FILLED)

            # transfer the format from frame to image
            image = Image.fromarray(frame)

            # we found compatibility problem between Tkinter,PIL and Macos,and it will
            # sometimes result the very long preriod of the "ImageTk.PhotoImage" function,
            # so for Macos,we start a new thread to execute the _updateGUIImage function.
            if system == "Windows" or system == "Linux":
                self._updateGUIImage(image)

            else:
                thread_tmp = threading.Thread(target=self._updateGUIImage,
                                              args=(image, ))
                thread_tmp.start()
                time.sleep(0.03)

    def _updateGUIImage(self, image):
        """
        Main operation to initial the object of image,and update the GUI panel 
        """
        image = ImageTk.PhotoImage(image)
        # if the panel none ,we need to initial 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

    def _autoTakeoff(self):
        """
        Firstly,it will waiting for the response that will be sent by Tello if Tello 
        
        finish the takeoff command.If computer doesn't receive the response,it may be
        
        because tello doesn't takeoff normally,or because the UDP pack of response is
        
        lost.So in order to confirm the reason,computer will send 'height?'command to
        
        get several real-time height datas and get a average value.If the height is in
        
        normal range,tello will execute the moveup command.Otherwise,tello will land.
        
        Finally,the sending-command thread will start.
        """
        response = None
        height_tmp = 0  # temp variable to content value of height
        height_val = 0  # average value of height
        cnt = 0  # effective number of height reading
        timeout = 6  # max waiting time of tello's response

        timer = threading.Timer(timeout, self._setQuitWaitingFlag)
        timer.start()

        # waiting for the response from tello
        while response != 'ok':
            if self.quit_waiting_flag is True:
                break
            response = self.tello.get_response()
            print("ack:%s" % response)
        timer.cancel()

        # receive the correct response
        if response == 'ok':
            self.tello.move_up(0.5)

        # calculate the height of tello
        else:
            for i in range(0, 50):
                height_tmp = self.tello.get_height()
                try:
                    height_val = height_val + height_tmp
                    cnt = cnt + 1
                    print(height_tmp, cnt)
                except:
                    height_val = height_val

            height_val = height_val / cnt

            # if the height value is in normal range
            if height_val == 9 or height_val == 10 or height_val == 11:
                self.tello.move_up(0.5)
            else:
                self.tello.land()
        # start the sendingCmd thread
        self.sending_command_thread.start()

    def _sendingCommand(self):
        """
        start a while loop that sends 'command' to tello every 5 second
        """

        while True:
            self.tello.send_command('command')
            time.sleep(5)

    def _setQuitWaitingFlag(self):
        """
        set the variable as TRUE,it will stop computer waiting for response from tello  
        """
        self.quit_waiting_flag = True

    def openCmdWindow(self):
        """
        open the cmd window and initial all the button and text
        """
        panel = Toplevel(self.root)
        panel.wm_title("Command Panel")

        # create text input entry
        text0 = tki.Label(
            panel,
            text=
            'This Controller map keyboard inputs to Tello control commands\n'
            'Adjust the trackbar to reset distance and degree parameter',
            font='Helvetica 10 bold')
        text0.pack(side='top')

        text1 = tki.Label(
            panel,
            text='W - Move Tello Up\t\t\tArrow Up - Move Tello Forward\n'
            'S - Move Tello Down\t\t\tArrow Down - Move Tello Backward\n'
            'A - Rotate Tello Counter-Clockwise\tArrow Left - Move Tello Left\n'
            'D - Rotate Tello Clockwise\t\tArrow Right - Move Tello Right',
            justify="left")
        text1.pack(side="top")

        self.btn_landing = tki.Button(panel,
                                      text="Land",
                                      relief="raised",
                                      command=self.telloLanding)
        self.btn_landing.pack(side="bottom",
                              fill="both",
                              expand="yes",
                              padx=10,
                              pady=5)

        self.btn_takeoff = tki.Button(panel,
                                      text="Takeoff",
                                      relief="raised",
                                      command=self.telloTakeOff)
        self.btn_takeoff.pack(side="bottom",
                              fill="both",
                              expand="yes",
                              padx=10,
                              pady=5)

        # binding arrow keys to drone control
        self.tmp_f = tki.Frame(panel, width=100, height=2)
        self.tmp_f.bind('<KeyPress-w>', self.on_keypress_w)
        self.tmp_f.bind('<KeyPress-s>', self.on_keypress_s)
        self.tmp_f.bind('<KeyPress-a>', self.on_keypress_a)
        self.tmp_f.bind('<KeyPress-d>', self.on_keypress_d)
        self.tmp_f.bind('<KeyPress-Up>', self.on_keypress_up)
        self.tmp_f.bind('<KeyPress-Down>', self.on_keypress_down)
        self.tmp_f.bind('<KeyPress-Left>', self.on_keypress_left)
        self.tmp_f.bind('<KeyPress-Right>', self.on_keypress_right)
        self.tmp_f.pack(side="bottom")
        self.tmp_f.focus_set()

        self.btn_landing = tki.Button(panel,
                                      text="Flip",
                                      relief="raised",
                                      command=self.openFlipWindow)
        self.btn_landing.pack(side="bottom",
                              fill="both",
                              expand="yes",
                              padx=10,
                              pady=5)

        self.distance_bar = Scale(panel,
                                  from_=0.02,
                                  to=5,
                                  tickinterval=0.01,
                                  digits=3,
                                  label='Distance(m)',
                                  resolution=0.01)
        self.distance_bar.set(0.2)
        self.distance_bar.pack(side="left")

        self.btn_distance = tki.Button(
            panel,
            text="Reset Distance",
            relief="raised",
            command=self.updateDistancebar,
        )
        self.btn_distance.pack(side="left",
                               fill="both",
                               expand="yes",
                               padx=10,
                               pady=5)

        self.degree_bar = Scale(panel,
                                from_=1,
                                to=360,
                                tickinterval=10,
                                label='Degree')
        self.degree_bar.set(30)
        self.degree_bar.pack(side="right")

        self.btn_distance = tki.Button(panel,
                                       text="Reset Degree",
                                       relief="raised",
                                       command=self.updateDegreebar)
        self.btn_distance.pack(side="right",
                               fill="both",
                               expand="yes",
                               padx=10,
                               pady=5)

    def openFlipWindow(self):
        """
        open the flip window and initial all the button and text
        """

        panel = Toplevel(self.root)
        panel.wm_title("Gesture Recognition")

        self.btn_flipl = tki.Button(panel,
                                    text="Flip Left",
                                    relief="raised",
                                    command=self.telloFlip_l)
        self.btn_flipl.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

        self.btn_flipr = tki.Button(panel,
                                    text="Flip Right",
                                    relief="raised",
                                    command=self.telloFlip_r)
        self.btn_flipr.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

        self.btn_flipf = tki.Button(panel,
                                    text="Flip Forward",
                                    relief="raised",
                                    command=self.telloFlip_f)
        self.btn_flipf.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

        self.btn_flipb = tki.Button(panel,
                                    text="Flip Backward",
                                    relief="raised",
                                    command=self.telloFlip_b)
        self.btn_flipb.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

    def takeSnapshot(self):
        """
        save the current frame of the video as a jpg file and put it into outputpath
        """

        # grab the current timestamp and use it to construct the filename
        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, cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR))
        print(("[INFO] saved {}".format(filename)))

    def setPoseMode(self):
        """
        Toggle the open/close of pose recognition mode
        """
        if self.pose_mode is False:
            self.pose_mode = True
            self.btn_pose.config(text='Pose Recognition Status: On')
        else:
            self.pose_mode = False
            self.btn_pose.config(text='Pose Recognition Status: Off')

    def pauseVideo(self):
        """
        Toggle the freeze/unfreze of video
        """
        if self.btn_pause.config('relief')[-1] == 'sunken':
            self.btn_pause.config(relief="raised")
            self.tello.video_freeze(False)
        else:
            self.btn_pause.config(relief="sunken")
            self.tello.video_freeze(True)

    def telloTakeOff(self):
        """
        send the takeoff command to tello,and wait for the first response,
        
        if get the 'error'response,remind the "battery low" warning.Otherwise,
        
        start the auto-takeoff thread
        """
        takeoff_response = None

        self.tello.takeoff()
        time.sleep(0.2)

        takeoff_response = self.tello.get_response()

        if takeoff_response != 'error':
            self.auto_takeoff_thread.start()
        else:
            print("battery low,please repalce with a new one")

    def telloLanding(self):
        return self.tello.land()

    def telloFlip_l(self):
        return self.tello.flip('l')

    def telloFlip_r(self):
        return self.tello.flip('r')

    def telloFlip_f(self):
        return self.tello.flip('f')

    def telloFlip_b(self):
        return self.tello.flip('b')

    def telloCW(self, degree):
        return self.tello.rotate_cw(degree)

    def telloCCW(self, degree):
        return self.tello.rotate_ccw(degree)

    def telloMoveForward(self, distance):
        return self.tello.move_forward(distance)

    def telloMoveBackward(self, distance):
        return self.tello.move_backward(distance)

    def telloMoveLeft(self, distance):
        return self.tello.move_left(distance)

    def telloMoveRight(self, distance):
        return self.tello.move_right(distance)

    def telloUp(self, dist):
        return self.tello.move_up(dist)

    def telloDown(self, dist):
        return self.tello.move_down(dist)

    def updateTrackBar(self):
        self.my_tello_hand.setThr(self.hand_thr_bar.get())

    def updateDistancebar(self):
        self.distance = self.distance_bar.get()
        print('reset distance to %.1f' % self.distance)

    def updateDegreebar(self):
        self.degree = self.degree_bar.get()
        print('reset distance to %d' % self.degree)

    def on_keypress_w(self, event):
        print("up %d m" % self.distance)
        self.telloUp(self.distance)

    def on_keypress_s(self, event):
        print("down %d m" % self.distance)
        self.telloDown(self.distance)

    def on_keypress_a(self, event):
        print("ccw %d degree" % self.degree)
        self.tello.rotate_ccw(self.degree)

    def on_keypress_d(self, event):
        print("cw %d m" % self.degree)
        self.tello.rotate_cw(self.degree)

    def on_keypress_up(self, event):
        print("forward %d m" % self.distance)
        self.telloMoveForward(self.distance)

    def on_keypress_down(self, event):
        print("backward %d m" % self.distance)
        self.telloMoveBackward(self.distance)

    def on_keypress_left(self, event):
        print("left %d m" % self.distance)
        self.telloMoveLeft(self.distance)

    def on_keypress_right(self, event):
        print("right %d m" % self.distance)
        self.telloMoveRight(self.distance)

    def on_keypress_enter(self, event):
        if self.frame is not None:
            self.registerFace()
        self.tmp_f.focus_set()

    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()
        del self.tello
        self.root.quit()
Beispiel #6
0
class Visual(Frame):
    '''Class that takes a world as argument and present it graphically
    on a tkinter canvas.'''

    def __init__(self):
        '''
        Sets up a simulation GUI in tkinter.
        '''
        Frame.__init__(self)
        self.master.title("The Schelling Segregation Model in Python")
        self.master.wm_resizable(0, 0)
        self.grid()
        self.movement_possible = True

        # --------------------------------------- #
        # --------- FRAMES FOR GUI -------------- #
        # --------------------------------------- #

        # The pane for user values
        self._entryPane = Frame(self,
                                borderwidth=5,
                                relief='sunken')
        self._entryPane.grid(row=0, column=0, sticky='n')

        # The buttons pane
        self._buttonPane = Frame(self, borderwidth=5)
        self._buttonPane.grid(row=1, column=0, sticky='n')

        # A temp pane where graph is located, just for cosmetic reasons
        width, height = 425, 350
        self._graph = Canvas(self,
                             width=width,
                             height=height,
                             background="black")
        self._graph.configure(relief='sunken', border=2)
        self._graph.grid(row=3, column=0)

        # The pane where the canvas is located
        self._animationPane = Frame(self,
                                    borderwidth=5,
                                    relief='sunken')
        self._animationPane.grid(row=0, column=1,
                                 rowspan=4, pady=10,
                                 sticky="n")

        # --------------------------------------- #
        # --------- FILLING THE FRAMES ---------- #
        # --------------------------------------- #

        self._canvas()      # Create graphics canvas
        self._entry()       # Create entry widgets
        self._buttons()     # Create button widgets

    def _plot_setup(self, time):
        '''Method for crudely annotating the graph window.'''
        time = time

        # Main plot
        width, height = 425, 350
        y0 = -time/10
        self._graph = Canvas(self, width=width,
                             height=height,
                             background="black",
                             borderwidth=5)
        self._graph.grid(row=3, column=0)
        self.trans = Plotcoords(width, height, y0, -0.2, time, 1.3)

        x, y = self.trans.screen(time // 2, 1.2)
        x1, y1 = self.trans.screen(time // 2, 1.13)
        self._graph.create_text(x, y,
                                text="% Happy",
                                fill="green",
                                font="bold 12")
        
        self._graph.create_text(x1, y1,
                                text="% Unhappy",
                                fill="red",
                                font="bold 12")
 
        # Line x-axis
        x, y = self.trans.screen((-5 * (time / 100)), -0.05)
        x1, y = self.trans.screen(time, -0.05)
        self._graph.create_line(x, y, x1, y, fill="white", width=1.5)
         
        # Text x-axis
        x_text, y_text = self.trans.screen(time / 2, -0.15)
        self._graph.create_text(x_text, y_text,
                                text="Time",
                                fill="white",
                                font="bold 12")

        # Line y-axis
        x, y = self.trans.screen((-0.5 * (time / 100)), -0.05)
        x, y1 = self.trans.screen((-5 * (time / 100)), 1)
        self._graph.create_line(x, y, x, y1, fill="white", width=1.5)
 
    def _entry(self):
        '''Method for creating widgets for collecting user input.'''
         
        # N (no of turtles)
        dim = 30*30

        self.fill_label = Label(self._entryPane,
                                anchor='w',
                                justify='left',
                                text='Fill',
                                relief='raised',
                                width=12,
                                height=1,
                                font='italic 20')
        
        self.fill_label.grid(row=0, column=1, ipady=14)

        self.fill = Scale(self._entryPane,
                          from_=0,
                          to=1,
                          resolution=0.01,
                          bd=3,
                          relief='sunken',
                          orient='horizontal',
                          length=235,
                          tickinterval=20)
        self.fill.grid(row=0, column=2)
        self.fill.set(0.8)
                           
        self._N_label = Label(self._entryPane,
                              anchor='w',
                              justify='left',
                              text="N:",
                              relief='raised',
                              width=12,
                              height=1,
                              font="italic 20")
        self._N_label.grid(row=1, column=1, ipady=14)

        self._N = Scale(self._entryPane,
                        from_=0,
                        to=100,
                        resolution=1,
                        bd=3,
                        relief='sunken',
                        orient='horizontal',
                        length=235,
                        tickinterval=20)
        self._N.set(30)
        self._N.grid(row=1, column=2)

        # Ticks (length of simulation)
        self._Ticks_label = Label(self._entryPane,
                                  anchor='w',
                                  justify='left',
                                  text="Time:",
                                  relief='raised',
                                  width=12,
                                  height=1,
                                  font="bold 20")
        self._Ticks_label.grid(row=2, column=1, ipady=14)
 
        self._Ticks = Scale(self._entryPane,
                            from_=10,
                            to=1000,
                            resolution=1,
                            bd=3,
                            relief='sunken',
                            orient='horizontal',
                            length=235,
                            tickinterval=990)
        self._Ticks.set(500)
        self._Ticks.grid(row=2, column=2)
 
        # % similar wanted
        self._Similar_label = Label(self._entryPane,
                                    anchor='w',
                                    justify='left',
                                    text="Similar wanted:",
                                    relief='raised',
                                    width=12,
                                    height=1,
                                    font="bold 20")
         
        self._Similar_label.grid(row=3, column=1, ipady=14)
 
        self._Similar = Scale(self._entryPane,
                              from_=0.0,
                              to=1.0,
                              resolution=0.01,
                              bd=3,
                              relief='sunken',
                              orient='horizontal',
                              length=235,
                              tickinterval=0.5)
        self._Similar.set(0.76)
        self._Similar.grid(row=3, column=2)

        # Delay between steps
        self._delay_label = Label(self._entryPane,
                                  anchor='w',
                                  justify='left',
                                  text="Delay (s):",
                                  relief='raised',
                                  width=12,
                                  height=1,
                                  font="bold 20")
         
        self._delay_label.grid(row=4, column=1, ipady=14)
 
        self._delay = Scale(self._entryPane,
                            from_=0.0,
                            to=1.0,
                            resolution=0.01,
                            bd=3,
                            relief='sunken',
                            orient='horizontal',
                            length=235,
                            tickinterval=0.5)
        self._delay.set(0.15)
        self._delay.grid(row=4, column=2)

    def _buttons(self):
        '''Method for creating button widgets for setting up,
        running and plotting results from simulation.'''
        width = 7
        height = 1

        # The 'Setup' button
        self._setupButton = Button(self._buttonPane,
                                   text="Setup",
                                   command=self._setup,
                                   width=width,
                                   height=height,
                                   font="bold 30",
                                   relief='raised',
                                   borderwidth=5)
        self._setupButton.grid(row=0, column=0)

        # The 'Go' button
        self._goButton = Button(self._buttonPane,
                                text="Go",
                                command=self._go,
                                width=width,
                                height=height,
                                font="bold 30",
                                relief='raised',
                                borderwidth=5)
        self._goButton.grid(row=0, column=1)

        # The 'Quit' button
        self._quitButton = Button(self._buttonPane,
                                  text="Quit",
                                  command=self._quit,
                                  width=width,
                                  height=height,
                                  font="bold 30",
                                  relief='raised',
                                  borderwidth=5)
        self._quitButton.grid(row=1, column=0, columnspan=2)

    def _canvas(self):
        '''Creates the canvas on which everything happens.'''
        # The tick counter information
        self._Tick_counter = Label(self._animationPane,
                                   anchor='w',
                                   justify='left',
                                   text="Time:",
                                   width=5,
                                   font="bold 20")
        self._Tick_counter.grid(row=0, column=0, sticky="e")
        self._Tick_counter1 = Label(self._animationPane,
                                    justify='center',
                                    text="",
                                    relief='raised',
                                    width=5,
                                    font="bold 20")
        self._Tick_counter1.grid(row=0, column=1, sticky='w')
        self.canvas_w, self.canvas_h = 750, 750
        self.canvas = Canvas(self._animationPane,
                             width=self.canvas_w,
                             height=self.canvas_h,
                             background="black")

        self.canvas.grid(row=1, column=0, columnspan=2)

    def _setup(self):
        '''Method for 'Setup' button.'''
        # Clearing the canvas and reset the go button
        self.canvas.delete('all')
        self._goButton['relief'] = 'raised'
        self.N = int(self._N.get())
        self.Ticks = int(self._Ticks.get())
        self.similar = float(self._Similar.get())
        self.data = []
        self.tick_counter = 0
        self._Tick_counter1['text'] = str(self.tick_counter)
        self._plot_setup(self.Ticks)
        self.grid_size = self.N
        self.world = World(750, 750, self.grid_size)
        self.create_turtles()
        self.neighbouring_turtles()
        self.draw_turtles()

    def _go(self):
        '''Method for the 'Go' button, i.e. running the simulation.'''
        self._goButton['relief'] = 'sunken'
        if self.tick_counter <= self.Ticks:
            self._Tick_counter1['text'] = str(self.tick_counter)
            self.canvas.update()

            self._graph.update()
            self._graph.after(0)

            # Data collection
            turtles_unhappy = self.check_satisfaction()
            prop_happy, prop_unhappy = self.calc_prop_happy(self.tick_counter)

            self.data_collection(self.tick_counter, prop_happy, prop_unhappy)

            if self.tick_counter >= 1:

                # HAPPY values (%)
                x0 = self.tick_counter-1
                x1 = self.tick_counter

                # Collecting values from stored data
                y0 = self.data[self.tick_counter-1][1]
                y1 = self.data[self.tick_counter][1]

                # Transforming to tkinter
                x1, y1 = self.trans.screen(x1, y1)
                x0, y0 = self.trans.screen(x0, y0)
                self._graph.create_line(x0, y0, x1, y1,
                                        fill="green", width=1.3,
                                        tag="happy")  # Draw "happy lines

                # UNHAPPY values (%)
                x0 = self.tick_counter-1
                x1 = self.tick_counter

                # Collecting values from stored data
                y0 = self.data[self.tick_counter-1][2]
                y1 = self.data[self.tick_counter][2]

                # Transforming to tkinter
                x1, y1 = self.trans.screen(x1, y1)
                x0, y0 = self.trans.screen(x0, y0)
                self._graph.create_line(x0, y0, x1, y1,
                                        fill="red", width=1.1,
                                        tag="unhappy")  # Draw unhappy lines
             
            if prop_happy < 1:
                self.turtle_move(turtles_unhappy)
                time.sleep(self._delay.get())
                self.update_neighbours()
                self.tick_counter += 1
                self.canvas.after(0, self._go())

        self._goButton['relief'] = 'raised'

    def _quit(self):
        '''Method for the 'Quit' button.'''
        self.master.destroy()

    # ------------------------------------------------------ #
    # ---------- FUNCTIONS CALLED AT EACH TICK ------------- #
    # ------------------------------------------------------ #

    def turtle_move(self, unhappy_turtles):
        '''Moves all the unhappy turtles (randomly).'''
         
        while unhappy_turtles:
            i = random.randint(0, len(unhappy_turtles)-1)
            turtle = unhappy_turtles.pop(i)
            turtle.move(self)

    def update_neighbours(self):
        '''Updates the turtles neigbour attributes. Called
        after all turtles have moved.'''
        for turtle in self.turtles:
            turtle.update_neighbours()

    def check_satisfaction(self):
        '''Checks to see if turtles are happy or not.
        Returns a list of unhappy turtles, i.e. turtles
        that should move.

        Called before the move method.'''

        for turtle in self.turtles:
            turtle.is_happy()

        unhappy_turtles = []
        for element in self.turtles:
            if not element.happy:
                unhappy_turtles.append(element)

        return unhappy_turtles

    def calc_prop_happy(self, i):
        '''Calculates the proportion of happy turtles.'''
        happy = 0
        unhappy = 0

        for turtle in self.turtles:
            if turtle.happy:
                happy += 1
            else:
                unhappy += 1
        prop_happy = happy/len(self.turtles)
        prop_unhappy = unhappy/len(self.turtles)

        return prop_happy, prop_unhappy

    def data_collection(self, i, prop_happy, prop_unhappy):
        '''Method for collecting data at each tick.'''
        self.data.append((i, prop_happy, prop_unhappy))


# ------------------------------------------------------ #
# ---------- INITIALISATION FUNCTIONS ------------------ #
# ------------------------------------------------------ #

    def create_turtles(self):
        '''Method for creating a new list of turtles.

        Upon creation they are registered in the World object.'''
        if self.N*self.N <= self.grid_size*self.grid_size:
            counter = 0
            self.turtles = []
            while counter < self.N * self.N * self.fill.get():
                             
                s = "S"+str(counter)
                if counter <= int(self.N * self.N * self.fill.get() / 2):
                    color = "green"
                else:
                    color = "red"

                x = random.randint(0, self.grid_size-1)
                y = random.randint(0, self.grid_size-1)

                if not self.world.patch_list[x][y]:
                    new_turtle = Schelling(world=self.world,
                                           x=x,
                                           y=y,
                                           s=s,
                                           color=color,
                                           similar_wanted=self.similar)

                    self.world.register(new_turtle)
                    counter += 1
                    self.turtles.append(new_turtle)
        else:
            print("Number of turtles exceeds world!")

    def draw_turtles(self):
        '''Method for drawing turtles on canvas.

           Calls each turtle's own method for drawing.'''
        for turtle in self.turtles:
            turtle.draw(self.canvas)
 
    def neighbouring_turtles(self):
        '''Method for updating turtles' neighbours.

           Calls on each turtle's own method for updating neighbours.'''
        for turtle in self.turtles:
            turtle.get_neighbouring_patches()
Beispiel #7
0
gain_label = Label(slider_frame, text='gain', font=('monospace'))
gain_label.grid(row=1, column=0)
reverb_label = Label(slider_frame, text='reverb', font=('monospace'))
reverb_label.grid(row=1, column=1)
chorus_label = Label(slider_frame, text='chorus', font=('monospace'))
chorus_label.grid(row=1, column=2)
#gain slider
gain_slider = Scale(slider_frame,
                    from_=10,
                    to=0,
                    width=50,
                    length=250,
                    command=lambda x: gain_command_change(
                        gain_slider.get(), client_connection))
gain_slider.set(2)
gain_slider.grid(row=0, column=0)

#reverb slider
rev_slider = Scale(
    slider_frame,
    from_=30,
    to=0,
    width=50,
    length=250,
    command=lambda x: rev_slider_change(rev_slider.get(), client_connection))
rev_slider.set(0)
rev_slider.grid(row=0, column=1)

chorus_slider = Scale(slider_frame,
                      from_=30,
Beispiel #8
0
class OfflineVisualiser(Visualiser):
    """A VTK-powered offline visualiser which runs in its own thread.
    In addition to the functions provided by the standard visualiser,
    the following additional functions are provided:

    precache_height_quantities() - Precache all the vtkpoints
    structures for any dynamic height based quantities to render.
    """
    def __init__(self, source, frameDelay=100, frameStep=1):
        """The source parameter is assumed to be a NetCDF sww file.
        The frameDelay parameter is the number of milliseconds waited between frames.
        """
        Visualiser.__init__(self, source)

        self.frameNumber = 0
        fin = NetCDFFile(self.source, 'r')
        self.maxFrameNumber = fin.variables['time'].shape[0] - 1
        fin.close()

        #self.frameNumberTkVariable = StringVar()
        #self.frameNumberTkVariable.set('Frame - %05g'%self.framNumber)

        self.frameDelay = frameDelay

        self.xmin = None
        self.xmax = None
        self.ymin = None
        self.ymax = None
        self.zmin = None
        self.zmax = None

        self.frameStep = frameStep

        self.vtk_heightQuantityCache = []
        for i in range(self.maxFrameNumber +
                       1):  # maxFrameNumber is zero indexed.
            self.vtk_heightQuantityCache.append({})

        self.paused = False
        self.movie = False

    def setup_grid(self):
        fin = NetCDFFile(self.source, 'r')
        self.vtk_cells = vtkCellArray()
        N_tri = fin.variables['volumes'].shape[0]
        for v in range(N_tri):
            self.vtk_cells.InsertNextCell(3)
            for i in range(3):
                self.vtk_cells.InsertCellPoint(fin.variables['volumes'][v][i])
        fin.close()

    def update_height_quantity(self, quantityName, dynamic=True):
        polydata = self.vtk_polyData[quantityName] = vtkPolyData()
        if dynamic is True:
            #print ' - Frame',self.frameNumber,'of',self.maxFrameNumber
            if quantityName not in self.vtk_heightQuantityCache[
                    self.frameNumber]:
                self.vtk_heightQuantityCache[self.frameNumber][quantityName]\
                    = self.read_height_quantity(quantityName, True, self.frameNumber)
            polydata.SetPoints(
                self.vtk_heightQuantityCache[self.frameNumber][quantityName])
        else:
            polydata.SetPoints(self.read_height_quantity(quantityName, False))
        polydata.SetPolys(self.vtk_cells)

    def get_3d_bounds(self):
        return [
            self.xmin, self.xmax, self.ymin, self.ymax, self.zmin, self.zmax
        ]

    def read_height_quantity(self, quantityName, dynamic=True, frameNumber=0):
        """Read in a height based quantity from the NetCDF source file
        and return a vtkPoints object. frameNumber is ignored if
        dynamic is false."""
        fin = NetCDFFile(self.source, 'r')
        points = vtkPoints()
        if dynamic is True:
            N_vert = fin.variables[quantityName].shape[1]
        else:
            N_vert = len(fin.variables[quantityName])
        x = num.ravel(num.array(fin.variables['x'], num.float))
        y = num.ravel(num.array(fin.variables['y'], num.float))
        if dynamic is True:
            q = num.array(fin.variables[quantityName][frameNumber], num.float)
        else:
            q = num.ravel(num.array(fin.variables[quantityName], num.float))

        q *= self.height_zScales[quantityName]
        q += self.height_offset[quantityName]

        for v in range(N_vert):
            points.InsertNextPoint(x[v], y[v], q[v])
            if self.xmin is None or self.xmin > x[v]:
                self.xmin = x[v]
            if self.xmax is None or self.xmax < x[v]:
                self.xmax = x[v]
            if self.ymin is None or self.ymin > y[v]:
                self.ymin = y[v]
            if self.ymax is None or self.ymax < y[v]:
                self.ymax = y[v]
            if self.zmin is None or self.zmin > q[v]:
                self.zmin = q[v]
            if self.zmax is None or self.zmax < q[v]:
                self.zmax = q[v]
        fin.close()
        return points

    def precache_height_quantities(self):
        """Precache any height-based quantities. Call before rendering
        beigns."""
        for q in self.height_quantities:
            if self.height_dynamic[q] is True:
                print('Precaching %s' % q)
                for i in range(self.maxFrameNumber +
                               1):  # maxFrameNumber is zero-indexed
                    print(' - Frame %d of %d' % (i, self.maxFrameNumber))
                    self.vtk_heightQuantityCache[i][q]\
                        = self.read_height_quantity(q, True, i)

    def build_quantity_dict(self):
        quantities = {}
        fin = NetCDFFile(self.source, 'r')
        for q in [
                n for n in list(fin.variables.keys()) if n != 'x' and n != 'y'
                and n != 'z' and n != 'time' and n != 'volumes'
        ]:
            if len(fin.variables[q].shape) == 1:  # Not a time-varying quantity
                quantities[q] = num.ravel(
                    num.array(fin.variables[q], num.float))
            else:  # Time-varying, get the current timestep data
                quantities[q] = num.array(fin.variables[q][self.frameNumber],
                                          num.float)
        fin.close()
        return quantities

    def setup_gui(self):
        Visualiser.setup_gui(self)
        self.tk_quit.grid(row=0, column=0, sticky=W + E)
        self.tk_movie_toggle = Button(self.tk_controlFrame,
                                      text="Movie off",
                                      command=self.movie_toggle)
        self.tk_movie_toggle.grid(row=0, column=6, sticky=W + E)

        self.tk_restart = Button(self.tk_controlFrame,
                                 text="<<<",
                                 command=self.restart,
                                 width=5)
        self.tk_restart.grid(row=1, column=0, sticky=W + E)
        self.tk_back10 = Button(self.tk_controlFrame,
                                text="<<",
                                command=self.back10,
                                width=5)
        self.tk_back10.grid(row=1, column=1, sticky=W + E)
        self.tk_back = Button(self.tk_controlFrame,
                              text="<",
                              command=self.back,
                              width=5)
        self.tk_back.grid(row=1, column=2, sticky=W + E)
        self.tk_pauseResume = Button(self.tk_controlFrame,
                                     text="Pause",
                                     command=self.pauseResume,
                                     width=15)
        self.tk_pauseResume.grid(row=1, column=3, sticky=W + E)
        self.tk_forward = Button(self.tk_controlFrame,
                                 text=">",
                                 command=self.forward,
                                 width=5)
        self.tk_forward.grid(row=1, column=4, sticky=W + E)
        self.tk_forward10 = Button(self.tk_controlFrame,
                                   text=">>",
                                   command=self.forward10,
                                   width=5)
        self.tk_forward10.grid(row=1, column=5, sticky=W + E)
        self.tk_forwardEnd = Button(self.tk_controlFrame,
                                    text=">>>",
                                    command=self.forwardEnd,
                                    width=5)
        self.tk_forwardEnd.grid(row=1, column=6, sticky=W + E)

        self.tk_frameNumber = Label(self.tk_controlFrame, text='Frame')
        self.tk_frameNumber.grid(row=2, column=0, sticky=W + E)
        self.tk_gotoFrame = Scale(self.tk_controlFrame,
                                  from_=0,
                                  to=self.maxFrameNumber,
                                  orient=HORIZONTAL)
        self.tk_gotoFrame.grid(row=2, column=1, columnspan=2, sticky=W + E)
        self.tk_stepLabel = Label(self.tk_controlFrame, text='Step')
        self.tk_stepLabel.grid(row=2, column=4, sticky=W + E)
        self.tk_frameStep = Scale(self.tk_controlFrame,
                                  from_=0,
                                  to=self.maxFrameNumber,
                                  orient=HORIZONTAL)
        self.tk_frameStep.grid(row=2, column=5, columnspan=2, sticky=W + E)

        # Make the buttons stretch to fill all available space
        for i in range(7):
            self.tk_controlFrame.grid_columnconfigure(i, weight=1)

    def run(self):
        self.alter_tkroot(Tk.after, (self.frameDelay, self.animateForward))
        Visualiser.run(self)

    def restart(self):
        self.frameNumber = 0
        self.redraw_quantities()
        self.update_labels()
        self.pause()

        if self.movie:
            self.save_image()

    def forwardEnd(self):
        self.frameNumber = self.maxFrameNumber
        self.redraw_quantities()
        self.update_labels()
        self.pause()

    def movie_toggle(self):
        if self.movie == True:
            self.movie = False
            self.tk_movie_toggle.config(text='Movie off')
        else:
            self.movie = True
            self.tk_movie_toggle.config(text='Movie on ')

    def save_image(self):

        from vtk import vtkJPEGWriter, vtkJPEGWriter, vtkPNGWriter
        from vtk import vtkPNMWriter, vtkWindowToImageFilter
        from os import path

        sourcebase, _ = path.splitext(self.source)
        fname = sourcebase + '%05g.png' % self.frameNumber
        #print fname

        extmap = {
            '.jpg': vtkJPEGWriter,
            '.jpeg': vtkJPEGWriter,
            '.png': vtkPNGWriter,
            '.pnm': vtkPNMWriter,
        }
        basename, ext = path.splitext(fname)
        try:
            Writer = extmap[ext.lower()]
        except KeyError:
            error_msg("Don't know how to handle %s files" % ext, parent=self)
            return

        renWin = self.vtk_renderer.GetRenderWindow()
        w2i = vtkWindowToImageFilter()
        writer = Writer()
        w2i.SetInput(renWin)
        w2i.Update()
        writer.SetInput(w2i.GetOutput())
        writer.SetFileName(fname)
        renWin.Render()
        writer.Write()

    def back10(self):
        if self.frameNumber - 10 >= 0:
            self.frameNumber -= 10
        else:
            self.frameNumber = 0
        self.redraw_quantities()
        self.update_labels()
        self.pause()

    def back(self):
        if self.frameNumber > 0:
            self.frameNumber -= 1
            self.redraw_quantities()
            self.update_labels()
            self.pause()

    def pauseResume(self):
        if self.paused is True:
            self.resume()
        else:
            self.pause()

    def pause(self):
        self.paused = True
        self.tk_pauseResume.config(text="Resume")

    def resume(self):
        self.paused = False
        self.tk_pauseResume.config(text="Pause")
        self.frameNumber = self.tk_gotoFrame.get()
        self.frameStep = self.tk_frameStep.get()
        self.tk_root.after(self.frameDelay, self.animateForward)

    def forward(self):
        if self.frameNumber < self.maxFrameNumber:
            self.frameNumber += 1
            self.redraw_quantities()
            self.update_labels()
            self.pause()

    def forward_step(self):
        if self.frameNumber + self.frameStep <= self.maxFrameNumber:
            self.frameNumber += self.frameStep
            self.redraw_quantities()
            self.update_labels()
        else:
            self.frameNumber = self.maxFrameNumber
            self.redraw_quantities()
            self.update_labels()
            self.pause()

        if self.movie:
            self.save_image()

    def forward10(self):
        if self.frameNumber + 10 <= self.maxFrameNumber:
            self.frameNumber += 10
        else:
            self.frameNumber = self.maxFrameNumber
        self.redraw_quantities()
        self.update_labels()
        self.pause()

    def animateForward(self):
        if self.paused is not True:
            self.forward_step()
            self.tk_root.after(self.frameDelay, self.animateForward)

    def update_labels(self):
        #self.tk_frameNumber.config(text='%05g of %05g'%(self.frameNumber,self.maxFrameNumber))
        self.tk_gotoFrame.set(self.frameNumber)
        self.tk_frameStep.set(self.frameStep)

    def shutdown(self):
        #self.pause()
        self.tk_root.withdraw()
        self.tk_root.destroy()
from tkinter import Tk, Canvas, Scale, VERTICAL


def setHeight(canvas, heightStr):
    height = 21
    height = height + 21
    y2 = height - 30
    print(heightStr)  #holds current scale pointer
    if y2 < 21:
        y2 = 21


root = Tk()
root.title('Scale')

canvas = Canvas(root, width=65, height=50, bd=0, highlightthickness=0)
scale = Scale(root,
              orient=VERTICAL,
              length=284,
              from_=0,
              to=250,
              tickinterval=25,
              command=lambda h, c=canvas: setHeight(c, h))

scale.grid(row=0, column=0, sticky='NE')

#starting point on scale
scale.set(125)

root.mainloop()
Beispiel #10
0
Datei: main.py Projekt: kr1/roqba
class Application(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.send_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
        self.sock.bind((host, port))
        self.grid()
        self.columnconfigure(0, minsize=100)
        self.columnconfigure(1, minsize=200)
        self.columnconfigure(2, minsize=200)
        self.columnconfigure(3, minsize=150)
        self.columnconfigure(4, minsize=150)
        self.columnconfigure(5, minsize=150)
        self.columnconfigure(6, minsize=150)
        self.create_widgets()
        self.settables = self.assemble_settables()
        self.gui_logger = logging.getLogger('gui')
        self.request_update()

    def create_widgets(self):
        self.create_monitor()
        self.create_check_buttons()
        self.create_ranges()
        self.create_scales()
        self.create_radio_buttons()
        self.create_voices()
        self.quitButton = Button(self, text='Quit', command=self.quit)
        self.quitButton.grid(columnspan=7, sticky=E + W)

    def assemble_settables(self):
        settables = self.winfo_children()
        for w in settables:
            settables += w.winfo_children()
        return [w for w in settables if w.__class__.__name__ in ['Scale', 'Checkbutton']]

    def create_radio_buttons(self):
        # Scale related
        entries = ['DIATONIC', 'HARMONIC', 'MELODIC', 'PENTATONIC', 'PENTA_MINOR',
                   'GREEK_CHROMATIC', 'GREEK_ENHARMONIC']
        self.scale = StringVar()
        self.scale.set('DIATONIC')
        self.rb_frame = Frame(self)
        for e in entries:
            rb = Radiobutton(self.rb_frame, value=e, text=e, anchor=W,
                             command=self.send_scale, variable=self.scale)
            rb.grid(row=len(self.rb_frame.winfo_children()), sticky=W)
        self.rb_frame.grid(column=1, row=len(self.grid_slaves(column=1)), rowspan=3)

    def create_monitor(self):
        self.monitor_frame = LabelFrame(self, text="Monitor and Transport")
        this_cycle = Scale(self.monitor_frame, label='cycle_pos', orient=HORIZONTAL,
                           from_=1, to=16, resolution=1)
        this_cycle.disable, this_cycle.enable = (None, None)
        this_cycle.ref = 'cycle_pos'
        this_cycle.grid(column=0, row=0, sticky=E + W)
        self.updateButton = Button(self.monitor_frame,
                                   text='Reload all Settings',
                                   command=self.request_update)
        self.updateButton.grid(row=1, sticky=E + W)
        self.ForceCaesuraButton = Button(self.monitor_frame,
                                         text='Force Caesura',
                                         command=self.force_caesura)
        self.ForceCaesuraButton.grid(row=2, sticky=E + W)
        self.saveBehaviourButton = Button(self.monitor_frame,
                                          text='Save current behaviour',
                                          command=self.request_saving_behaviour)
        self.saveBehaviourButton.grid(row=3, sticky=E + W)
        self.saveBehaviourNameEntry = Entry(self.monitor_frame)
        self.saveBehaviourNameEntry.grid(row=4, sticky=E + W)
        self.saveBehaviourNameEntry.bind('<KeyRelease>', self.request_saving_behaviour)
        self.selected_behaviour = StringVar()
        self.selected_behaviour.trace('w', self.new_behaviour_chosen)
        self.savedBehavioursMenu = OptionMenu(self.monitor_frame,
                                              self.selected_behaviour, None,)
        self.savedBehavioursMenu.grid(row=5, sticky=E + W)
        self.monitor_frame.grid(column=0, row=10, sticky=E + W)

    def request_update(self):
        self.send({'sys': 'update'})

    def request_saving_behaviour(self, event=None):
        """callback for save behaviour button and textentry"""
        if event and event.widget == self.saveBehaviourNameEntry:
            if event.keysym == 'Return':
                name = self.saveBehaviourNameEntry.get()
                self.saveBehaviourNameEntry.delete(0, len(name))
            else:
                return
        else:  # button was pressed
            name = self.saveBehaviourNameEntry.get()
        if name:
            self.send({'sys': ['save_behaviour', name]})

    def force_caesura(self):
        self.send({'force_caesura': True})

    def create_voices(self):
        voice_ids = ['1', '2', '3', '4']
        SCALES = OrderedDict([
                  ('pan_pos', {'min': -1, 'max': 1, 'start': 0.5, 'res': 0.001}),
                  ('volume', {'min': 0, 'max': 1, 'start': 0.666, 'res': 0.001}),
                  ('slide_duration_msecs', {'min': 0, 'max': 2000, 'start': 60, 'res': 1}),
                  ('slide_duration_prop', {'min': 0, 'max': 2, 'start': 0.666, 'res': 0.001}),
                  ('binaural_diff', {'min': 0, 'max': 66, 'start': 0.2, 'res': 0.01})
                ])

        for vid in voice_ids:
            counter = 0
            for sca in SCALES:
                name = 'voice_' + vid + '_' + sca
                setattr(self, 'min_' + name, SCALES[sca]['min'])
                setattr(self, 'max_' + name, SCALES[sca]['max'])
                this_sca = Scale(self, label=sca, orient=HORIZONTAL,
                                 from_=getattr(self, 'min_' + name),
                                 to=getattr(self, 'max_' + name),
                                 resolution=SCALES[sca]['res'])
                this_sca.enable = ('enable' in list(SCALES[sca].keys()) and
                                   SCALES[sca]['enable'] or None)
                this_sca.disable = ('disable' in list(SCALES[sca].keys()) and
                                    SCALES[sca]['disable'] or None)
                this_sca.grid(column=int(2 + int(vid)), row=counter, sticky=E + W)
                this_sca.bind("<ButtonRelease>", self.scale_handler)
                this_sca.ref = name
                counter += 1
        CHECK_BUTTONS = OrderedDict(
                 [('mute', False),
                  ('automate_binaural_diffs', True),
                  ('automate_note_duration_prop', True),
                  ('use_proportional_slide_duration', {'val': True, 'label': 'proportional slide'}),
                  ('automate_pan', True),
                  ('automate_wavetables', True)])
        for vid in voice_ids:
            counter = 0
            cb_frame = LabelFrame(self, text="Voice {0} - Automation".format(vid))
            setattr(self, 'voice_' + vid + '_cb_frame', cb_frame)
            for cb in CHECK_BUTTONS:
                options = CHECK_BUTTONS[cb]
                name = 'voice_' + vid + '_' + cb
                if isinstance(options, dict) and 'label' in list(options.keys()):
                    label = options['label']
                else:
                    label = cb[9:] if cb[:9] == 'automate_' else cb
                setattr(self, name, IntVar(
                    value=type(options) == dict and options['val'] or options))
                self.this_cb = Checkbutton(cb_frame, text=label, variable=getattr(self, name))
                self.this_cb.bind('<Button-1>', self.check_boxes_handler)
                self.this_cb.disable = None
                self.this_cb.grid(sticky=W, column=0, row=counter)
                self.this_cb.ref = name
                counter += 1
            # add trigger wavetable-button
            trigWavetableButton = Button(cb_frame, text='Next Wavetable')
            trigWavetableButton.bind('<Button-1>', self.trigger_waveform_handler)
            trigWavetableButton.ref = 'voice_' + vid + "_trigger_wavetable"
            trigWavetableButton.grid(row=counter)
            cb_frame.grid(column=int(vid) + 2, row=5, sticky=E + W + N, rowspan=8)
        for vid in voice_ids:
            generation_types = ["random", "random_harmonic", "harmonic"]
            partial_pools = ["even", "odd", "all"]
            prefix = 'voice_' + vid + '_'
            types_name = prefix + 'wavetable_generation_type'
            pools_name = prefix + 'partial_pool'
            setattr(self, types_name, StringVar())
            getattr(self, types_name).set("random")
            setattr(self, pools_name, StringVar())
            getattr(self, pools_name).set("all")
            target_frame = getattr(self, 'voice_' + vid + '_cb_frame')
            gen_typ_frame = LabelFrame(target_frame, text="type")
            gen_typ_frame.grid(row=len(target_frame.winfo_children()), sticky=W)
            for gen_t in generation_types:
                gen_t_entry = Radiobutton(gen_typ_frame, value=gen_t, text=gen_t, anchor=W,
                                          variable=getattr(self, types_name))
                gen_t_entry.bind('<ButtonRelease-1>', self.wt_handler)
                gen_t_entry.ref = types_name
                gen_t_entry.grid(row=len(gen_typ_frame.winfo_children()), sticky=W)
            pp_frame = LabelFrame(target_frame, text="harmonics")
            for pp in partial_pools:
                pp_entry = Radiobutton(pp_frame, value=pp, text=pp, anchor=W,
                                       variable=getattr(self, pools_name))
                pp_entry.bind('<ButtonRelease-1>', self.wt_handler)
                pp_entry.ref = pools_name
                pp_entry.grid(row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials = Scale(pp_frame, label='number of harmonics', orient=HORIZONTAL,
                                      from_=1, to=24, resolution=1)
            this_num_partials.ref = prefix + 'num_partials'
            this_num_partials.grid(column=0, row=len(pp_frame.winfo_children()), sticky=E + W)
            this_num_partials.bind("<ButtonRelease>", self.scale_handler)
            pp_frame.grid(row=len(target_frame.winfo_children()), sticky=E + W)

    def wt_handler(self, event):
        print(event.widget.tk)
        ref = event.widget.ref
        self.send({ref: getattr(self, ref).get()})

    def create_check_buttons(self):
        self.cb_frame = LabelFrame(self, text="Global Settings")
        for cb in CHECK_BUTTONS:
            label = cb
            target_parent = self.cb_frame
            if isinstance(CHECK_BUTTONS[cb], dict) and 'sub_frame' in list(CHECK_BUTTONS[cb].keys()):
                target_parent = getattr(self, CHECK_BUTTONS[cb]['sub_frame'])
            setattr(self, cb, IntVar(value=type(CHECK_BUTTONS[cb]) == dict and
                                     CHECK_BUTTONS[cb]['val'] or
                                     CHECK_BUTTONS[cb]))
            self.this_cb = Checkbutton(target_parent, text=label, variable=getattr(self, cb))
            self.this_cb.bind('<Button-1>', self.check_boxes_handler)
            self.this_cb.disable = (type(CHECK_BUTTONS[cb]) == dict and
                                    'disable' in list(CHECK_BUTTONS[cb].keys()))
            self.this_cb.grid(sticky=W, column=0, row=len(target_parent.winfo_children()))
            self.this_cb.ref = cb
        for but in GLOBAL_BUTTONS:
            label = but
            ele = GLOBAL_BUTTONS[but]
            this_but = Button(self.cb_frame, text=but)
            this_but.bind('<ButtonRelease-1>', getattr(self, ele['handler']))
            this_but.ref = but
            this_but.grid(sticky=W, column=0, row=len(self.cb_frame.winfo_children()))
        self.cb_frame.grid(column=0, row=0, rowspan=10, sticky=N)

    def new_behaviour_chosen(self, a, b, c):
        self.send({'sys': ['change_behaviour', self.selected_behaviour.get()]})

    def set_value(self, name, val):
        '''sets a widget to the specified value

        various different widget types need custom setting functionality'''

        direct = ['scale', 'wavetable_generation_type', 'partial_pool']
        if [x for x in direct if match("(voice_\d_|)" + x, name)]:
            self.gui_logger.info("setting: '{0}' to '{1}' in GUI".format(name, val))
            getattr(self, name).set(val)
            return
        if name == 'saved_behaviours' and len(val):
            self.savedBehavioursMenu.destroy()
            self.savedBehavioursMenu = OptionMenu(self.monitor_frame,
                                                  self.selected_behaviour, *sorted(val))
            self.savedBehavioursMenu.grid(row=5, sticky=E + W)
            return
        for w in self.settables:
            typ = w.__class__.__name__
            if w.ref == name:
                # print "setting '{0}' of type: '{1}' to: {2}".format(name, typ, val)
                if typ == 'Scale':
                    w.set(val)
                elif typ == "Checkbutton":
                    w.select() if val else w.deselect()

    def check_boxes_handler(self, event):
        '''handles checkbox events.

        shows and hides gui elements according to their enable/disable fields'''
        # print event.__dict__
        # print event.widget.__dict__
        ref = event.widget.ref
        val = not getattr(self, ref).get()  # because is read before the var is changed
        self.send({ref: val})
        # print ref, val
        # handle gui elements
        # enable/disable functionality temporarily(?) commented on:
        # Wed Aug 17 09:39:54 CEST 2011
#        if event.widget.disable:
#            for w in self.children.values():
#
#                # this try clause is for debugging, remove when stable
#                try:
#                    w.ref
#                    #print w.ref
#                except:
#                    pass
#                if (w.__class__.__name__ == 'Scale' and
#                    (w.disable or w.enable)):
#                    if w.disable == ref:
#                        if val:
#                            w.grid()
#                        else:
#                            w.grid_remove()
#                    elif w.enable == ref:
#                        if val:
#                            w.grid_remove()
#                        else:
#                            w.grid()
#                    #print w.disable, w.enable

    def create_scales(self):
        counter = 0
        for sca in SCALES:
            label = SCALES[sca]['label'] if 'label' in list(SCALES[sca].keys()) else sca
            setattr(self, 'min_' + sca, SCALES[sca]['min'])
            setattr(self, 'max_' + sca, SCALES[sca]['max'])
            self.this_scale = Scale(self, label=label, orient=HORIZONTAL,
                                    from_=getattr(self, 'min_' + sca),
                                    to=getattr(self, 'max_' + sca),
                                    resolution=SCALES[sca]['res'])
            self.this_scale.set(SCALES[sca]['start'])
            self.this_scale.enable = ('enable' in list(SCALES[sca].keys()) and
                                      SCALES[sca]['enable'] or None)
            self.this_scale.disable = ('disable' in list(SCALES[sca].keys()) and
                                       SCALES[sca]['disable'] or None)
            if 'pos' in list(SCALES[sca].keys()):
                pos = SCALES[sca]['pos']
                col = pos['c']
                row = pos['r']
            else:
                row = counter
                col = 1
                counter += 1
            self.this_scale.grid(column=col, row=row, sticky=E + W)
            self.this_scale.ref = sca
            self.this_scale.bind("<ButtonRelease>", self.scale_handler)

    def scale_handler(self, event):
        self.send({event.widget.ref: event.widget.get()})
        self.gui_logger.info("handling scale: {0}, with new value: {1}".format(
                  event.widget.ref, event.widget.get()))

    def trigger_waveform_handler(self, event):
        self.send({event.widget.ref: True})
        # print event.widget.ref, "- triggering wavetable"

    def send_scale(self):
        do = {'scale': self.scale.get()}
        self.send(do)

    def send(self, msg):
        self.gui_logger.info("sending: {0}".format(msg))
        self.send_sock.sendto(json.dumps(msg), (remote_host, send_port))

    def create_ranges(self):
        counter = 0
        for ran in RANGES:
            setattr(self, 'min_' + ran, RANGES[ran]['min'])
            setattr(self, 'max_' + ran, RANGES[ran]['max'])
            self.this_min_scale = Scale(self, label='min ' + ran, orient=HORIZONTAL,
                                        from_=getattr(self, 'min_' + ran),
                                        to=getattr(self, 'max_' + ran),
                                        resolution=RANGES[ran]['res'])
            self.this_max_scale = Scale(self, label='max ' + ran, orient=HORIZONTAL,
                                        from_=getattr(self, 'min_' + ran),
                                        to=getattr(self, 'max_' + ran),
                                        resolution=RANGES[ran]['res'])
            self.this_min_scale.set(RANGES[ran]['min_start'])
            self.this_max_scale.set(RANGES[ran]['max_start'])
            self.this_min_scale.enable = ('enable' in list(RANGES[ran].keys()) and
                                          RANGES[ran]['enable'] or None)
            self.this_min_scale.disable = ('disable' in list(RANGES[ran].keys()) and
                                           RANGES[ran]['disable'] or None)
            self.this_max_scale.enable = ('enable' in list(RANGES[ran].keys()) and
                                          RANGES[ran]['enable'] or None)
            self.this_max_scale.disable = ('disable' in list(RANGES[ran].keys()) and
                                           RANGES[ran]['disable'] or None)
            self.this_min_scale.grid(column=2, row=counter, sticky=E + W)
            self.this_max_scale.grid(column=2, row=counter + 1, sticky=E + W)
            self.this_min_scale.ref = 'min_' + ran
            self.this_max_scale.ref = 'max_' + ran
            self.this_min_scale.bind("<ButtonRelease>", self.scale_handler)
            self.this_max_scale.bind("<ButtonRelease>", self.scale_handler)
            counter += 2

    def socket_read_handler(self, file, mask):
        data_object = json.loads(file.recv(1024))
        do = list(data_object.items())[0]
        self.set_value(do[0], do[1])
Beispiel #11
0
class SimulationPage(tk.Frame):
    def __init__(self, parent, controller, queue):
        self._dashboard = Dashboard()
        self.controller = controller
        self.simulator = Simulator(queue)
        self.window_closed = False

        tk.Frame.__init__(self, parent, bg='white')
        title_label = tk.Label(self,
                               text="Project Origin Dashboard",
                               font=LARGE_FONT,
                               foreground='blue',
                               bg='white')
        title_label.pack(pady=10, padx=10)

        self.s = ttk.Style()
        self.s.theme_use('vista')

        self.status_label = tk.Label(self, text="Simulator Ready.", bg='white')
        self.status_label.pack(pady=10, padx=10)

        self.sim_btn = ttk.Button(
            self,
            text="Start Simulation",
            command=lambda: self.on_simulation_btn_click())

        self.sim_btn.pack()
        self.food_creature_scale = Scale(
            self,
            from_=0,
            to=1,
            orient=tk.HORIZONTAL,
            resolution=0.1,
            bg='white',
            command=lambda x: self.set_food_creature_ratio(x))
        self.food_creature_scale.set(ConfigPhysics.FOOD_CREATURE_RATIO)
        self.food_creature_scale.pack()

        dash_fig = self._dashboard.get_figure()

        canvas = FigureCanvasTkAgg(dash_fig, self)
        canvas.draw()
        canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)

        controller.protocol("WM_DELETE_WINDOW", self.close_window_event)

    def close_window_event(self):
        self.stop_simulation()
        self.window_closed = True
        if self.simulator.status() == SimState.IDLE:
            self.close_window()

    def close_window(self):
        self.controller.destroy()
        sys.exit()

    def refresh_data(self, msg):
        if type(msg) == SimState:
            print(msg.value)
            if msg == SimState.IDLE:
                self.sim_btn['text'] = 'Start Simulation'
                self.sim_btn['state'] = tk.ACTIVE
                if self.window_closed:
                    self.close_window()
            self.status_label['text'] = str(msg.value)
        else:
            self._dashboard.update_step_dash(msg.step_stats_df)
            self._dashboard.update_epoch_dash(msg.epoch_stats_df)

    def on_simulation_btn_click(self):
        if self.sim_btn['text'] == 'Start Simulation':
            self.start_simulation()
            self.sim_btn['text'] = 'Stop Simulation'
        else:
            self.stop_simulation()
            self.sim_btn['state'] = tk.DISABLED

    def stop_simulation(self):
        self.simulator.stop()
        self.status_label['text'] = "Simulation Interrupted. Stopping..."

    def start_simulation(self):
        self.simulator.run_in_thread()

    @staticmethod
    def set_food_creature_ratio(new):
        ConfigPhysics.FOOD_CREATURE_RATIO = float(new)
Beispiel #12
0
class HsvGui(tk.Frame):
    def __init__(self, master=None,):
        tk.Frame.__init__(self, master)
        self.root = master

        self.Webcam = G2.Webcamera()
        self.baseImage = self.Webcam.save_image(persist=False)
        self.baseImage = cv2.cvtColor(numpy.array(self.baseImage), cv2.COLOR_RGB2BGR)
        self.createWidgets()
        self.OnValueChange = event.Event()

        self.title = "Webcam"

        cv2.startWindowThread()
        cv2.namedWindow(self.title, cv2.WINDOW_NORMAL)
        cv2.imshow(self.title, self.baseImage)
        self.Funkify()


    def createWidgets(self):

        Label(self.root, text="Value:").grid(row=0, sticky=W)

        Label(self.root, text="H:").grid(row=1, sticky=W)
        Label(self.root, text="S:").grid(row=2, sticky=W)
        Label(self.root, text="V:").grid(row=3, sticky=W)

        Label(self.root, text="S:").grid(row=4, sticky=W)
        Label(self.root, text="V:").grid(row=5, sticky=W)
        Label(self.root, text="H:").grid(row=6, sticky=W)


        self.valueLabel = Label(self.root, text="000-000-000 to 000-000-000")
        self.valueLabel.grid(row=0, column=1, sticky=W)

        self.Hvalue = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback)
        self.Hvalue.grid(row=1, column=1)
        self.Hvalue.set(0)

        self.Svalue = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback)
        self.Svalue.grid( row=2, column=1)
        self.Svalue.set(90)

        self.Vvalue = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback)
        self.Vvalue.grid( row=3, column=1)
        self.Vvalue.set(0)


        self.HvalueMax = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback)
        self.HvalueMax.grid(row=4, column=1)
        self.HvalueMax.set(255)

        self.SvalueMax = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback)
        self.SvalueMax.grid(row=5, column=1)
        self.SvalueMax.set(255)

        self.VvalueMax = Scale(self.root, from_=0, to=255, orient=HORIZONTAL, command=self.__sliderCallback)
        self.VvalueMax.grid(row=6, column=1)
        self.VvalueMax.set(120)

        self.Go = tk.Button(self.root, text="Go!", fg="Green", command=self.Funkify)
        self.Go.grid(row=7, column=0)
        self.QUIT = tk.Button(self.root, text="QUIT", fg="red", command=self.root.destroy)
        self.QUIT.grid(row=7, column=1)




    def Funkify(self):
        H = int(self.Hvalue.get())
        S = int(self.Svalue.get())
        V = int(self.Vvalue.get())
        lower = [H, S, V]

        Hmax = int(self.HvalueMax.get())
        Smax = int(self.SvalueMax.get())
        Vmax = int(self.VvalueMax.get())
        upper= [Hmax, Smax, Vmax]

        #self.valueLabel['text'] = '{0}-{1}-{2} to {3}-{4}-{5}'.format(H, S, V, Hmax, Smax, Vmax)

        output, a = self.Webcam.funkyfy(colorrange=(lower, upper))

        cv2.imshow(self.title, numpy.hstack([output, a]))


    def __sliderCallback(self, args):
        print('Sliding!!')
Beispiel #13
0
    # Etiqueta que contiene la cantidad de iteraciones realizadas para el cálculo.
    etiqueta = Label (ventana, text = ('Iteraciones necesarias: ' + str (iteracionesTotales)))
    etiqueta.config (bg = 'white', font = ('Verdana', 15))
    etiqueta.place (relx=0.5, rely=0.37, anchor=CENTER)

    #Función que permite graficar a tiempo real. Esta ejecuta nuevamente la función Graficar para realizar nuevamente el cálculo.
    animation.FuncAnimation (fig, Graficar, interval = 1000)
    plt.close ()
 

# Se define el slider para el tamaño del lado.
barraL = Scale(ventana, from_=7, to=20, tickinterval=13, length=400, bg = 'White',
resolution=1, showvalue=True, orient='horizontal', label="Tamaño del Lado (Lx)", cursor = "hand1")
barraL.bind ("<ButtonRelease-1>",Graficar)
barraL.set(10)

barraL.place (relx=0.175, rely=0.05, anchor=CENTER)

# Se define el slider para el tiempo a evaluar.
barraTiempos = Scale(ventana, from_=1, to=5, tickinterval=4,length=400, bg = 'White',
resolution=0.5, showvalue=True, orient='horizontal', label="Tiempo (s)", cursor = "hand1")
barraTiempos.bind ("<ButtonRelease-1>",Graficar)
barraTiempos.set(3)

barraTiempos.place (relx=0.5, rely=0.05, anchor=CENTER)

# Se define el slider para el número de términos.
barraPresición = Scale(ventana, from_=0.001, to=1, tickinterval=0.999,length=400, bg = 'White',
resolution=0.001, showvalue=True, orient='horizontal', label="Presición", cursor = "hand1")
barraPresición.bind ("<ButtonRelease-1>",Graficar)
Beispiel #14
0
def main():
    """
    основной метод - создание графического интерфейса TKinter
    :return:
    """
    global params
    window = Tk()
    window.title("Отражение в параболическом зеркале")
    window.geometry('500x400')
    canv = Frame(window)
    setup = LabelFrame(window, text='Настройки', width=450, height=150)
    c = Canvas(canv, width=450, height=230, bg='black')
    c.pack(side=TOP, padx=10)

    setup1 = Frame(setup)
    butFrame = Frame(setup1)

    scal = Scale(setup1,
                 orient=HORIZONTAL,
                 length=200,
                 from_=0.002,
                 to=0.01,
                 tickinterval=0.002,
                 resolution=0.002)
    scal.set(0.002)
    scal.pack(side=TOP, pady=(0, 10), padx=(10, 10))
    scal.bind("<ButtonRelease-1>",
              lambda event, draw_canv=c: redraw(event, draw_canv))

    Button(butFrame, text='Очистить', width=12,
           command=lambda event=None, draw_canv=c, flag=True: redraw(event, draw_canv,
                                                                     setarrow=flag)) \
        .pack(side=LEFT, padx=(10, 5), pady=(5, 10))
    Button(butFrame,
           text='Закрыть',
           width=12,
           command=lambda flag=0: sys.exit(flag)).pack(side=LEFT,
                                                       padx=(5, 10),
                                                       pady=(5, 10))

    butFrame.pack(side=TOP)

    setup1.pack(side=LEFT)

    columns = ('#1', '#2')
    params = Treeview(setup, show='headings', columns=columns)
    params.heading('#1', text='Параметр')
    params.heading('#2', text='Значение')
    params.column('#1', width=100, minwidth=50, stretch=NO, anchor=N)
    params.column('#2', width=100, minwidth=50, stretch=NO, anchor=N)
    params.pack(side=LEFT, padx=(5, 10), pady=(0, 10))

    canv.pack(side=TOP, pady=(10, 10))
    setup.pack(side=TOP, pady=(0, 10), padx=(25, 25))

    draw_parabola(c)

    window.bind('<Button-1>', press)
    window.bind('<ButtonRelease-1>',
                lambda event, draw_canv=c: release(event, draw_canv))
    window.mainloop()
#FullScreen Checkbox
FullScreen_state = tk.IntVar()
FullScreen_state.set(False) #set check state
chk = Checkbutton(window, text='Fullscreen', var=FullScreen_state)

#Volume Label
Volume_lbl = tk.Label(text="Volume", fg="black", width=15, height=1, font=ConfigFont)
Volume_lbl.pack(anchor=tk.W)

#Background Music Volume Label
BGMVolume_lbl = tk.Label(text="Background Music Volume", fg="black", width=25, height=1, font=ConfigFont)
BGMVolume_lbl.pack(anchor=tk.W)

#Background Music Volume Slider
BGMVol_Slider = Scale(window, from_=0, to=100, orient=HORIZONTAL, font=ConfigFont)
BGMVol_Slider.set(50)
BGMVol_Slider.pack(anchor=tk.W)

BGVolume = BGMVol_Slider.get()/10

#Sound Effects Volume Label
SFXVolume_lbl = tk.Label(text="Sound Effects Volume", fg="black", width=25, height=1, font=ConfigFont)
SFXVolume_lbl.pack(anchor=tk.W)

#Sound Effects Volume Slider
SFXVol_Slider = Scale(window, from_=0, to=100, orient=HORIZONTAL, font=ConfigFont)
SFXVol_Slider.set(50)
SFXVol_Slider.pack(anchor=tk.W)

Sound_Output = tk.IntVar()
Sound_Output.set(2)
class TLight(TObject):
    def __init__(self, send_func, light, master=None):
        super().__init__(send_func, light, master)
        self._power_property_label.configure(text="Power:")
        self.__brightness_frame = None
        self.__brightness_property_label = None
        self.__brightness_property_scale = None
        self.__brightness_property_status_label = None
        self.__brightness_property_button = None
        self.__set_brightness_property__()
        self.__color_frame = None
        self.__color_property_label = None
        self.__color_property_combobox = None
        self.__color_property_status_label = None
        self.__color_property_button = None
        self.__set_color_property__()

    def __set_brightness_property__(self):
        self.__brightness_frame = Frame(self)
        self.__brightness_frame.pack()
        self.__brightness_property_label = Label(self.__brightness_frame,
                                                 text='Brightness:')
        self.__brightness_property_label.pack(side=LEFT, padx=3)
        self.__brightness_property_status_label = Label(
            self.__brightness_frame, text=f'(currently {self.obj.brightness})')
        self.__brightness_property_status_label.pack(side=LEFT, padx=3)
        self.__brightness_property_scale = Scale(self.__brightness_frame,
                                                 from_=0,
                                                 to=100,
                                                 orient=HORIZONTAL)
        self.__brightness_property_scale.set(50)
        self.__brightness_property_scale.pack(side=LEFT, padx=3)
        self.__brightness_property_button = Button(
            self.__brightness_frame,
            text='Change',
            command=self.__brightness_button_event__)
        self.__brightness_property_button.pack(side=LEFT, padx=3)

    def __set_color_property__(self):
        if self.obj.colors:
            self.__color_frame = Frame(self)
            self.__color_frame.pack()
            self.__color_property_label = Label(self.__color_frame,
                                                text='Color:')
            self.__color_property_label.pack(side=LEFT, padx=3)
            self.__color_property_status_label = Label(
                self.__color_frame,
                text=f'(currently {self.obj.current_color})')
            self.__color_property_status_label.pack(side=LEFT, padx=3)
            self.__color_property_combobox = ttk.Combobox(self.__color_frame,
                                                          state='readonly')
            self.__color_property_combobox['values'] = self.obj.colors
            self.__color_property_combobox.current(0)
            self.__color_property_combobox.pack(side=LEFT, padx=3, pady=5)
            self.__color_property_button = Button(
                self.__color_frame,
                text='Change',
                command=self.__color_button_event__)
            self.__color_property_button.pack(side=LEFT, padx=3)

    def __brightness_button_event__(self):
        self._send_func(
            self.obj.location,
            str('brightness=' + str(self.__brightness_property_scale.get())))

    def __update_brightness_property__(self):
        self.__brightness_property_status_label.configure(
            text=f'(currently {self.obj.brightness})')

    def __color_button_event__(self):
        self._send_func(self.obj.location,
                        str('color=' + self.__color_property_combobox.get()))

    def __update_color_property(self):
        self.__color_property_status_label.configure(
            text=f'(currently {self.obj.current_color})')

    def notify(self, information=None):
        if information is None:
            return
        elif information == 'power':
            self.__update_power_property__()
        elif information == 'brightness':
            self.__update_brightness_property__()
        elif information == 'color':
            self.__update_color_property()
Beispiel #17
0
class SliderDialog(CustomDialog):
    def __init__(self,
                 root,
                 title="Slider Dialog",
                 init_val=0,
                 min_val=-1,
                 max_val=1,
                 default_val=0,
                 on_change=list(),
                 resolution=1,
                 on_confirm=list(),
                 on_cancel=list()):
        self.init_val = init_val
        self.default_val = default_val
        self.on_change = on_change
        self.on_confirm = on_confirm
        self.on_cancel = on_cancel

        self.window = Toplevel()
        self.window.title(title)
        self.window.transient(root)
        self.window.grab_set()

        self.scale = Scale(self.window,
                           orient='horizontal',
                           from_=min_val,
                           to=max_val,
                           command=self.on_update,
                           resolution=resolution)
        self.scale.set(init_val)
        self.scale.grid(row=0, column=0, sticky='nesw')

        self.cancel_button = Button(self.window,
                                    text='Cancel',
                                    command=self.cancel)
        self.cancel_button.grid(row=1, column=0)

        self.reset_button = Button(self.window,
                                   text='Reset',
                                   command=self.reset)
        self.reset_button.grid(row=1, column=1)

        self.confirm_button = Button(self.window,
                                     text='Confirm',
                                     command=self.confirm)
        self.confirm_button.grid(row=1, column=2)

    def on_update(self, value):
        for callback in self.on_change:
            callback(value)

    def cancel(self):
        for callback in self.on_cancel:
            callback()
        self.on_change[0](
            self.init_val
        )  # hardcoded atm, so assumes the set method is first (good enough for now)
        self.window.destroy()

    def reset(self):
        self.scale.set(self.default_val)

    def confirm(self):
        for callback in self.on_confirm:
            callback()
        self.window.destroy()
Beispiel #18
0
class Slider(WidgetMixin, ScheduleMixin, DestroyMixin, EnableMixin, FocusMixin,
             DisplayMixin, ColorMixin, ReprMixin):
    def __init__(self,
                 master,
                 start=0,
                 end=100,
                 horizontal=True,
                 command=None,
                 grid=None,
                 align=None):

        # If you specify a command to the slider, it must take one argument as it will be given
        # the slider's current value

        self._master = master
        self._grid = grid
        self._align = align
        self._visible = True

        # Description of this object (for friendly error messages)
        self.description = "[Slider] object from " + str(start) + " to " + str(
            end)

        # Set the direction
        orient = HORIZONTAL if horizontal else VERTICAL

        # Create a tk Scale object within this object
        self.tk = Scale(master.tk,
                        from_=start,
                        to=end,
                        orient=orient,
                        command=self._command_callback)

        self.update_command(command)

        # Pack this object
        try:
            utils.auto_pack(self, master, grid, align)
        except AttributeError:
            utils.error_format(
                self.description + "\n" +
                "Could not add to interface - check first argument is [App] or [Box]"
            )

    # PROPERTIES
    # ----------------
    # Get/set the value
    @property
    def value(self):
        return (self.tk.get())

    @value.setter
    def value(self, value):
        self.tk.set(value)

    # METHODS
    # ----------------
    # Calls the given function when the slider value is changed

    def _command_callback(self, value):
        if self._command:
            args_expected = utils.no_args_expected(self._command)
            if args_expected == 0:
                self._command()
            elif args_expected == 1:
                self._command(value)
            else:
                utils.error_format(
                    "Slider command function must accept either 0 or 1 arguments.\nThe current command has {} arguments."
                    .format(args_expected))

    def update_command(self, command):
        if command is None:
            self._command = lambda: None
        else:
            self._command = command

    # DEPRECATED
    # -------------------------------------------

    def add_command(self, command):
        self.update_command(command)
        utils.deprecated(
            "Slider add_command() is deprecated - renamed to update_command()")
Beispiel #19
0
class LayerViewer(ttk.LabelFrame):
    def __init__(self, project, width, height, *args, **kwargs):
        ttk.LabelFrame.__init__(self, *args, **kwargs)
        self.configure(text="LayerViewer")
        self.project = project
        self.width = width
        self.height = height
        self.delay = 1000
        self.index = 0
        self.state = PAUSED

        self.outer_frame = Frame(self)
        self.outer_frame.pack(side="top",
                              fill="both",
                              expand=True,
                              padx=4,
                              pady=4)
        self.outer_frame.config(width=250, height=200)
        self.inner_frame = Frame(self)
        force_aspect(self.inner_frame, self.outer_frame,
                     float(width) / float(height))

        self.canvas = Canvas(self.inner_frame, relief="sunken")
        self.canvas.config(
            width=50,  #Parent frame width
            height=50,
            highlightthickness=0)
        self.canvas.config()
        self.canvas_frame = Frame(self.canvas, border=0, highlightthickness=0)
        self.canvas.create_window(0, 0, window=self.canvas_frame, anchor='nw')
        self.canvas_frame.config(width=50, height=50)
        self.canvas.pack(fill="both", expand=True)

        self.playback_scale = Scale(self,
                                    orient="horizontal",
                                    from_=0,
                                    to=30,
                                    command=self.set_delay)
        self.playback_scale.set(int(self.delay / 1000))
        self.playback_scale.pack(fill="both", expand=False, padx=4, pady=4)

        self.display_loop()

    # def pause(self, event = None):
    # 	self.state = PAUSED

    # def play(self, event = None):
    # 	self.state = RUNNING

    def set_delay(self, fps):
        if float(fps) < float(1.0):
            self.delay = None
            return
        self.delay = int(1000.0 / float(fps))

    """
	Approximates an fps, milage will vary, it would be 
	better for me to run this as a thread spawned by a
	timer thread  that acts as the loop, so the fps 
	would more closely match the one selected with the menu bar
	"""

    def display_loop(self):
        if not self.project.frames or not self.delay:
            self.after(100, self.display_loop)
            return
        if self.index > len(self.project.frames) - 1:
            self.index = 0
        layer = self.project.frames[self.index]
        self.image = layer.export_composite_image().resize(
            (self.inner_frame.winfo_width(), self.inner_frame.winfo_height()),
            Image.BOX)
        self.displayed = ImageTk.PhotoImage(self.image)
        self.canvas.delete("all")
        self.canvas.create_image(0, 0, image=self.displayed, anchor="nw")
        self.configure(text=f"Preview: {layer.id}")
        self.index += 1
        if self.delay < 10:
            delay = 10
        delay = self.delay or 1000
        self.after(delay, self.display_loop)
Beispiel #20
0
class Fenetre(Tk):
    def __init__(self):
        Tk.__init__(self)
        self.tilt_val_init = 110
        self.pan_val_init = 75
        self.pan_min = 0
        self.pan_max = 105
        self.tilt_min = 35
        self.tilt_max = 135
        self.pas = 5

        # Full Screen
        largeur, hauteur = self.winfo_screenwidth(), self.winfo_screenheight()
        self.overrideredirect(0)
        self.geometry("%dx%d" % (largeur, hauteur))

        # TILT
        self.tilt_bar = Scale(self, from_=self.tilt_min, to=self.tilt_max, length=250, label='Tilt', sliderlength=20,
                              orient=HORIZONTAL,
                              command=self.update_tilt)
        self.tilt_bar.set((self.tilt_max + self.tilt_min) // 2)
        self.tilt_bar.grid(row=1, column=2)

        self.tilt_angle = StringVar()
        self.tilt_val = self.tilt_bar.get()

        # PAN
        self.pan_bar = Scale(self, from_=self.pan_min, to=self.pan_max, length=250, label='Pan', sliderlength=20,
                             orient=HORIZONTAL,
                             command=self.update_pan)
        self.pan_bar.set((self.pan_max + self.pan_min) // 2)
        self.pan_bar.grid(row=2, column=2)

        self.pan_angle = StringVar()
        self.pan_val = self.pan_bar.get()

        # PS3 Controller
        self.bind("<a>", self.pan_plus)
        self.bind("<d>", self.pan_moins)
        self.bind("<s>", self.tilt_plus)
        self.bind("<w>", self.tilt_moins)
        self.bind("<p>", self.lean_left)
        self.bind("<m>", self.lean_right)
        self.bind("<q>", self.initialiser_positon)

        self.bind("<j>", self.forward)
        self.bind("<u>", self.reverse)
        self.bind("<h>", self.left)
        self.bind("<k>", self.right)
        self.bind("<i>", self.break_motor)

        self.bind("<Button-2>", self.alarm)
        self.bind("<Button-3>", self.beep)

        # Motor
        self.gear = 0
        self.speed_init = 5
        self.speed = self.speed_init
        self.leds = [led_1, led_2, led_3]
        self.bind("<e>", self.shift_down)
        self.bind("<r>", self.shift_up)
        self.pwm = gpio.PWM(enable_pin, 50)  # 50 is the frequency

        # Infos
        self.pas_label = Label(self, text=str(self.pas))
        self.pas_label.grid(row=3)
        self.buzzer_state = 0

    #--------Buzzer--------
    def beep(self, event, time=100):
        self.buzzer_on()
        self.after(time, self.buzzer_off)

    def buzzer_on(self):
        gpio.output(buzzer, gpio.HIGH)
        self.buzzer_state = 1

    def buzzer_off(self):
        gpio.output(buzzer, gpio.LOW)
        self.buzzer_state = 0

    def alarm(self, event):
        if self.buzzer_state == 0:
            gpio.output(buzzer, gpio.HIGH)
            self.buzzer_state = 1
        else:
            gpio.output(buzzer, gpio.LOW)
            self.buzzer_state = 0

    #-------Camera-------

    #-------Motor-------
    def shift_up(self, event):
        if self.gear != 3:
            self.gear += 1
            gpio.output(self.leds[self.gear - 1], gpio.HIGH)
        else:
            self.beep(event, time=70)
        if self.gear == 0:
            self.speed = self.speed_init
        elif self.gear == 1:
            self.speed = 33
        elif self.gear == 2:
            self.speed = 66
        elif self.gear == 3:
            self.speed = 100

    def shift_down(self, event):
        if self.gear != 0:
            gpio.output(self.leds[self.gear - 1], gpio.LOW)
            self.gear -= 1
        if self.gear == 0:
            self.speed = self.speed_init
        elif self.gear == 1:
            self.speed = 33
        elif self.gear == 2:
            self.speed = 66
        elif self.gear == 3:
            self.speed = 100

    def forward(self, event):
        self.go("forward")

    def reverse(self, event):
        self.go("reverse")

    def right(self, event):
        self.go("right")

    def left(self, event):
        self.go("left")

    def lean_left(self, event):
        self.go('lean left')

    def lean_right(self, event):
        self.go('lean right')

    def break_motor(self, event):
        self.go("stop")

    def go(self, direction):
        gpio_reset_motor()
    
        if direction == "forward":
            print("forward")
            gpio.output(right_forward, gpio.HIGH)
            gpio.output(left_forward, gpio.HIGH)
        elif direction == "reverse":
            print("reverse")
            gpio.output(right_reverse, gpio.HIGH)
            gpio.output(left_reverse, gpio.HIGH)
        elif direction == "right":
            print("right")
            gpio.output(left_reverse, gpio.HIGH)
            gpio.output(right_forward, gpio.HIGH)
        elif direction == "left":
            print("left")
            gpio.output(right_reverse, gpio.HIGH)
            gpio.output(left_forward, gpio.HIGH)
        elif direction == 'lean left':
            gpio.output(left_reverse, gpio.HIGH)
        elif direction == 'lean right':
            gpio.output(right_reverse, gpio.HIGH)        
        elif direction == 'stop':
            self.pwm.stop()
            self.pwm = gpio.PWM(enable_pin, 50)  # 50 is the frequency
        else:
            pass

        self.pwm.start(self.speed)  # a "speed" of 50, sends power exactly every second cycle
        #time.sleep(1)
        #direction = input('Enter next direction')

    #-------Servos-------

    def tilt_plus(self, event):
        if verif_angle(self.tilt_val + self.pas, self.tilt_min, self.tilt_max):
            self.tilt_val += self.pas
            self.tilt_bar.set(self.tilt_val)

    def tilt_moins(self, event):
        if verif_angle(self.tilt_val - self.pas, self.tilt_min, self.tilt_max):
            self.tilt_val -= self.pas
            self.tilt_bar.set(self.tilt_val)

    def pan_plus(self, event):
        if verif_angle(self.pan_val + self.pas, self.pan_min, self.pan_max):
            self.pan_val += self.pas
            self.pan_bar.set(self.pan_val)

    def pan_moins(self, event):
        if verif_angle(self.pan_val - self.pas, self.pan_min, self.pan_max):
            self.pan_val -= self.pas * 2
            self.pan_bar.set(self.pan_val)

    def pas_plus(self, event):
        if self.pas + 1 < 21:
            self.pas += 1
            self.update_window()

    def pas_moins(self, event):
        if self.pas - 1 > 0:
            self.pas -= 1
            self.update_window()

    def update_tilt(self, x):
        if x == 0:
            pass
        set_servo(int(x), 0)
        self.tilt_val = int(x)

    def update_pan(self, x):
        if x == 0:
            pass
        set_servo(int(x), 1)
        self.pan_val = int(x)

    def update_window(self):
        self.pas_label['text'] = str(self.pas)

    def initialiser_positon(self, event):
        self.tilt_bar.set(self.tilt_val_init)
        self.pan_bar.set(self.pan_val_init)
Beispiel #21
0
    class vedoGUI(Frame):
        def __init__(self, parent):
            Frame.__init__(self, parent, bg="white")
            self.parent = parent
            self.filenames = []
            self.noshare = BooleanVar()
            self.flat = BooleanVar()
            self.xspacing = StringVar()
            self.yspacing = StringVar()
            self.zspacing = StringVar()
            self.background_grad = BooleanVar()
            self.initUI()

        def initUI(self):
            self.parent.title("vedo")
            self.style = Style()
            self.style.theme_use("clam")
            self.pack(fill=BOTH, expand=True)

            ############import
            Button(self,
                   text="Import Files",
                   command=self._importCMD,
                   width=15).place(x=115, y=17)

            ############meshes
            Frame(root, height=1, width=398, bg="grey").place(x=1, y=60)
            Label(self,
                  text="Meshes",
                  fg="white",
                  bg="green",
                  font=("Courier 11 bold")).place(x=20, y=65)

            # color
            Label(self, text="Color:", bg="white").place(x=30, y=98)
            colvalues = ('by scalar', 'gold', 'red', 'green', 'blue', 'coral',
                         'plum', 'tomato')
            self.colorCB = Combobox(self,
                                    state="readonly",
                                    values=colvalues,
                                    width=10)
            self.colorCB.current(0)
            self.colorCB.place(x=100, y=98)

            # mode
            modvalues = ('surface', 'surf. & edges', 'wireframe',
                         'point cloud')
            self.surfmodeCB = Combobox(self,
                                       state="readonly",
                                       values=modvalues,
                                       width=14)
            self.surfmodeCB.current(0)
            self.surfmodeCB.place(x=205, y=98)

            # alpha
            Label(self, text="Alpha:", bg="white").place(x=30, y=145)
            self.alphaCB = Scale(
                self,
                from_=0,
                to=1,
                resolution=0.02,
                bg="white",
                length=220,
                orient="horizontal",
            )
            self.alphaCB.set(1.0)
            self.alphaCB.place(x=100, y=125)

            # lighting
            Label(self, text="Lighting:", bg="white").place(x=30, y=180)
            lightvalues = ('default', 'metallic', 'plastic', 'shiny', 'glossy')
            self.lightCB = Combobox(self,
                                    state="readonly",
                                    values=lightvalues,
                                    width=10)
            self.lightCB.current(0)
            self.lightCB.place(x=100, y=180)
            # shading phong or flat
            self.flatCB = Checkbutton(self,
                                      text="flat shading",
                                      var=self.flat,
                                      bg="white")
            #self.flatCB.select()
            self.flatCB.place(x=210, y=180)

            # rendering arrangement
            Label(self, text="Arrange as:", bg="white").place(x=30, y=220)
            schemevalues = ('superpose (default)', 'mesh browser',
                            'n sync-ed renderers')
            self.schememodeCB = Combobox(self,
                                         state="readonly",
                                         values=schemevalues,
                                         width=20)
            self.schememodeCB.current(0)
            self.schememodeCB.place(x=160, y=220)

            # share cam
            self.noshareCB = Checkbutton(self,
                                         text="independent cameras",
                                         variable=self.noshare,
                                         bg="white")
            self.noshareCB.place(x=160, y=245)

            ############volumes
            Frame(root, height=1, width=398, bg="grey").place(x=1, y=275)
            Label(self,
                  text="Volumes",
                  fg="white",
                  bg="blue",
                  font=("Courier 11 bold")).place(x=20, y=280)

            # mode
            Label(self, text="Rendering mode:", bg="white").place(x=30, y=310)
            modevalues = (
                "isosurface (default)",
                "composite",
                "maximum proj",
                "lego",
                "slicer",
                "slicer2d",
            )
            self.modeCB = Combobox(self,
                                   state="readonly",
                                   values=modevalues,
                                   width=20)
            self.modeCB.current(0)
            self.modeCB.place(x=160, y=310)

            Label(self, text="Spacing factors:", bg="white").place(x=30, y=335)
            self.xspacingCB = Entry(self, textvariable=self.xspacing, width=3)
            self.xspacing.set('1.0')
            self.xspacingCB.place(x=160, y=335)
            self.yspacingCB = Entry(self, textvariable=self.yspacing, width=3)
            self.yspacing.set('1.0')
            self.yspacingCB.place(x=210, y=335)
            self.zspacingCB = Entry(self, textvariable=self.zspacing, width=3)
            self.zspacing.set('1.0')
            self.zspacingCB.place(x=260, y=335)

            ############## options
            Frame(root, height=1, width=398, bg="grey").place(x=1, y=370)
            Label(self,
                  text="Options",
                  fg='white',
                  bg="brown",
                  font=("Courier 11 bold")).place(x=20, y=375)

            # backgr color
            Label(self, text="Background color:", bg="white").place(x=30,
                                                                    y=405)
            bgcolvalues = ("white", "lightyellow", "azure", "blackboard",
                           "black")
            self.bgcolorCB = Combobox(self,
                                      state="readonly",
                                      values=bgcolvalues,
                                      width=9)
            self.bgcolorCB.current(3)
            self.bgcolorCB.place(x=160, y=405)
            # backgr color gradient
            self.backgroundGradCB = Checkbutton(self,
                                                text="gradient",
                                                variable=self.background_grad,
                                                bg="white")
            self.backgroundGradCB.place(x=255, y=405)

            ################ render button
            Frame(root, height=1, width=398, bg="grey").place(x=1, y=437)
            Button(self, text="Render", command=self._run,
                   width=15).place(x=115, y=454)

        def _importCMD(self):
            ftypes = [
                ("All files", "*"),
                ("VTK files", "*.vtk"),
                ("VTK files", "*.vtp"),
                ("VTK files", "*.vts"),
                ("VTK files", "*.vtu"),
                ("Surface Mesh", "*.ply"),
                ("Surface Mesh", "*.obj"),
                ("Surface Mesh", "*.stl"),
                ("Surface Mesh", "*.off"),
                ("Surface Mesh", "*.facet"),
                ("Volume files", "*.tif"),
                ("Volume files", "*.slc"),
                ("Volume files", "*.vti"),
                ("Volume files", "*.mhd"),
                ("Volume files", "*.nrrd"),
                ("Volume files", "*.nii"),
                ("Volume files", "*.dem"),
                ("Picture files", "*.png"),
                ("Picture files", "*.jpg"),
                ("Picture files", "*.bmp"),
                ("Picture files", "*.gif"),
                ("Picture files", "*.jpeg"),
                ("Geojson files", "*.geojson"),
                ("DOLFIN files", "*.xml.gz"),
                ("DOLFIN files", "*.xml"),
                ("DOLFIN files", "*.xdmf"),
                ("Neutral mesh", "*.neu*"),
                ("GMESH", "*.gmsh"),
                ("Point Cloud", "*.pcd"),
                ("3DS", "*.3ds"),
                ("Numpy scene file", "*.npy"),
                ("Numpy scene file", "*.npz"),
            ]
            self.filenames = tkFileDialog.askopenfilenames(parent=root,
                                                           filetypes=ftypes)
            args.files = list(self.filenames)

        def _run(self):

            tips()

            args.files = list(self.filenames)
            if self.colorCB.get() == "by scalar":
                args.color = None
            else:
                if self.colorCB.get() == 'red':
                    args.color = 'crimson'
                elif self.colorCB.get() == 'green':
                    args.color = 'limegreen'
                elif self.colorCB.get() == 'blue':
                    args.color = 'darkcyan'
                else:
                    args.color = self.colorCB.get()

            args.alpha = self.alphaCB.get()

            args.wireframe = False
            args.showedges = False
            args.point_size = 0
            if self.surfmodeCB.get() == 'point cloud':
                args.point_size = 2
            elif self.surfmodeCB.get() == 'wireframe':
                args.wireframe = True
            elif self.surfmodeCB.get() == 'surf. & edges':
                args.showedges = True
            else:
                pass  # normal surface mode

            args.lighting = self.lightCB.get()
            args.flat = self.flat.get()

            args.no_camera_share = self.noshare.get()
            args.background = self.bgcolorCB.get()

            args.background_grad = None
            if self.background_grad.get():
                b = getColor(args.background)
                args.background_grad = (b[0] / 1.8, b[1] / 1.8, b[2] / 1.8)

            args.multirenderer_mode = False
            args.scrolling_mode = False
            if self.schememodeCB.get() == "n sync-ed renderers":
                args.multirenderer_mode = True
            elif self.schememodeCB.get() == "mesh browser":
                args.scrolling_mode = True

            args.ray_cast_mode = False
            args.lego = False
            args.slicer = False
            args.slicer2d = False
            args.lego = False
            args.mode = 0
            if self.modeCB.get() == "composite":
                args.ray_cast_mode = True
                args.mode = 0
            elif self.modeCB.get() == "maximum proj":
                args.ray_cast_mode = True
                args.mode = 1
            elif self.modeCB.get() == "slicer":
                args.slicer = True
            elif self.modeCB.get() == "slicer2d":
                args.slicer2d = True
            elif self.modeCB.get() == "lego":
                args.lego = True

            args.x_spacing = 1
            args.y_spacing = 1
            args.z_spacing = 1
            if self.xspacing.get() != '1.0':
                args.x_spacing = float(self.xspacing.get())
            if self.yspacing.get() != '1.0':
                args.y_spacing = float(self.yspacing.get())
            if self.zspacing.get() != '1.0':
                args.z_spacing = float(self.zspacing.get())

            draw_scene(args)
            if os.name == "nt":
                exit()
            if settings.plotter_instance:
                settings.plotter_instance.close()
Beispiel #22
0
class ipGUI:
    def __init__(self, master):
        self.master = master
        self.master.minsize(width=800, height=600)

        menu = Menu(self.master)
        master.config(menu=menu)

        # ***** Main Menu *****
        # *** file menu ***
        fileMenu = Menu(menu)
        menu.add_cascade(label='File', menu=fileMenu)
        fileMenu.add_command(label="Open", command=self.openImage)
        fileMenu.add_command(label="Load Blur Kernel", command=self.loadKernel)
        fileMenu.add_command(label="Save", command=self.saveImage)
        fileMenu.add_command(label="Exit", command=master.destroy)

        # *** edit menu ***
        editMenu = Menu(menu)
        menu.add_cascade(label='Space', menu=editMenu)
        editMenu.add_command(label="Histogram Equalization",
                             command=self.histWrap)
        editMenu.add_command(label="Gamma Correction",
                             command=self.gammaCorWrap)
        editMenu.add_command(label="Log Transform", command=self.logTranWrap)
        editMenu.add_command(label="Sharpen", command=self.sharpWrap)
        editMenu.add_command(label="Cartoonify", command=self.cartoonifyWrap)

        # *** blur menu ***
        blurMenu = Menu(editMenu)
        editMenu.add_cascade(label='Blur', menu=blurMenu)
        blurMenu.add_command(label="Box", command=self.boxBlurWrap)
        blurMenu.add_command(label="Gaussian", command=self.gaussianBlurWrap)
        blurMenu.add_command(label="Median", command=self.medianBlurWrap)

        # *** frequency filtering ***
        freqMenu = Menu(menu)
        menu.add_cascade(label='Frequency', menu=freqMenu)
        freqMenu.add_command(label="DFT", command=self.dftWrap)
        freqMenu.add_command(label="Load Mask", command=self.freqMaskWrap)

        # *** Mask Menu ***
        maskMenu = Menu(freqMenu)
        freqMenu.add_cascade(label='Create Mask', menu=maskMenu)
        maskMenu.add_command(label='Low Pass', command=self.lpmWrap)
        maskMenu.add_command(label='High Pass', command=self.hpmWrap)
        maskMenu.add_command(label='Band Pass', command=self.bppmWrap)
        maskMenu.add_command(label='Band Stop', command=self.bspmWrap)

        # *** frequency filtering ***
        restorationMenu = Menu(menu)
        menu.add_cascade(label='Restoration', menu=restorationMenu)
        restorationMenu.add_command(label="Full Inverse",
                                    command=self.fullInverseWrap)
        restorationMenu.add_command(label="Radially Limited Inverse",
                                    command=self.truncatedInverseWrap)
        restorationMenu.add_command(label="Approximate Weiner",
                                    command=self.approximateWeinerWrap)
        restorationMenu.add_command(label="Constrained LS",
                                    command=self.contrainedLSWrap)

        # ***** Toolbar *****
        toolbar = Frame(master, bg="grey")
        undoButton = Button(toolbar, text="Undo", command=self.undoFunc)
        undoButton.pack(side=LEFT)
        origButton = Button(toolbar, text="Original", command=self.origFunc)
        origButton.pack(side=LEFT)
        toolbar.pack(side=TOP, fill=X)

        # ***** Image Display Area *****
        self.frame = Frame(self.master)
        self.frame.pack()
        self.panel = Label(self.frame)
        self.panel.pack(padx=10, pady=10)
        self.img = None
        self.origImg = None
        self.prevImg = None

        # ***** Gamma Controls *****
        self.gammaFrame = Frame(self.master)
        self.gammaSlider = Scale(self.gammaFrame,
                                 from_=0.1,
                                 to=2,
                                 orient=HORIZONTAL,
                                 resolution=0.1)
        self.gammaSlider.pack(side=TOP)
        self.gammaExitButton = Button(self.gammaFrame,
                                      text="Exit",
                                      command=self.gammaFrame.pack_forget)
        self.gammaExitButton.pack(side=TOP)

        # ***** Box Blur Controls *****
        self.boxFrame = Frame(self.master)
        self.boxSlider = Scale(self.boxFrame, from_=1, to=5, orient=HORIZONTAL)
        self.boxSlider.pack(side=TOP)
        self.boxExitButton = Button(self.boxFrame,
                                    text="Exit",
                                    command=self.boxFrame.pack_forget)
        self.boxExitButton.pack(side=TOP)

        # ***** Truncated Inverse Controls *****
        self.truncatedInverseFrame = Frame(self.master)
        self.truncatedInverseSlider = Scale(self.truncatedInverseFrame,
                                            from_=-3,
                                            to=2,
                                            orient=HORIZONTAL,
                                            resolution=0.1)
        self.truncatedInverseSlider.pack(side=TOP)
        self.truncatedInverseExitButton = Button(
            self.truncatedInverseFrame,
            text="Exit",
            command=self.truncatedInverseFrame.pack_forget)
        self.truncatedInverseExitButton.pack(side=TOP)

        # ***** Weiner Controls *****
        self.weinerFrame = Frame(self.master)
        self.weinerSlider = Scale(self.weinerFrame,
                                  from_=-3,
                                  to=2,
                                  orient=HORIZONTAL,
                                  resolution=0.1)
        self.weinerSlider.pack(side=TOP)
        self.weinerExitButton = Button(self.weinerFrame,
                                       text="Exit",
                                       command=self.weinerFrame.pack_forget)
        self.weinerExitButton.pack(side=TOP)

        # ***** CLS Controls *****
        self.clsFrame = Frame(self.master)
        self.clsSlider = Scale(self.clsFrame,
                               from_=-3,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=0.1)
        self.clsSlider.pack(side=TOP)
        self.clsExitButton = Button(self.clsFrame,
                                    text="Exit",
                                    command=self.clsFrame.pack_forget)
        self.clsExitButton.pack(side=TOP)

        # ***** DFT Display Area ******
        self.dftFrame = Frame(self.master)
        self.magPanel = Label(self.dftFrame)
        self.magPanel.pack(padx=10, pady=10, side=TOP)
        self.freqPanel = Label(self.dftFrame)
        self.freqPanel.pack(padx=10, pady=10, side=TOP)
        self.dftExitButton = Button(
            self.dftFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.dftExitButton.pack(side=TOP, fill=X)

        # ***** Low Pass Mask Creation *****
        self.lpmFrame = Frame(self.master)
        self.lpmPanel = Label(self.lpmFrame)
        self.lpmPanel.pack(padx=10, pady=10, side=TOP)
        self.lpmSubButton = Button(self.lpmFrame, text="submit")
        self.lpmSubButton.pack(side=TOP)
        self.lpmExitButton = Button(
            self.lpmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.lpmExitButton.pack(side=TOP)
        self.lpmSlider = Scale(self.lpmFrame,
                               from_=1,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=1)

        # ***** High Pass Mask Creation *****
        self.hpmFrame = Frame(self.master)
        self.hpmPanel = Label(self.hpmFrame)
        self.hpmPanel.pack(padx=10, pady=10, side=TOP)
        self.hpmSubButton = Button(self.hpmFrame, text="submit")
        self.hpmSubButton.pack(side=TOP)
        self.hpmExitButton = Button(
            self.hpmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.hpmExitButton.pack(side=TOP)
        self.hpmSlider = Scale(self.hpmFrame,
                               from_=1,
                               to=2,
                               orient=HORIZONTAL,
                               resolution=1)

        # ***** Band Pass Mask Creation *****
        self.bppmFrame = Frame(self.master)
        self.bppmPanel = Label(self.bppmFrame)
        self.bppmPanel.pack(padx=10, pady=10, side=TOP)
        self.bppmSubButton = Button(self.bppmFrame, text="submit")
        self.bppmSubButton.pack(side=TOP)
        self.bppmExitButton = Button(
            self.bppmFrame,
            text="Exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.bppmExitButton.pack(side=TOP)
        self.bppmSliderLow = Scale(self.bppmFrame,
                                   from_=1,
                                   to=2,
                                   orient=HORIZONTAL,
                                   resolution=1)
        self.bppmSliderHigh = Scale(self.bppmFrame,
                                    from_=1,
                                    to=2,
                                    orient=HORIZONTAL,
                                    resolution=1)

        # ***** Band Pass Mask Creation *****
        self.bspmFrame = Frame(self.master)
        self.bspmPanel = Label(self.bspmFrame)
        self.bspmPanel.pack(padx=10, pady=10, side=TOP)
        self.bspmSubButton = Button(self.bspmFrame, text="submit")
        self.bspmSubButton.pack(side=TOP)
        self.bspmExitButton = Button(
            self.bspmFrame,
            text="exit",
            command=lambda: self.displayImg(np.array(self.img)))
        self.bspmExitButton.pack(side=TOP)
        self.bspmSliderLow = Scale(self.bspmFrame,
                                   from_=1,
                                   to=2,
                                   orient=HORIZONTAL,
                                   resolution=1)
        self.bspmSliderHigh = Scale(self.bspmFrame,
                                    from_=1,
                                    to=2,
                                    orient=HORIZONTAL,
                                    resolution=1)

    def displayImg(self, img):
        # input image in RGB
        self.frame.pack()
        self.dftFrame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.img = Image.fromarray(img)
        imgtk = ImageTk.PhotoImage(self.img)

        self.panel.configure(image=imgtk)
        self.panel.image = imgtk

    def openImage(self):
        # can change the image
        path = filedialog.askopenfilename()
        if len(path) > 0:
            imgRead = cv2.imread(path)
            if imgRead is not None:
                imgRead = cv2.cvtColor(imgRead, cv2.COLOR_BGR2RGB)
                self.origImg = Image.fromarray(imgRead)
                self.prevImg = Image.fromarray(imgRead)
                self.displayImg(imgRead)
            else:
                raise ValueError("Not a valid image")
        else:
            raise ValueError("Not a valid path")

    def loadKernel(self):
        path = filedialog.askopenfilename()
        if len(path) > 0:
            self.filter_kernel = np.mean(cv2.imread(path), axis=-1)
            self.filter_kernel = self.filter_kernel / np.sum(
                self.filter_kernel)
        else:
            raise ValueError("Not a valid path")

    def saveImage(self):
        if self.img is not None:
            toSave = filedialog.asksaveasfilename()
            self.img.save(toSave)
        else:
            messagebox.showerror(title="Save Error",
                                 message="No image to be saved!")

    def histWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.histEqlFunc(img)
        self.displayImg(imgNew)

    # Gamma Correction
    def gammaCallback(self, event, img):
        gamma = self.gammaSlider.get()
        self.prevImg = self.img
        imgNew = image_utils.gammaCorFunc(img, 255.0 / (255.0**gamma), gamma)
        self.displayImg(imgNew)

    def truncatedInverseCallback(self, event, img):
        th = 10**self.truncatedInverseSlider.get()
        imgNew = self.truncatedInverseFilter(th)
        self.displayImg(imgNew)

    def weinerCallback(self, event, img):
        gamma = 10**self.weinerSlider.get()
        imgNew = self.weinerFilter(gamma)
        self.displayImg(imgNew)

    def clsCallback(self, event, img):
        K = 10**self.clsSlider.get()
        imgNew = self.clsFilter(K)
        self.displayImg(imgNew)

    def gammaCorWrap(self):
        img = np.array(self.img)
        self.gammaFrame.pack()
        self.gammaSlider.set(1.0)
        self.gammaSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.gammaCallback(event, img))

    def logTranWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.logTranFunc(img, 255.0 / np.log10(256))
        self.displayImg(imgNew)

    def sharpWrap(self):
        # Sharpen Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.sharpFunc(img)
        self.displayImg(imgNew)

    def boxBlurWrap(self):
        # Box Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        self.boxFrame.pack()
        self.boxSlider.set(1)
        self.boxSlider.bind("<ButtonRelease-1>",
                            lambda event, img=img: self.displayImg(
                                image_utils.boxBlurFunc(
                                    event, img, 2 * self.boxSlider.get() + 1)))

    def gaussianBlurWrap(self):
        # Gaussian Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.gaussianBlurFunc(img)
        self.displayImg(imgNew)

    def medianBlurWrap(self):
        # Median Blur Wrapper
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.medianBlurFunc(img)
        self.displayImg(imgNew)

    def cartoonifyWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = image_utils.cartoonifyFunc(img)
        self.displayImg(imgNew)

    def undoFunc(self):
        self.img = self.prevImg
        self.displayImg(np.array(self.img))

    def origFunc(self):
        self.prevImg = self.img
        self.img = self.origImg
        self.displayImg(np.array(self.img))

    def displayDFT(self, x_fft):
        m, n = x_fft.shape[:]
        self.frame.pack_forget()
        self.dftFrame.pack()

        x_mag = np.log10(np.absolute(x_fft)) * 255 / np.log10(m * n * 255)
        x_mag = Image.fromarray(x_mag)
        x_mag = x_mag.resize((min(256, m), min(int(256 * n / m), n)),
                             Image.ANTIALIAS)
        x_mag = ImageTk.PhotoImage(x_mag)

        x_freq = (np.angle(x_fft) % 360) * 255 / 360
        x_freq = Image.fromarray(x_freq)
        x_freq = x_freq.resize((min(256, m), min(int(256 * n / m), n)),
                               Image.ANTIALIAS)
        x_freq = ImageTk.PhotoImage(x_freq)

        self.magPanel.configure(image=x_mag)
        self.magPanel.image = x_mag

        self.freqPanel.configure(image=x_freq)
        self.freqPanel.image = x_freq

    def dftWrap(self):
        img = np.array(self.img)
        x = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        x_outp_img = fft.fft2d_img(x)
        self.displayDFT(x_outp_img)

    def freqMaskWrap(self):
        m, n = np.array(self.img).shape[:2]
        lm, ln = np.log2(m), np.log2(m)
        dm, dn = int(2**np.ceil(lm)) + 1, int(2**np.ceil(ln)) + 1
        messagebox.showinfo(
            "Mask Size",
            "Mask Size should be (" + str(dm) + "," + str(dn) + ")")
        path = filedialog.askopenfilename()
        if len(path) > 0:
            maskRead = cv2.imread(path, 0)
            if (maskRead.shape != (dm, dn)):
                messagebox.showerror(
                    title="Shape Error",
                    message="Shape of mask and image don't match")
            else:
                self.prevImg = self.img
                self.display(image_utils.freqMask(np.array(self.img),
                                                  maskRead))
        else:
            raise ValueError("Not a valid path")

    def maskWrap(self):
        img = np.array(self.img)
        x = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)
        x_outp_img = fft.fft2d_img(x)
        x_mag = image_utils.xMagCreate(x_outp_img)

        return x_outp_img, x_mag

    def maskFinal(self, x_outp_img):
        self.prevImg = self.img
        img = np.array(self.img)
        img = cv2.cvtColor(img, cv2.COLOR_RGB2HSV)
        m = len(img)
        res = fft.ifft2d_img(x_outp_img)
        res = np.array(res * 255 / np.max(res), dtype=np.uint8)
        res = np.array([[[img[i][j][0], img[i][j][1], res[i][j]]
                         for j in range(m)] for i in range(m)])
        res = cv2.cvtColor(res, cv2.COLOR_HSV2RGB)
        self.displayImg(res)

    def lpmCallBack(self, event, slider, x_outp_img):
        m = len(x_outp_img)
        m2 = int((m - 1) / 2)
        r = slider.get()
        x_outp_copy = np.copy(x_outp_img)

        nCircle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(m)]
                            for i in range(m)])
        nCircle = np.where(nCircle > r**2)
        x_outp_copy[nCircle] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.lpmPanel.configure(image=x_mag)
        self.lpmPanel.image = x_mag

    def lpmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = self.lpmSlider.get()
        nCircle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nCircle = np.where(nCircle > r**2)
        x_outp_img[nCircle] = 0

        self.maskFinal(x_outp_img)

    def lpmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.lpmPanel.configure(image=x_mag)
        self.lpmPanel.image = x_mag

        self.lpmSlider.configure(to=int(np.ceil(m / 2)))
        self.lpmSlider.set(1)
        self.lpmSlider.pack(side=TOP)
        self.lpmSlider.bind(
            "<ButtonRelease-1>",
            lambda event, slider=self.lpmSlider, x_outp_img=x_outp_img: self.
            lpmCallBack(event, slider, x_outp_img))

        self.lpmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.lpmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.lpmFrame.pack()

    def hpmCallBack(self, event, slider, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = slider.get()
        x_outp_copy = np.copy(x_outp_img)

        circle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                           for i in range(mx)])
        circle = np.where(circle <= r**2)
        x_outp_copy[circle] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.hpmPanel.configure(image=x_mag)
        self.hpmPanel.image = x_mag

    def hpmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r = self.hpmSlider.get()
        circle = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                           for i in range(mx)])
        circle = np.where(circle <= r**2)
        x_outp_img[circle] = 0

        self.maskFinal(x_outp_img)

    def hpmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.hpmPanel.configure(image=x_mag)
        self.hpmPanel.image = x_mag

        self.hpmSlider.configure(to=m // 2)
        self.hpmSlider.set(1)
        self.hpmSlider.pack(side=TOP)
        self.hpmSlider.bind(
            "<ButtonRelease-1>",
            lambda event, slider=self.hpmSlider, x_outp_img=x_outp_img: self.
            hpmCallBack(event, slider, x_outp_img))

        self.hpmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.hpmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.hpmFrame.pack()

    def bppmCallBack(self, event, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bppmSliderLow.get()
        r2 = self.bppmSliderHigh.get()
        assert (r1 <= r2)

        self.bppmSliderLow.configure(to=r2)
        self.bppmSliderHigh.configure(from_=r1)

        x_outp_copy = np.copy(x_outp_img)
        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where(allVals < r1**2)
        x_outp_copy[nullVals] = 1
        nullVals = np.where(allVals > r2**2)
        x_outp_copy[nullVals] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.bppmPanel.configure(image=x_mag)
        self.bppmPanel.image = x_mag

    def bppmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bppmSliderLow.get()
        r2 = self.bppmSliderHigh.get()

        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where(allVals < r1**2)
        x_outp_img[nullVals] = 0
        nullVals = np.where(allVals > r2**2)
        x_outp_img[nullVals] = 0

        self.maskFinal(x_outp_img)

    def bppmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.bppmPanel.configure(image=x_mag)
        self.bppmPanel.image = x_mag

        self.bppmSliderHigh.configure(from_=1)
        self.bppmSliderHigh.configure(to=m // 2)
        self.bppmSliderHigh.set(m // 2)
        self.bppmSliderHigh.pack(side=TOP)
        self.bppmSliderHigh.bind("<ButtonRelease-1>",
                                 lambda event, x_outp_img=x_outp_img: self.
                                 bppmCallBack(event, x_outp_img))

        self.bppmSliderLow.configure(from_=1)
        self.bppmSliderLow.configure(to=m // 2)
        self.bppmSliderLow.set(1)
        self.bppmSliderLow.pack(side=TOP)
        self.bppmSliderLow.bind("<ButtonRelease-1>",
                                lambda event, x_outp_img=x_outp_img: self.
                                bppmCallBack(event, x_outp_img))

        self.bppmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.bppmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bspmFrame.pack_forget()
        self.bppmFrame.pack()

    def bspmCallBack(self, event, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bspmSliderLow.get()
        r2 = self.bspmSliderHigh.get()
        assert (r1 <= r2)

        self.bspmSliderLow.configure(to=r2)
        self.bspmSliderHigh.configure(from_=r1)

        x_outp_copy = np.copy(x_outp_img)
        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where((allVals - r1**2) * (allVals - r2**2) < 0)
        x_outp_copy[nullVals] = 1

        x_mag = image_utils.xMagCreate(x_outp_copy)

        self.bspmPanel.configure(image=x_mag)
        self.bspmPanel.image = x_mag

    def bspmFinal(self, x_outp_img):
        mx = len(x_outp_img)
        m2 = int((mx - 1) / 2)
        r1 = self.bspmSliderLow.get()
        r2 = self.bspmSliderHigh.get()

        allVals = np.array([[(i - m2)**2 + (j - m2)**2 for j in range(mx)]
                            for i in range(mx)])
        nullVals = np.where((allVals - r1**2) * (allVals - r2**2) < 0)
        x_outp_img[nullVals] = 0

        self.maskFinal(x_outp_img)

    def bspmWrap(self):
        x_outp_img, x_mag = self.maskWrap()
        m = len(x_outp_img)

        self.bspmPanel.configure(image=x_mag)
        self.bspmPanel.image = x_mag

        self.bspmSliderHigh.configure(from_=1)
        self.bspmSliderHigh.configure(to=m // 2)
        self.bspmSliderHigh.set(m // 2)
        self.bspmSliderHigh.pack(side=TOP)
        self.bspmSliderHigh.bind("<ButtonRelease-1>",
                                 lambda event, x_outp_img=x_outp_img: self.
                                 bspmCallBack(event, x_outp_img))

        self.bspmSliderLow.configure(from_=1)
        self.bspmSliderLow.configure(to=m // 2)
        self.bspmSliderLow.set(1)
        self.bspmSliderLow.pack(side=TOP)
        self.bspmSliderLow.bind("<ButtonRelease-1>",
                                lambda event, x_outp_img=x_outp_img: self.
                                bspmCallBack(event, x_outp_img))

        self.bspmSubButton.configure(
            command=lambda x_outp_img=x_outp_img: self.bspmFinal(x_outp_img))

        self.dftFrame.pack_forget()
        self.frame.pack_forget()
        self.lpmFrame.pack_forget()
        self.hpmFrame.pack_forget()
        self.bppmFrame.pack_forget()
        self.bspmFrame.pack()

    def fullInverseWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        imgNew = filtering.inverseFilter2D(img, self.filter_kernel)
        self.displayImg(imgNew)

    def truncatedInverseWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        self.truncatedInverseFilter = filtering.getTruncatedInverseFilter2D(
            img, self.filter_kernel)
        self.truncatedInverseFrame.pack()
        self.truncatedInverseSlider.set(1.0)
        self.truncatedInverseSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.truncatedInverseCallback(event, img))

    def approximateWeinerWrap(self):
        img = np.array(self.img)
        self.prevImg = self.img
        self.weinerFilter = filtering.getApproximateWeinerFilter2D(
            img, self.filter_kernel)
        self.weinerFrame.pack()
        self.weinerSlider.set(1.0)
        self.weinerSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.weinerCallback(event, img))

    def contrainedLSWrap(self):  # TODO: implement
        img = np.array(self.img)
        self.prevImg = self.img
        self.clsFilter = filtering.getConstrainedLSFilter2D(
            img, self.filter_kernel)
        self.clsFrame.pack()
        self.clsSlider.set(1.0)
        self.clsSlider.bind(
            "<ButtonRelease-1>",
            lambda event, img=img: self.clsCallback(event, img))
Beispiel #23
0
cb3 = ttk.Combobox(root)
cb3.grid(row=3, column=2, sticky="we")
cb3['value'] = method()
cb3.current(0)

## row 4
v1 = DoubleVar()
s1 = Scale(root,
           label="Speed:",
           variable=v1,
           from_=0.25,
           to=4.00,
           orient="horizontal",
           resolution=0.01)
s1.grid(row=4, column=1, sticky="wens")
s1.set(1.00)

v2 = DoubleVar()
s2 = Scale(root,
           label="Pitch:",
           variable=v2,
           from_=-20,
           to=20.00,
           orient="horizontal",
           resolution=0.01)
s2.grid(row=4, column=2, sticky="wens")
s2.set(0)

# row 5: Check and save
# bt1 = Button(root, text = "SPEAK IT", font=("Helvetica", 18, "bold"))
# bt1.grid(row = 5, column = 1, pady = 20, sticky = "we")
class TelloUI(object):
    """
    Wrapper class to enable the GUI.
    """
    def __init__(self, tello):
        """
        Initializes all the element of the GUI, supported by Tkinter

        :param tello: class interacts with the Tello drone.
        """
        self.tello = tello  # videostream device
        self.thread = None  # thread of the Tkinter mainloop
        self.stopEvent = None

        # control variables
        self.distance = 0.1  # default distance for 'move' cmd
        self.degree = 30  # default degree for 'cw' or 'ccw' cmd

        # if the flag is TRUE,the auto-takeoff thread will stop waiting
        # for the response from tello
        self.quit_waiting_flag = False

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

        # create buttons
        self.btn_landing = tki.Button(self.root,
                                      text='Open Command Panel',
                                      relief='raised',
                                      command=self.openCmdWindow)
        self.btn_landing.pack(side='bottom',
                              fill='both',
                              expand='yes',
                              padx=10,
                              pady=5)

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

        # set a callback to handle when the window is closed
        self.root.wm_title('TELLO Controller')
        self.root.wm_protocol('WM_DELETE_WINDOW', self.on_close)

        # the sending_command will send command to tello every 5 seconds
        self.sending_command_thread = threading.Thread(
            target=self._sendingCommand)

    def _sendingCommand(self):
        """
        Starts a while loop that sends 'command' to tello every 5 second.

        :return: None
        """

        while True:
            self.tello.send_command('command')
            time.sleep(5)

    def _setQuitWaitingFlag(self):
        """
        Set the variable as TRUE; it will stop computer waiting for response from tello.

        :return: None
        """
        self.quit_waiting_flag = True

    def openCmdWindow(self):
        """
        Open the cmd window and initial all the button and text.

        :return: None
        """
        panel = Toplevel(self.root)
        panel.wm_title('Command Panel')

        # create text input entry
        text0 = tki.Label(
            panel,
            text=
            'This Controller map keyboard inputs to Tello control commands\n'
            'Adjust the trackbar to reset distance and degree parameter',
            font='Helvetica 10 bold')
        text0.pack(side='top')

        text1 = tki.Label(
            panel,
            text='W - Move Tello Up\t\t\tArrow Up - Move Tello Forward\n'
            'S - Move Tello Down\t\t\tArrow Down - Move Tello Backward\n'
            'A - Rotate Tello Counter-Clockwise\tArrow Left - Move Tello Left\n'
            'D - Rotate Tello Clockwise\t\tArrow Right - Move Tello Right',
            justify='left')
        text1.pack(side='top')

        self.btn_landing = tki.Button(panel,
                                      text='Land',
                                      relief='raised',
                                      command=self.telloLanding)
        self.btn_landing.pack(side='bottom',
                              fill='both',
                              expand='yes',
                              padx=10,
                              pady=5)

        self.btn_takeoff = tki.Button(panel,
                                      text='Takeoff',
                                      relief='raised',
                                      command=self.telloTakeOff)
        self.btn_takeoff.pack(side='bottom',
                              fill='both',
                              expand='yes',
                              padx=10,
                              pady=5)

        # binding arrow keys to drone control
        self.tmp_f = tki.Frame(panel, width=100, height=2)
        self.tmp_f.bind('<KeyPress-w>', self.on_keypress_w)
        self.tmp_f.bind('<KeyPress-s>', self.on_keypress_s)
        self.tmp_f.bind('<KeyPress-a>', self.on_keypress_a)
        self.tmp_f.bind('<KeyPress-d>', self.on_keypress_d)
        self.tmp_f.bind('<KeyPress-Up>', self.on_keypress_up)
        self.tmp_f.bind('<KeyPress-Down>', self.on_keypress_down)
        self.tmp_f.bind('<KeyPress-Left>', self.on_keypress_left)
        self.tmp_f.bind('<KeyPress-Right>', self.on_keypress_right)
        self.tmp_f.pack(side='bottom')
        self.tmp_f.focus_set()

        self.btn_landing = tki.Button(panel,
                                      text='Flip',
                                      relief='raised',
                                      command=self.openFlipWindow)
        self.btn_landing.pack(side='bottom',
                              fill='both',
                              expand='yes',
                              padx=10,
                              pady=5)

        self.distance_bar = Scale(panel,
                                  from_=0.02,
                                  to=5,
                                  tickinterval=0.01,
                                  digits=3,
                                  label='Distance(m)',
                                  resolution=0.01)
        self.distance_bar.set(0.2)
        self.distance_bar.pack(side='left')

        self.btn_distance = tki.Button(
            panel,
            text='Reset Distance',
            relief='raised',
            command=self.updateDistancebar,
        )
        self.btn_distance.pack(side='left',
                               fill='both',
                               expand='yes',
                               padx=10,
                               pady=5)

        self.degree_bar = Scale(panel,
                                from_=1,
                                to=360,
                                tickinterval=10,
                                label='Degree')
        self.degree_bar.set(30)
        self.degree_bar.pack(side='right')

        self.btn_distance = tki.Button(panel,
                                       text='Reset Degree',
                                       relief='raised',
                                       command=self.updateDegreebar)
        self.btn_distance.pack(side='right',
                               fill='both',
                               expand='yes',
                               padx=10,
                               pady=5)

    def openFlipWindow(self):
        """
        Open the flip window and initial all the button and text.

        :return: None
        """
        panel = Toplevel(self.root)
        panel.wm_title('Gesture Recognition')

        self.btn_flipl = tki.Button(panel,
                                    text='Flip Left',
                                    relief='raised',
                                    command=self.telloFlip_l)
        self.btn_flipl.pack(side='bottom',
                            fill='both',
                            expand='yes',
                            padx=10,
                            pady=5)

        self.btn_flipr = tki.Button(panel,
                                    text='Flip Right',
                                    relief='raised',
                                    command=self.telloFlip_r)
        self.btn_flipr.pack(side='bottom',
                            fill='both',
                            expand='yes',
                            padx=10,
                            pady=5)

        self.btn_flipf = tki.Button(panel,
                                    text='Flip Forward',
                                    relief='raised',
                                    command=self.telloFlip_f)
        self.btn_flipf.pack(side='bottom',
                            fill='both',
                            expand='yes',
                            padx=10,
                            pady=5)

        self.btn_flipb = tki.Button(panel,
                                    text='Flip Backward',
                                    relief='raised',
                                    command=self.telloFlip_b)
        self.btn_flipb.pack(side='bottom',
                            fill='both',
                            expand='yes',
                            padx=10,
                            pady=5)

    def telloTakeOff(self):
        return self.tello.takeoff()

    def telloLanding(self):
        return self.tello.land()

    def telloFlip_l(self):
        return self.tello.flip('l')

    def telloFlip_r(self):
        return self.tello.flip('r')

    def telloFlip_f(self):
        return self.tello.flip('f')

    def telloFlip_b(self):
        return self.tello.flip('b')

    def telloCW(self, degree):
        return self.tello.rotate_cw(degree)

    def telloCCW(self, degree):
        return self.tello.rotate_ccw(degree)

    def telloMoveForward(self, distance):
        return self.tello.move_forward(distance)

    def telloMoveBackward(self, distance):
        return self.tello.move_backward(distance)

    def telloMoveLeft(self, distance):
        return self.tello.move_left(distance)

    def telloMoveRight(self, distance):
        return self.tello.move_right(distance)

    def telloUp(self, dist):
        return self.tello.move_up(dist)

    def telloDown(self, dist):
        return self.tello.move_down(dist)

    def updateDistancebar(self):
        self.distance = self.distance_bar.get()
        print(f'reset distance to {self.distance:.1f}')

    def updateDegreebar(self):
        self.degree = self.degree_bar.get()
        print(f'reset distance to {self.degree}')

    def on_keypress_w(self, event):
        print(f'up {self.distance} m')
        self.telloUp(self.distance)

    def on_keypress_s(self, event):
        print(f'down {self.distance} m')
        self.telloDown(self.distance)

    def on_keypress_a(self, event):
        print(f'ccw {self.degree} degree')
        self.tello.rotate_ccw(self.degree)

    def on_keypress_d(self, event):
        print(f'cw {self.degree} m')
        self.tello.rotate_cw(self.degree)

    def on_keypress_up(self, event):
        print(f'forward {self.distance} m')
        self.telloMoveForward(self.distance)

    def on_keypress_down(self, event):
        print(f'backward {self.distance} m')
        self.telloMoveBackward(self.distance)

    def on_keypress_left(self, event):
        print(f'left {self.distance} m')
        self.telloMoveLeft(self.distance)

    def on_keypress_right(self, event):
        print(f'right {self.distance} m')
        self.telloMoveRight(self.distance)

    def on_close(self):
        """
        Sets the stop event, cleanup the camera, and allow the rest of
        the quit process to continue.
        :return: None
        """
        print('[INFO] closing...')
        self.stopEvent.set()
        del self.tello
        self.root.quit()
Beispiel #25
0
class Application(Frame):

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.pack()
        self.createWidgets()

    def generate(self):
        n = int(self.menu_gen.get())
        seed = self.inp_seed.get()
        self.output = Generator.convert(seed, n)
        if len(self.output) > 0:
            self.generated = True
            self.butt_draw.config(    state= 'normal')
            self.chek_fullscrn.config(state= 'normal')
            self.clearOutput(self.output)

    def draw(self, n, step=False):
        p1, p2 = Draw.move(n)
        self.curr_canvas.create_line(p1[0], p1[1], p2[0], p2[1], fill= self.color, width= self.thick)
        if step:
            self.curr_canvas.update_idletasks()

    def do(self, action, step, rainbow):
        if len(action) > 1:
            p = action[1]
        else:
            p = 1.0

        self.timebuff += step
        cmd = action[0].lower()
        if cmd == "draw":
            if rainbow:
                self.incColor()
                if self.incThickYN:
                    self.incThick(self.reverseThick, False)
            elif self.incThickYN:
                self.incThick(self.reverseThick, True)
            if self.timebuff > 1.0:
                truncate = int(self.timebuff)
                self.after(truncate, self.draw(float(p), True))
                self.timebuff -= truncate
            else:
                self.draw(float(p))
        elif cmd == "turn":
            Draw.turn(float(p))
        elif cmd == "skip":
            Draw.skip(float(p))
        elif cmd == "back":
            Draw.back(float(p))
        elif cmd == "color":
            if not rainbow:
                self.color = Color.getHexString(p)
        elif cmd == "thick":
            self.thick = int(p)
        else:
            print("Unknown command " + cmd)

    def drawAll(self, newWindow= True):
        if self.generated == True:
            self.butt_print.config(state= 'disabled')
            self.timebuff = 0.0
            self.color = Color.white()
            self.thick = 2
            l = float(self.slid_linesize.get())
            a = float(self.slid_angle.get())
            Draw.init(self.startingPoint, l, a)
            if self.fullScreen.get() == 1:
                if newWindow:
                    self.curr_canvas = dc.BigCanvas(self).canvas
                self.canvas.delete("all")
            else:
                self.curr_canvas = self.canvas
            self.curr_canvas.delete("all")
            self.curr_canvas.config(bg= Color.getHexString(self.bgColor.get()))
            rainbow = self.rainbowCheck.get() == 1
            if rainbow or self.incThickYN:
                self.incStep = 1.0/float(self.getDrawCount(self.output))
                self.percent = 0.0
            for c in self.output:
                if c == '[':
                    Draw.push()
                elif c == ']':
                    Draw.pop()
                else:
                    for r in Rule.getDrawings():
                        if c == r[0]:
                            if len(r) > 2:
                                params = (r[1], r[2])
                            else:
                                params = (r[1],)
                            s = float(self.slid_timer.get())
                            self.do(params, s, rainbow)
                            break
            self.butt_print.config(state= 'normal')

    def incColor(self):
        self.color    = Color.getValueByPercent(self.percent)
        self.percent += self.incStep

    def incThick(self, reverse, incYN):
        maxthick = 5
        minthick = 1
        diff = maxthick - minthick
        if reverse:
            result = maxthick - int(diff * self.percent)
        else:
            result = minthick + int(diff * self.percent)
        self.thick = result
        if incYN:
            self.percent += self.incStep

    def getDrawCount(self, s):
        draw_commands = []
        for r in Rule.getDrawings():
            if r[1].lower() == "draw":
                draw_commands.append(r[0])
        draw_count = 0;
        for c in s:
            for d in draw_commands:
                if c == d:
                    draw_count += 1
                    break
        return draw_count

    def clearOutput(self, replacement=None):
        self.text_output.config(state= 'normal')
        self.text_output.delete(1.0, END)
        if replacement:
            self.text_output.insert(END, replacement)
        self.text_output.config(state= 'disabled')

    def formatRules(self, rules):
        ret = []
        for r in rules:
            entry = r[0] + " | " + r[1]
            if len(r) > 2:
                entry += " " + r[2]
            ret.append(entry)
        return ret

    def getRuleFromFormatted(self, s):
        if s:
            rule = s.split('|')
            rule[0] = rule[0].strip()
            rule[1] = rule[1].strip()
            prod = rule[1].split(" ")
            if len(prod) == 1:
                return (rule[0], prod[0])
            else:
                return (rule[0], prod[0], prod[1])

    def RefreshLists(self):
        self.list_prod.delete(0, END)
        self.list_draw.delete(0, END)

        l = self.formatRules(Rule.getProductions())
        for p in l:
            self.list_prod.insert(END, p)

        l = self.formatRules(Rule.getDrawings())
        for d in l:
            self.list_draw.insert(END, d)




    def AddProductionRule(self, edit=None):
        rule = dp.AddProductionRuleDialog(self, edit).result
        if rule:
            if edit:
                Rule.removeProd(edit[0])
            Rule.AddProduction(rule)
            self.RefreshLists()

    def AddDrawingRule(self, edit=None):
        rule = dd.AddDrawingRuleDialog(self, edit).result
        if rule:
            if edit:
                Rule.removeDraw(edit[0])
            Rule.AddDrawing(rule)
            self.RefreshLists()

    def EditProductionRule(self):
        s = self.list_prod.curselection()
        if s:
            idx = s[0]
            rule = (idx,) + self.getRuleFromFormatted(self.list_prod.get(idx))
            if rule:
                self.AddProductionRule(rule)

    def EditDrawingRule(self):
        s = self.list_draw.curselection()
        if s:
            idx = s[0]
            rule = (idx,) + self.getRuleFromFormatted(self.list_draw.get(idx))
            if rule:
                self.AddDrawingRule(rule)

    def DeleteProductionRule(self):
        s = self.list_prod.curselection()
        if s:
            Rule.removeProd(s[0])
            self.RefreshLists()

    def DeleteDrawingRule(self):
        s = self.list_draw.curselection()
        if s:
            Rule.removeDraw(s[0])
            self.RefreshLists()


    def packOutput(self):
        ret = ""
        ret += self.packAxiom()
        ret += self.packProdRules()
        ret += self.packDrawRules()
        return ret

    def packAxiom(self):
        return "@" + str(self.inp_seed.get()).strip()

    def packRules(self, rules):
        ret = "@"
        for r in rules:
            ret += "$" + str(r[0]) + "|" + str(r[1])
            if len(r) > 2:
                ret += ":" + str(r[2])
        return ret

    def packProdRules(self):
        return self.packRules(Rule.getProductions())

    def packDrawRules(self):
        return self.packRules(Rule.getDrawings())


    def parseProdRules(self, raw):
        rules = raw.split('$')
        for rule in rules:
            if rule is not "":
                r = rule.split('|')
                Rule.AddProduction((r[0], r[1]))

    def parseDrawRules(self, raw):
        rules = raw.split('$')
        for rule in rules:
            if rule is not "":
                r = rule.split('|')
                p = r[1].split(':')
                if len(p) == 1:
                    tup = (r[0], p[0])
                else:
                    tup = (r[0], p[0], p[1])
                Rule.AddDrawing(tup)


    def parseSaveFile(self, s):
        Rule.wipe()
        settings = s.split('@')
        self.inp_seed.set(str(settings[1]))
        self.parseProdRules(settings[2])
        self.parseDrawRules(settings[3])
        self.RefreshLists()


    def save(self):
        try:
            filename = filedialog.asksaveasfilename(**self.file_options['txt'])
            if filename:
                f = open(filename, 'w')
                f.write(self.packOutput())
                f.close()
        except Exception as e:
            print("File IO error in save\n", e)

    def load(self):
        try:
            filename = filedialog.askopenfilename(**self.file_options['txt'])
            if filename:
                f = open(filename, 'r')
                self.parseSaveFile(f.read())
                f.close()
                self.slid_linesize.set(1.0)
                self.slid_timer.set(0.0)
                self.menu_gen.set(1)
                self.clearOutput()

        except Exception as e:
            print("File IO error in load\n" + e)

    def help(self):
        help.HelpDialog(self)


    def saveImage(self):
        filename = filedialog.asksaveasfilename(**self.file_options['ps'])
        self.curr_canvas.postscript(file=filename, colormode='color')

    def click(self, event):
        self.startingPoint = (event.x, event.y)

    def clickAndRedraw(self, event):
        self.click(event)
        self.drawAll(False)

    def fileOptions(self):
        self.file_options = {}
        txt_options  = {}
        ps_options  = {}
        txt_options['defaultextension'] = '.txt'
        txt_options['filetypes'] = [('Plaintext', '.txt')]
        txt_options['initialdir'] = 'Patterns'
        ps_options['defaultextension'] = '.ps'
        ps_options['filetypes'] = [('Postscript Image', '.ps')]
        ps_options['initialdir'] = 'Images'
        self.file_options['txt'] = txt_options
        self.file_options['ps'] = ps_options

    def makeMenuBar(self):
        self.menubar = Menu(self);
        self.menubar.add_command(label="Save", command= self.save)
        self.menubar.add_command(label="Load", command= self.load)
        self.menubar.add_command(label="Help", command= self.help)
        root.config(menu= self.menubar)

    def makeInputFrame(self):
        self.inp_seed         = String()
        self.bgColor          = String()
        self.gen_value        = Int()
        self.rainbowCheck     = Int()
        self.fram_input       = Frame(self,              bd= 2, relief= self.style, width= input_frame_width, height= input_frame_height)
        self.fram_seed        = Frame(self.fram_input,   bd= 1, relief= self.style)
        self.fram_prod        = Frame(self.fram_input,   bd= 1, relief= self.style)
        self.fram_draw        = Frame(self.fram_input,   bd= 1, relief= self.style)
        self.fram_drawParams  = Frame(self.fram_input,   bd= 1, relief= self.style)
        self.fram_gen         = Frame(self.fram_input,   bd= 1, relief= self.style)
        self.fram_output      = Frame(self.fram_input,   bd= 1, relief= self.style)
        self.menu_gen         = DropDown(self.fram_gen,  textvariable= self.gen_value, state= 'readonly')
        self.entr_seed        = Input(self.fram_seed,    textvariable= self.inp_seed)
        self.text_output      = Output(self.fram_output, width= 35, height= 10)
        self.scrl_output      = Scrollbar(self.fram_output)
        self.list_prod        = List(self.fram_prod,     selectmode= BROWSE, font= "Courier 8", height= 5)
        self.list_draw        = List(self.fram_draw,     selectmode= BROWSE, font= "Courier 8", height= 5)
        self.slid_linesize    = Slider(self.fram_drawParams,  from_= 0.1, to= 10.0,     orient= HORIZONTAL, resolution= 0.1, length= 180)
        self.slid_timer       = Slider(self.fram_drawParams,  from_= 0, to= 2,          orient= HORIZONTAL, resolution= 0.02, length= 180)
        self.slid_angle       = Slider(self.fram_drawParams,  from_= 0, to= 359,        orient= HORIZONTAL, length= 180)
        self.entr_bgcolor     = Input (self.fram_drawParams, textvariable= self.bgColor)
        self.butt_prodAdd     = Button(self.fram_prod,   text= "Add",    width=8, command= self.AddProductionRule)
        self.butt_prodEdit    = Button(self.fram_prod,   text= "Edit",   width=8, command= self.EditProductionRule)
        self.butt_prodDelete  = Button(self.fram_prod,   text= "Delete", width=8, command= self.DeleteProductionRule)
        self.butt_drawAdd     = Button(self.fram_draw,   text= "Add",    width=8, command= self.AddDrawingRule)
        self.butt_drawEdit    = Button(self.fram_draw,   text= "Edit",   width=8, command= self.EditDrawingRule)
        self.butt_drawDelete  = Button(self.fram_draw,   text= "Delete", width=8, command= self.DeleteDrawingRule)
        self.chek_incColor    = CheckBox(self.fram_draw, text= "Rainbow", variable= self.rainbowCheck)
        Label(self.fram_seed,       text= "Axiom:", width=8).grid             (row=0, column=0)
        Label(self.fram_prod,       text= "Production\nRules:", width=8).grid (row=0, column=0)
        Label(self.fram_draw,       text= "Drawing\nRules:", width=8).grid    (row=0, column=0)
        Label(self.fram_drawParams, text= "Line Size:").grid                  (row=0, column=0)
        Label(self.fram_drawParams, text= "Delay (ms):").grid                 (row=1, column=0)
        Label(self.fram_drawParams, text= "Starting Angle:").grid             (row=2, column=0)
        Label(self.fram_drawParams, text= "Background Color:").grid           (row=3, column=0)
        Label(self.fram_output,     text= "Output:").grid                     (row=0, column=0)
        Label(self.fram_gen,        text= "Generations:").grid                (row=0, column=0)

        self.gen_value.set(1)
        self.menu_gen['values'] = tuple(range(1, 13))
        self.slid_linesize.set(1.0)
        self.bgColor.set( Color.default() )
        self.text_output.config(state='disabled', yscrollcommand= self.scrl_output.set)
        self.scrl_output.config(command=self.text_output.yview)

        self.fram_input.grid      (row=0, column=0)
        self.fram_seed.grid       (row=1, column=0, sticky= 'ew')
        self.fram_prod.grid       (row=2, column=0, sticky= 'ew')
        self.fram_draw.grid       (row=3, column=0, sticky= 'ew')
        self.fram_drawParams.grid (row=4, column=0, sticky= 'ew')
        self.fram_gen.grid        (row=5, column=0, sticky= 'ew')
        self.fram_output.grid     (row=6, column=0, sticky= 'ew')
        self.entr_seed.grid       (row=0, column=1, sticky= 'ew')
        self.list_prod.grid       (row=0, column=1, sticky= 'ew')
        self.butt_prodAdd.grid    (row=1, column=0, sticky= 'ew')
        self.butt_prodEdit.grid   (row=1, column=1, sticky= 'ew')
        self.butt_prodDelete.grid (row=1, column=2, sticky= 'ew')
        self.list_draw.grid       (row=0, column=1)
        self.butt_drawAdd.grid    (row=1, column=0, sticky= 'ew')
        self.butt_drawEdit.grid   (row=1, column=1, sticky= 'ew')
        self.butt_drawDelete.grid (row=1, column=2, sticky= 'ew')
        self.chek_incColor.grid   (row=0, column=2)
        self.slid_linesize.grid   (row=0, column=1, sticky= 'ew')
        self.slid_timer.grid      (row=1, column=1, sticky= 'ew')
        self.slid_angle.grid      (row=2, column=1, sticky= 'ew')
        self.entr_bgcolor.grid    (row=3, column=1, sticky= 'ew')
        self.menu_gen.grid        (row=0, column=1, sticky= 'ew')
        self.text_output.grid     (row=1, column=0)
        self.scrl_output.grid     (row=1, column=1, sticky= 'ns')

    def makeCanvasFrame(self):
        self.fram_canvas = Frame(self, bd=10, relief=self.style)
        self.canvas      = Canvas(self.fram_canvas, width= canvas_width, height= canvas_height)
        self.fram_canvas.grid(row=0, column=1, sticky='nesw')
        self.canvas.grid(sticky='nesw')
        self.canvas.bind("<Button-1>", self.click)
        self.curr_canvas = self.canvas

    def makeIgnitionFrame(self):
        self.fullScreen    = Int()
        self.fram_ignition = Frame(self, bd=4, relief=self.style, width= ignition_frame_width, height= ignition_frame_height)
        self.butt_generate = Button(self.fram_ignition,   text= " -- GENERATE -- ", width=111, command= self.generate)
        self.butt_draw     = Button(self.fram_ignition,   text= " -- DRAW -- ",     width=100, command= self.drawAll, state= 'disabled')
        self.butt_print    = Button(self.fram_ignition,   text= "Save Image", command= self.saveImage, state= 'disabled')
        self.chek_fullscrn = CheckBox(self.fram_ignition, text= "Fullscreen", variable= self.fullScreen, state= 'disabled')
        self.fram_ignition.grid(row=1, column=0, columnspan=2)
        self.butt_generate.grid(row=0, column=0, columnspan=2)
        self.butt_draw.grid(    row=1, column=0)
        self.butt_print.grid(   row=0, column=2, rowspan= 2, sticky='ns')
        self.chek_fullscrn.grid(row=1, column=1)

    def createWidgets(self):
        self.incThickYN    = False
        self.reverseThick  = False
        self.style         = RIDGE
        self.startingPoint = (20, 20)
        self.generated     = False
        self.fileOptions()
        self.makeMenuBar()
        self.makeInputFrame()
        self.makeCanvasFrame()
        self.makeIgnitionFrame()
Beispiel #26
0
                     text="Load example image",
                     width=16,
                     command=load_example,
                     activebackground="#e3c3d7")
load2_button = Button(save_load_frame,
                      text="Load example2 image",
                      width=16,
                      command=load2_example,
                      activebackground="#e3c3d7")
curve_n_label = Label(options_frame, text="Curve Flow")
curve_n = Scale(options_frame, from_=4, to=75, orient="horizontal")
curve_guide_label = Label(options_frame, text="show curve guide?")
curve_guide_check = Checkbutton(options_frame, variable=curve_guide)
circle_guide_label = Label(options_frame, text="show circles on click?")
circle_guide_check = Checkbutton(options_frame, variable=click_circle)
curve_n.set(50)
axis_label = Label(options_frame, text="mirror axis")
x_radio = Radiobutton(options_frame, text="X", variable=mirror_axis, value='x')
y_radio = Radiobutton(options_frame, text="Y", variable=mirror_axis, value='y')
xy_radio = Radiobutton(options_frame,
                       text="XY",
                       variable=mirror_axis,
                       value='xy')

#Set in GUI
load_button.pack(side="top")
load2_button.pack(side="top")
save_button.pack(side="bottom")
bg_color_sett.pack(side="left")
curve_n_label.pack(side="left")
curve_n.pack(side="left")
class AuxMode(Frame):
    def __init__(self, root, parent):
        Frame.__init__(self, root, borderwidth=2, relief='groove', height=10)
        settings = parent.settings('aux_mode')
        self.parent = parent

        lbl_power = Label(self, text='Power:')
        lbl_power.grid(row=0, column=0, pady=2)
        self.cmb_power = ttk.Combobox(self, value=['Off', 'On'])
        self.cmb_power.grid(row=0, column=1, pady=2)
        self.cmb_power.set(settings['power'])
        self.cmb_power['state'] = 'readonly'
        self.cmb_power.bind('<<ComboboxSelected>>', self.set_power)

        lbl_aux_pin = Label(self, text='AUX pin:')
        lbl_aux_pin.grid(row=1, column=0, pady=2)
        self.cmb_aux_pin = ttk.Combobox(self, values=['AUX', 'CS'])
        self.cmb_aux_pin.grid(row=1, column=1, pady=2)
        self.cmb_aux_pin['state'] = 'readonly'
        self.cmb_aux_pin.set(settings['aux_pin'])
        self.cmb_aux_pin.bind('<<ComboboxSelected>>', self.select_aux_pin)

        lbl_aux = Label(self, text='AUX mode:')
        lbl_aux.grid(row=2, column=0, pady=2)
        self.cmb_aux_mode = ttk.Combobox(
            self, values=['Input', 'Output', 'Servo', 'PWM'])
        self.cmb_aux_mode.grid(row=2, column=1, pady=2)
        self.cmb_aux_mode['state'] = 'readonly'
        self.cmb_aux_mode.set(settings['mode'])
        self.cmb_aux_mode.bind('<<ComboboxSelected>>', self.select_aux_mode)

        self.aux_servo = Scale(self, from_=0, to=180, orient='horizontal')
        self.aux_servo.set(settings['servo'])
        self.aux_servo.bind('<ButtonRelease-1>', self.select_aux_mode)

        self.aux_pin_state = IntVar()
        self.aux_pin_state.set(settings['aux_state'])
        self.aux_pin_state.trace_add('write', self.select_aux_mode)

        self.aux_high = Radiobutton(self,
                                    text='HIGH',
                                    value=1,
                                    variable=self.aux_pin_state)
        self.aux_low = Radiobutton(self,
                                   text='LOW',
                                   value=0,
                                   variable=self.aux_pin_state)

        self.aux_pwm_lbl = Label(self, text='Frequency (KHz):')
        self.aux_pwm_freq = Entry(self)
        self.aux_pwm_freq.insert(0, settings['pwm_freq'])
        self.aux_pwm_freq.bind('<KeyRelease>', self.select_aux_mode)

        self.aux_pwm_duty_lbl = Label(self, text='Duty cycle (%):')
        self.aux_pwm_duty = Scale(self, from_=0, to=99, orient='horizontal')
        self.aux_pwm_duty.set(settings['pwm_duty'])
        self.aux_pwm_duty.bind('<ButtonRelease-1>', self.select_aux_mode)

    def __call__(self):
        return {
            'power': self.cmb_power.get(),
            'mode': self.cmb_aux_mode.get(),
            'aux_state': self.aux_pin_state.get(),
            'aux_pin': self.cmb_aux_pin.get(),
            'servo': self.aux_servo.get(),
            'pwm_freq': self.aux_pwm_freq.get(),
            'pwm_duty': self.aux_pwm_duty.get()
        }

    def select_aux_mode(self, e=None, a=None, b=None):

        for i, widget in enumerate(self.winfo_children()):
            if i > 5:
                widget.grid_forget()
        mode = self.cmb_aux_mode.get()

        # if self.parent.console.mode == 'HiZ': return
        if mode == 'Input':
            self.parent.console.aux('Input')

        if mode == 'Output':
            self.aux_high.grid(row=3, column=1)
            self.aux_low.grid(row=4, column=1)
            self.parent.console.aux('Output', self.aux_pin_state.get())

        if mode == 'Servo':
            self.aux_servo.grid(row=3, column=1)
            self.parent.console.servo(self.aux_servo.get())

        if mode == 'PWM':
            self.aux_pwm_lbl.grid(row=3, column=0)
            self.aux_pwm_freq.grid(row=3, column=1)
            self.aux_pwm_duty_lbl.grid(row=4, column=0)
            self.aux_pwm_duty.grid(row=4, column=1)
            self.parent.console.pwm(self.aux_pwm_freq.get(),
                                    self.aux_pwm_duty.get())

        if mode == 'CS':
            self.parent.console.cs()

        self.parent.settings('aux_mode', self())

    def select_aux_pin(self, e=None):
        self.parent.console.aux_pin(self.cmb_aux_pin.get())

    def set_power(self, e=None):
        self.parent.console.power(self.cmb_power.get())
        self.parent.settings('aux_mode', self())

    def disable(self):
        self.cmb_power['state'] = 'disabled'
        self.cmb_aux_mode['state'] = 'disabled'
        self.aux_high['state'] = 'disabled'
        self.aux_low['state'] = 'disabled'
        self.aux_servo['state'] = 'disabled'
        self.aux_pwm_freq['state'] = 'disabled'
        self.aux_pwm_duty['state'] = 'disabled'

    def enable(self):
        self.cmb_power['state'] = 'readonly'
        self.cmb_aux_mode['state'] = 'readonly'
        self.aux_high['state'] = 'normal'
        self.aux_low['state'] = 'normal'
        self.aux_servo['state'] = 'normal'
        self.aux_pwm_freq['state'] = 'normal'
        self.aux_pwm_duty['state'] = 'normal'
Beispiel #28
0
class Visual(Frame):
    '''Class that takes a world as argument and present it graphically
    on a tkinter canvas.'''
    def __init__(self):
        '''Sets up a simulation GUI in tkinter.
        '''
        Frame.__init__(self)
        self.master.title("The Schelling Segregation Model in Python")
        self.master.wm_resizable(0, 0)
        self.grid()

        self.movement_possible = True

        # --------------------------------------- #
        # --------- FRAMES FOR GUI -------------- #
        # --------------------------------------- #

        # The pane for user values
        self._entryPane = Frame(self, borderwidth=5, relief='sunken')
        self._entryPane.grid(row=0, column=0, sticky='n')

        # The buttons pane
        self._buttonPane = Frame(self, borderwidth=5)

        self._buttonPane.grid(row=1, column=0, sticky='n')

        # A temp pane where graph is located, just for cosmetic reasons
        width, height = 425, 350
        self._graph = Canvas(self,
                             width=width,
                             height=height,
                             background="black")
        self._graph.configure(relief='sunken', border=2)

        self._graph.grid(row=3, column=0)

        # The pane where the canvas is located
        self._animationPane = Frame(self, borderwidth=5, relief='sunken')
        self._animationPane.grid(row=0,
                                 column=1,
                                 rowspan=4,
                                 pady=10,
                                 sticky="n")

        # --------------------------------------- #
        # --------- FILLING THE FRAMES ---------- #
        # --------------------------------------- #

        self._canvas()  # Create graphics canvas

        self._entry()  # Create entry widgets

        self._buttons()  # Create button widgets

    def _plot_setup(self, time):
        '''Method for crudely annotating the graph window.'''
        time = time

        # Main plot
        width, height = 425, 350
        y0 = -time / 10
        self._graph = Canvas(self,
                             width=width,
                             height=height,
                             background="black",
                             borderwidth=5)
        self._graph.grid(row=3, column=0)
        self.trans = Plotcoords(width, height, y0, -0.2, time, 1.3)

        x, y = self.trans.screen(time // 2, 1.2)
        x1, y1 = self.trans.screen(time // 2, 1.13)
        self._graph.create_text(x,
                                y,
                                text="% Happy",
                                fill="yellow",
                                font="bold 12")
        self._graph.create_text(x1,
                                y1,
                                text="% Unhappy",
                                fill="blue",
                                font="bold 12")

        # Line x-axis
        x, y = self.trans.screen((-5 * (time / 100)), -0.05)
        x1, y = self.trans.screen(time, -0.05)
        self._graph.create_line(x, y, x1, y, fill="white", width=1.5)

        # Text x-axis
        x_text, y_text = self.trans.screen(time / 2, -0.15)
        self._graph.create_text(x_text,
                                y_text,
                                text="Time",
                                fill="white",
                                font="bold 12")

        # Liney-axis
        x, y = self.trans.screen((-0.5 * (time / 100)), -0.05)
        x, y1 = self.trans.screen((-5 * (time / 100)), 1)
        self._graph.create_line(x, y, x, y1, fill="white", width=1.5)

    def _entry(self):
        '''Method for creating widgets for collecting user input.'''

        # N (no of turtles)
        dim = 30 * 30
        self._N_label = Label(self._entryPane,
                              anchor='w',
                              justify='left',
                              text="N:",
                              relief='raised',
                              width=12,
                              height=1,
                              font="italic 20")
        self._N_label.grid(row=0, column=1, ipady=14)

        self._N = Scale(self._entryPane,
                        from_=1,
                        to=dim - 50,
                        resolution=1,
                        bd=3,
                        relief='sunken',
                        orient='horizontal',
                        length=235,
                        tickinterval=849)
        self._N.set(400)
        self._N.grid(row=0, column=2)

        # Ticks (lenght of simulation)
        self._Ticks_label = Label(self._entryPane,
                                  anchor='w',
                                  justify='left',
                                  text="Time:",
                                  relief='raised',
                                  width=12,
                                  height=1,
                                  font="bold 20")
        self._Ticks_label.grid(row=1, column=1, ipady=14)

        self._Ticks = Scale(self._entryPane,
                            from_=10,
                            to=1000,
                            resolution=1,
                            bd=3,
                            relief='sunken',
                            orient='horizontal',
                            length=235,
                            tickinterval=990)
        self._Ticks.set(500)
        self._Ticks.grid(row=1, column=2)

        # % similar wanted
        self._Similar_label = Label(self._entryPane,
                                    anchor='w',
                                    justify='left',
                                    text="Similar wanted:",
                                    relief='raised',
                                    width=12,
                                    height=1,
                                    font="bold 20")

        self._Similar_label.grid(row=2, column=1, ipady=14)

        self._Similar = Scale(self._entryPane,
                              from_=0.0,
                              to=1.0,
                              resolution=0.01,
                              bd=3,
                              relief='sunken',
                              orient='horizontal',
                              length=235,
                              tickinterval=1)
        self._Similar.set(0.76)
        self._Similar.grid(row=2, column=2)

    def _buttons(self):
        '''Method for creating button widgets for setting up, running and plotting results from simulation.'''
        width = 7
        height = 1

        # The 'Setup' button
        self._setupButton = Button(self._buttonPane,
                                   text="Setup",
                                   command=self._setup,
                                   width=width,
                                   height=height,
                                   font="bold 30",
                                   relief='raised',
                                   borderwidth=5)
        self._setupButton.grid(row=0, column=0)

        # The 'Go' button
        self._goButton = Button(self._buttonPane,
                                text="Go",
                                command=self._go,
                                width=width,
                                height=height,
                                font="bold 30",
                                relief='raised',
                                borderwidth=5)
        self._goButton.grid(row=0, column=1)

        # The 'Quit' button
        self._quitButton = Button(self._buttonPane,
                                  text="Quit",
                                  command=self._quit,
                                  width=width,
                                  height=height,
                                  font="bold 30",
                                  relief='raised',
                                  borderwidth=5)
        self._quitButton.grid(row=1, column=0, columnspan=2)

    def _canvas(self):
        '''Creates the canvas on which everything happens.'''
        # The tick counter information
        self._Tick_counter = Label(self._animationPane,
                                   anchor='w',
                                   justify='left',
                                   text="Time:",
                                   width=5,
                                   font="bold 20")
        self._Tick_counter.grid(row=0, column=0, sticky="e")

        self._Tick_counter1 = Label(self._animationPane,
                                    justify='center',
                                    text="",
                                    relief='raised',
                                    width=5,
                                    font="bold 20")
        self._Tick_counter1.grid(row=0, column=1, sticky='w')

        self.canvas_w, self.canvas_h = 750, 750

        self.canvas = Canvas(self._animationPane,
                             width=self.canvas_w,
                             height=self.canvas_h,
                             background="black")

        self.canvas.grid(row=1, column=0, columnspan=2)

    def _setup(self):
        '''Method for 'Setup' button.'''
        ## Clearing the canvas and reset the go button
        self.canvas.delete('all')
        self._goButton['relief'] = 'raised'
        self.N = int(self._N.get())
        self.Ticks = int(self._Ticks.get())
        self.similar = float(self._Similar.get())
        self.data = []
        self.tick_counter = 0
        self._Tick_counter1['text'] = str(self.tick_counter)
        self._plot_setup(self.Ticks)
        self.grid_size = 30
        self.world = World(750, 750, self.grid_size)
        self.create_turtles()
        self.neighbouring_turtles()
        self.draw_turtles()

    def _go(self):
        '''Method for the 'Go' button, i.e. running the simulation.'''
        self._goButton['relief'] = 'sunken'
        if self.tick_counter <= self.Ticks:
            self._Tick_counter1['text'] = str(self.tick_counter)
            self.canvas.update()

            self._graph.update()
            self._graph.after(0)

            # Data collection
            turtles_unhappy = self.check_satisfaction()
            prop_happy, prop_unhappy = self.calc_prop_happy(self.tick_counter)

            self.data_collection(self.tick_counter, prop_happy, prop_unhappy)

            if self.tick_counter >= 1:

                # HAPPY values (%)
                x0 = self.tick_counter - 1
                x1 = self.tick_counter

                # Collecting values from stoblue data
                y0 = self.data[self.tick_counter - 1][1]
                y1 = self.data[self.tick_counter][1]

                # Transforming to tkinter
                x1, y1 = self.trans.screen(x1, y1)
                x0, y0 = self.trans.screen(x0, y0)
                self._graph.create_line(x0,
                                        y0,
                                        x1,
                                        y1,
                                        fill="yellow",
                                        width=1.3,
                                        tag="happy")  # Draw "happy lines

                # UNHAPPY values (%)
                x0 = self.tick_counter - 1
                x1 = self.tick_counter

                # Collecting values from stored data
                y0 = self.data[self.tick_counter - 1][2]
                y1 = self.data[self.tick_counter][2]

                # Transforming to tkinter
                x1, y1 = self.trans.screen(x1, y1)
                x0, y0 = self.trans.screen(x0, y0)
                self._graph.create_line(x0,
                                        y0,
                                        x1,
                                        y1,
                                        fill="blue",
                                        width=1.1,
                                        tag="unhappy")  # Draw unhappy lines

            if prop_happy < 1:
                self.turtle_move(turtles_unhappy)
                self.update_neighbours()
                self.tick_counter += 1
                self.canvas.after(0, self._go())

        self._goButton['relief'] = 'raised'

    def _quit(self):
        '''Method for the 'Quit' button.'''
        self.master.destroy()

    # ------------------------------------------------------ #
    # ---------- FUNCTIONS CALLED AT EACH TICK ------------- #
    # ------------------------------------------------------ #

    def turtle_move(self, unhappy_turtles):
        '''Moves all the unhappy turtles (randomly).'''

        while unhappy_turtles:
            i = random.randint(0, len(unhappy_turtles) - 1)
            turtle = unhappy_turtles.pop(i)
            turtle.move(self)

    def update_neighbours(self):
        '''Updates the turtles neigbour attributes. Called
        after all turtles have moved.'''
        for turtle in self.turtles:
            turtle.update_neighbours()

    def check_satisfaction(self):
        '''Checks to see if turtles are happy or not.
        Returns a list of unhappy turtles, i.e. turtles
        that should move.
 
        Called before the move method.'''

        for turtle in self.turtles:
            turtle.is_happy()

        unhappy_turtles = []
        for element in self.turtles:
            if not element.happy:
                unhappy_turtles.append(element)

        return unhappy_turtles

    def calc_prop_happy(self, i):
        '''Calculates the proportion of happy turtles.'''
        happy = 0
        unhappy = 0

        for turtle in self.turtles:
            if turtle.happy:
                happy += 1
            else:
                unhappy += 1
        prop_happy = happy / len(self.turtles)
        prop_unhappy = unhappy / len(self.turtles)

        return prop_happy, prop_unhappy

    def data_collection(self, i, prop_happy, prop_unhappy):
        '''Method for collecting data at each tick.'''
        self.data.append((i, prop_happy, prop_unhappy))

# ------------------------------------------------------ #
# ---------- INITIALISATION FUNCTIONS ------------------ #
# ------------------------------------------------------ #

    def create_turtles(self):
        '''Method for creating a new list of turtles.
 
        Upon creation they are registered in the World object.'''
        if self.N <= self.grid_size * self.grid_size:
            counter = 0
            self.turtles = []
            while counter < self.N:

                s = "S" + str(counter)
                if counter <= int(self.N / 2):
                    color = "yellow"
                else:
                    color = "blue"

                x = random.randint(0, self.grid_size - 1)
                y = random.randint(0, self.grid_size - 1)

                if not self.world.patch_list[x][y]:
                    new_turtle = Schelling(world=self.world,
                                           x=x,
                                           y=y,
                                           s=s,
                                           color=color,
                                           similar_wanted=self.similar)

                    self.world.register(new_turtle)
                    counter += 1
                    self.turtles.append(new_turtle)
        else:
            print("Number of turtles exceeds world!")

    def draw_turtles(self):
        '''Method for drawing turtles on canvas.
 
           Calls each turtle's own method for drawing.'''
        for turtle in self.turtles:
            turtle.draw(self.canvas)

    def neighbouring_turtles(self):
        '''Method for updating turtles' neighbours.
 
           Calls on each turtle's own method for updating neighbours.'''
        for turtle in self.turtles:
            turtle.get_neighbouring_patches()
Beispiel #29
0
class Report(Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.root = self.winfo_toplevel()
        self.root.title(" ".join((APPNAME, VERSION, "| Report")))
        self.root.resizable(0, 0)
        self.items = None
        headers = ('Page', 'Rank', 'PageRank Value', 'Incoming')
        self.t = Scale(self,
                       from_=0,
                       to=1,
                       label='n-th iteration',
                       bd=1,
                       width=7,
                       orient='horizontal',
                       command=self.__set_t)
        self.t.pack(fill='x')
        self.label = Label(self, anchor='e')
        self.label.pack(fill='x')
        self.tree = Treeview(self,
                             columns=headers,
                             show="headings",
                             height=REPORT_HEIGHT)
        self.tree.column(0, anchor='center', width=55)
        self.tree.column(1, anchor='center', width=55)
        self.tree.column(2, width=175)
        self.tree.column(3, anchor='center', width=55)
        self.scroll = Scrollbar(self, command=self.tree.yview)
        self.scroll.pack(side='right', fill='y')
        self.tree.config(yscrollcommand=self.scroll.set)
        for col in headers:
            self.tree.heading(col, text=col.title())
        self.root.master.focus_force()
        self.root.bind('<Key>', self.__keys)

    def __keys(self, event):
        if event.char == 'i':
            self.t.set(self.t.get() - 1)
        elif event.char == 'I':
            self.t.set(0)
        elif event.char == 'o':
            self.t.set(self.t.get() + 1)
        elif event.char == 'O':
            self.t.set(self.pagerank[1])

    def __set_t(self, t=None):
        self.render(self.pagerank, self.edge_counts, self.d, self.e, t=int(t))

    def render(self, pagerank, edge_counts, d, e, t=None):
        self.d, self.e = d, e
        self.edge_counts = edge_counts
        self.pagerank = pagerank
        if t is not None:
            pr = pagerank[0][t]
        else:
            self.t.config(command=None)
            self.t.config(to=self.pagerank[1])
            self.t.set(self.pagerank[1])
            self.t.config(command=self.__set_t)
            pr = pagerank[0][-1]
        label_text = '# of ranks:{0:>3}     # of iterations:{1:>3}'.format(
            len(set(pr.values())), self.pagerank[1])
        self.label.config(text=label_text)
        in_map = {k: 0 for k in pr.keys()}  # incoming edges by nodes
        for (tail, head), n in edge_counts.items():
            if tail is not head:
                in_map[head] += n

        get_rank = lambda k: sorted(pr.values())[::-1].index(pr[k]) + 1
        data = tuple(
            (k, get_rank(k), pr[k], in_map[k]) for k in sorted(pr.keys()))
        if self.items: self.tree.delete(*self.items)
        self.items = [
            self.tree.insert('', 'end', values=line) for line in data
        ]
        self.tree.pack(side='left', fill='y')
        #self.root.master.focus_force()

    def destroy(self):
        super().destroy()
        self.root.master.r_win = False
        self.root.master.windowsmenu.entryconfig(0, label='[ ] Report window')
        self.root.destroy()
class TelloUI:
    """Wrapper class to enable the GUI."""
    def __init__(self, tello, outputpath):
        """
        Initial all the element of the GUI,support by Tkinter

        :param tello: class interacts with the Tello drone.

        Raises:
            RuntimeError: If the Tello rejects the attempt to enter command mode.
        """

        self.tello = tello  # videostream device
        self.outputPath = outputpath  # the path that save pictures created by clicking the takeSnapshot button
        self.frame = None  # frame read from h264decoder and used for pose recognition
        self.thread = None  # thread of the Tkinter mainloop
        self.stopEvent = None

        # control variables
        self.distance = 0.1  # default distance for 'move' cmd
        self.degree = 30  # default degree for 'cw' or 'ccw' cmd

        # if the flag is TRUE,the auto-takeoff thread will stop waiting for the response from tello
        self.quit_waiting_flag = False

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

        # create buttons
        self.btn_snapshot = tki.Button(self.root,
                                       text="Snapshot!",
                                       command=self.takeSnapshot)
        self.btn_snapshot.pack(side="bottom",
                               fill="both",
                               expand="yes",
                               padx=10,
                               pady=5)

        self.btn_pause = tki.Button(self.root,
                                    text="Pause",
                                    relief="raised",
                                    command=self.pauseVideo)
        self.btn_pause.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

        self.btn_landing = tki.Button(self.root,
                                      text="Open Command Panel",
                                      relief="raised",
                                      command=self.openCmdWindow)
        self.btn_landing.pack(side="bottom",
                              fill="both",
                              expand="yes",
                              padx=10,
                              pady=5)

        # 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("TELLO Controller")
        self.root.wm_protocol("WM_DELETE_WINDOW", self.onClose)

        # the sending_command will send command to tello every 5 seconds
        self.sending_command_thread = threading.Thread(
            target=self._sendingCommand)

    def videoLoop(self):
        """
        The mainloop thread of Tkinter
        Raises:
            RuntimeError: To get around a RunTime error that Tkinter throws due to threading.
        """
        try:
            # start the thread that get GUI image and drwa skeleton
            time.sleep(0.5)
            self.sending_command_thread.start()
            while not self.stopEvent.is_set():
                system = platform.system()

                # read the frame for GUI show
                self.frame = self.tello.read()
                if self.frame is None or self.frame.size == 0:
                    continue

                    # transfer the format from frame to image
                image = Image.fromarray(self.frame)

                # we found compatibility problem between Tkinter,PIL and Macos,and it will
                # sometimes result the very long preriod of the "ImageTk.PhotoImage" function,
                # so for Macos,we start a new thread to execute the _updateGUIImage function.
                if system == "Windows" or system == "Linux":
                    self._updateGUIImage(image)

                else:
                    thread_tmp = threading.Thread(target=self._updateGUIImage,
                                                  args=(image, ))
                    thread_tmp.start()
                    time.sleep(0.03)
        except RuntimeError as e:
            print("[INFO] caught a RuntimeError")

    def _updateGUIImage(self, image):
        """
        Main operation to initial the object of image,and update the GUI panel
        """
        image = ImageTk.PhotoImage(image)
        # if the panel none ,we need to initial 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

    def _sendingCommand(self):
        """
        start a while loop that sends 'command' to tello every 5 second
        """

        while True:
            self.tello.send_command('command')
            time.sleep(5)

    def _setQuitWaitingFlag(self):
        """
        set the variable as TRUE,it will stop computer waiting for response from tello
        """
        self.quit_waiting_flag = True

    def openCmdWindow(self):
        """
        open the cmd window and initial all the button and text
        """
        panel = Toplevel(self.root)
        panel.wm_title("Command Panel")

        # create text input entry
        text0 = tki.Label(
            panel,
            text=
            'This Controller map keyboard inputs to Tello control commands\n'
            'Adjust the trackbar to reset distance and degree parameter',
            font='Helvetica 10 bold')
        text0.pack(side='top')

        text1 = tki.Label(
            panel,
            text='W - Move Tello Up\t\t\tArrow Up - Move Tello Forward\n'
            'S - Move Tello Down\t\t\tArrow Down - Move Tello Backward\n'
            'A - Rotate Tello Counter-Clockwise\tArrow Left - Move Tello Left\n'
            'D - Rotate Tello Clockwise\t\tArrow Right - Move Tello Right',
            justify="left")
        text1.pack(side="top")

        self.btn_landing = tki.Button(panel,
                                      text="Land",
                                      relief="raised",
                                      command=self.telloLanding)
        self.btn_landing.pack(side="bottom",
                              fill="both",
                              expand="yes",
                              padx=10,
                              pady=5)

        self.btn_takeoff = tki.Button(panel,
                                      text="Takeoff",
                                      relief="raised",
                                      command=self.telloTakeOff)
        self.btn_takeoff.pack(side="bottom",
                              fill="both",
                              expand="yes",
                              padx=10,
                              pady=5)

        # binding arrow keys to drone control
        self.tmp_f = tki.Frame(panel, width=100, height=2)
        self.tmp_f.bind('<KeyPress-w>', self.on_keypress_w)
        self.tmp_f.bind('<KeyPress-s>', self.on_keypress_s)
        self.tmp_f.bind('<KeyPress-a>', self.on_keypress_a)
        self.tmp_f.bind('<KeyPress-d>', self.on_keypress_d)
        self.tmp_f.bind('<KeyPress-Up>', self.on_keypress_up)
        self.tmp_f.bind('<KeyPress-Down>', self.on_keypress_down)
        self.tmp_f.bind('<KeyPress-Left>', self.on_keypress_left)
        self.tmp_f.bind('<KeyPress-Right>', self.on_keypress_right)
        self.tmp_f.pack(side="bottom")
        self.tmp_f.focus_set()

        self.btn_landing = tki.Button(panel,
                                      text="Flip",
                                      relief="raised",
                                      command=self.openFlipWindow)
        self.btn_landing.pack(side="bottom",
                              fill="both",
                              expand="yes",
                              padx=10,
                              pady=5)

        self.distance_bar = Scale(panel,
                                  from_=0.02,
                                  to=5,
                                  tickinterval=0.01,
                                  digits=3,
                                  label='Distance(m)',
                                  resolution=0.01)
        self.distance_bar.set(0.2)
        self.distance_bar.pack(side="left")

        self.btn_distance = tki.Button(
            panel,
            text="Reset Distance",
            relief="raised",
            command=self.updateDistancebar,
        )
        self.btn_distance.pack(side="left",
                               fill="both",
                               expand="yes",
                               padx=10,
                               pady=5)

        self.degree_bar = Scale(panel,
                                from_=1,
                                to=360,
                                tickinterval=10,
                                label='Degree')
        self.degree_bar.set(30)
        self.degree_bar.pack(side="right")

        self.btn_distance = tki.Button(panel,
                                       text="Reset Degree",
                                       relief="raised",
                                       command=self.updateDegreebar)
        self.btn_distance.pack(side="right",
                               fill="both",
                               expand="yes",
                               padx=10,
                               pady=5)

    def openFlipWindow(self):
        """
        open the flip window and initial all the button and text
        """

        panel = Toplevel(self.root)
        panel.wm_title("Gesture Recognition")

        self.btn_flipl = tki.Button(panel,
                                    text="Flip Left",
                                    relief="raised",
                                    command=self.telloFlip_l)
        self.btn_flipl.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

        self.btn_flipr = tki.Button(panel,
                                    text="Flip Right",
                                    relief="raised",
                                    command=self.telloFlip_r)
        self.btn_flipr.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

        self.btn_flipf = tki.Button(panel,
                                    text="Flip Forward",
                                    relief="raised",
                                    command=self.telloFlip_f)
        self.btn_flipf.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

        self.btn_flipb = tki.Button(panel,
                                    text="Flip Backward",
                                    relief="raised",
                                    command=self.telloFlip_b)
        self.btn_flipb.pack(side="bottom",
                            fill="both",
                            expand="yes",
                            padx=10,
                            pady=5)

    def takeSnapshot(self):
        """
        save the current frame of the video as a jpg file and put it into outputpath
        """

        # grab the current timestamp and use it to construct the filename
        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, cv2.cvtColor(self.frame, cv2.COLOR_RGB2BGR))
        print("[INFO] saved {}".format(filename))

    def pauseVideo(self):
        """
        Toggle the freeze/unfreze of video
        """
        if self.btn_pause.config('relief')[-1] == 'sunken':
            self.btn_pause.config(relief="raised")
            self.tello.video_freeze(False)
        else:
            self.btn_pause.config(relief="sunken")
            self.tello.video_freeze(True)

    def telloTakeOff(self):
        return self.tello.takeoff()

    def telloLanding(self):
        return self.tello.land()

    def telloFlip_l(self):
        return self.tello.flip('l')

    def telloFlip_r(self):
        return self.tello.flip('r')

    def telloFlip_f(self):
        return self.tello.flip('f')

    def telloFlip_b(self):
        return self.tello.flip('b')

    def telloCW(self, degree):
        return self.tello.rotate_cw(degree)

    def telloCCW(self, degree):
        return self.tello.rotate_ccw(degree)

    def telloMoveForward(self, distance):
        return self.tello.move_forward(distance)

    def telloMoveBackward(self, distance):
        return self.tello.move_backward(distance)

    def telloMoveLeft(self, distance):
        return self.tello.move_left(distance)

    def telloMoveRight(self, distance):
        return self.tello.move_right(distance)

    def telloUp(self, dist):
        return self.tello.move_up(dist)

    def telloDown(self, dist):
        return self.tello.move_down(dist)

    def updateTrackBar(self):
        self.my_tello_hand.setThr(self.hand_thr_bar.get())

    def updateDistancebar(self):
        self.distance = self.distance_bar.get()
        print
        'reset distance to %.1f' % self.distance

    def updateDegreebar(self):
        self.degree = self.degree_bar.get()
        print
        'reset distance to %d' % self.degree

    def on_keypress_w(self, event):
        print
        "up %d m" % self.distance
        self.telloUp(self.distance)

    def on_keypress_s(self, event):
        print
        "down %d m" % self.distance
        self.telloDown(self.distance)

    def on_keypress_a(self, event):
        print
        "ccw %d degree" % self.degree
        self.tello.rotate_ccw(self.degree)

    def on_keypress_d(self, event):
        print
        "cw %d m" % self.degree
        self.tello.rotate_cw(self.degree)

    def on_keypress_up(self, event):
        print
        "forward %d m" % self.distance
        self.telloMoveForward(self.distance)

    def on_keypress_down(self, event):
        print
        "backward %d m" % self.distance
        self.telloMoveBackward(self.distance)

    def on_keypress_left(self, event):
        print
        "left %d m" % self.distance
        self.telloMoveLeft(self.distance)

    def on_keypress_right(self, event):
        print
        "right %d m" % self.distance
        self.telloMoveRight(self.distance)

    def on_keypress_enter(self, event):
        if self.frame is not None:
            self.registerFace()
        self.tmp_f.focus_set()

    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()
        del self.tello
        self.root.quit()
class Visualiser(object):
    '''
    Generic Offline Visualiser. Subclasses need to be used that specify
    how to handle a data source.
    '''
    
    ### Public functions ###

    def __init__(self,
                 title="Visualisation",
                 width=400,
                 height=400,
                 recording=False,
                 recordPattern=None,
                 paused=False,
                 source=None):
        '''
        Constructor.

        Params:
        title: string - Title of the visualisation window
        width: int - Width of the visualisation window
        height: int - Height of the visualisation window
        recording: boolean - Start with recording enabled?
        recordPattern: string - Pattern for recorded images,
          e.g., cylinders%05g.png
        paused: boolean - Start with playback paused?
        source:- The data source to read.
          What is required here varies by visualiser.
        '''

        # Visualisation options
        self.vis_features = []
        self.vis_frame = 0
        self.vis_frameStep = 1
        self.vis_jumping = False
        self.vis_recording = recording
        self.vis_recordPattern = recordPattern
        self.vis_paused = paused
        self.vis_source = source

        # VTK structures
        self.vtk_cells = vtkCellArray()
        self.vtk_renderer = vtkRenderer()

        # Tk structures
        self.tk_root = Tk()
        self.tk_root.title(title)
        self.tk_root.grid_rowconfigure(0, weight=1)
        self.tk_root.grid_columnconfigure(0, weight=3)
        self.tk_root.bind('<Destroy>', self.destroyed)
        if not self.vis_paused: self.tk_root.after(100, self.animate)            

        self.tk_renderWidget = vtkTkRenderWidget(self.tk_root,
                                                 width=width,
                                                 height=height)
        self.tk_renderWidget.grid(row=0, column=0, sticky=N+S+E+W)
        self.tk_renderWidget.GetRenderWindow().AddRenderer(self.vtk_renderer)

        self.tk_featureFrame = Frame(self.tk_root)
        self.tk_featureFrame.grid(row=0, column=1, rowspan=2)
        Label(self.tk_featureFrame, text='Features:').grid(row=0, column=0)

        self.tk_controlFrame = Frame(self.tk_root)
        self.tk_controlFrame.grid(row=1, column=0)

        self.tk_quit = Button(self.tk_controlFrame, text="Quit",
                              command=self.shutdown)
        self.tk_quit.grid(row=0, column=0, columnspan=2)

        def pause():
            if self.vis_paused:
                self.tk_pause.config(text='Pause')
                self.tk_root.after(100, self.animate)
            else:
                self.tk_pause.config(text='Resume')
            self.vis_paused ^= True
        self.tk_pause = Button(self.tk_controlFrame, text="Pause", command=pause)
        self.tk_pause.grid(row=0, column=2, columnspan=2)

        if self.vis_recordPattern is not None:
            def record():
                if self.vis_recording:
                    self.tk_record.config(text='Start Recording')
                else:
                    self.tk_record.config(text='Stop Recording')
                self.vis_recording ^= True
            self.tk_record = Button(self.tk_controlFrame, text="Start Recording", command=record)
            self.tk_record.grid(row=0, column=4, columnspan=2)
            if self.vis_recording:
                self.tk_record.config(text="Stop Recording")

        def make_seek_button(label, column, frame):
            def jump():
                self.jumpTo(frame)
            b = Button(self.tk_controlFrame,
                       text=label,
                       command=jump)
            b.grid(row=1, column=column, sticky=W+E)
            return b
        self.tk_seek_start = make_seek_button("|<", 0, 0)
        self.tk_seek_back10 = make_seek_button("<<", 1,
                                               lambda: self.vis_frame - 10)
        self.tk_seek_back1 = make_seek_button("<", 2,
                                              lambda: self.vis_frame - 1)
        self.tk_seek_forward1 = make_seek_button(">", 3,
                                                 lambda: self.vis_frame + 1)
        self.tk_seek_forward10 = make_seek_button(">>", 4,
                                                  lambda: self.vis_frame + 10)
        self.tk_seek_end = make_seek_button(">|", 5,
                                            self.getMaxFrameNumber)

        Label(self.tk_controlFrame, text='Frame').grid(row=2, column=0,
                                                       sticky=W+E)
        def changeFrame(frame):
            if not self.vis_jumping:
                self.vis_jumping = True
                self.jumpTo(self.tk_frame.get())
                self.vis_jumping = False
        self.tk_frame = Scale(self.tk_controlFrame, command=changeFrame,
                              from_=0, to=0, orient=HORIZONTAL)
        self.tk_frame.grid(row=2, column=1, columnspan=2, sticky=W+E)

        Label(self.tk_controlFrame, text='Step').grid(row=2, column=3,
                                                     sticky=W+E)
        def changeFrameStep(step):
            self.vis_frameStep = int(step)
        self.tk_frameStep = Scale(self.tk_controlFrame, command=changeFrameStep,
                                  from_=1, to=1, orient=HORIZONTAL)
        self.tk_frameStep.grid(row=2, column=4, columnspan=2, sticky=W+E)

        self.setupGrid()

    def add_feature(self, feature):
        '''Add a feature to this visualiser'''
        self.vis_features.append(feature)
        feature.button(self.tk_featureFrame).grid(row=len(self.vis_features),
                                                  column=0, sticky=W+E)
        feature.visualiser = self

    def run(self):
        '''Start the visualiser'''
        self.redraw()
        self.tk_root.mainloop()

    ### Private funcitions ###

    def resetSliders(self):
        '''
        Recalculate the upper bound on the frame and frameStep
        sliders.
        '''
        maxFrame = self.getMaxFrameNumber()
        self.tk_frame.config(to=maxFrame)
        self.tk_frameStep.config(to=maxFrame)

    def jumpTo(self, frame):
        '''
        Jump to a given frame. If frame is a function, jump to the
        return value of frame().
        '''
        oldFrame = self.vis_frame
        if hasattr(frame, '__call__'):
            self.vis_frame = frame()
        else:
            self.vis_frame = frame

        maxFrame = self.getMaxFrameNumber()

        if self.vis_frame < 0:
            self.vis_frame = 0
        elif self.vis_frame > maxFrame:
            self.vis_frame = maxFrame
            self.vis_paused = True
            self.tk_pause.config(text='Resume')

        self.tk_frame.set(self.vis_frame)
        self.redraw(oldFrame != self.vis_frame)

    def redraw(self, update=False):
        self.resetSliders()
        for feature in [ f for f in self.vis_features if not f.dynamic ]:
            feature.draw(self.vtk_renderer)
        if update:
            for feature in [ f for f in self.vis_features if f.dynamic]:
                f.redraw(self.vtk_renderer)
        self.tk_renderWidget.GetRenderWindow().Render()
        self.tk_root.update_idletasks()

    ### Gui events ###

    def destroyed(self, event):
        if event.widget == self.tk_root:
            self.shutdown()

    def shutdown(self):
        self.tk_root.withdraw()
        self.tk_root.destroy()

    def animate(self):
        if not self.vis_paused:
            self.jumpTo(self.vis_frame + self.vis_frameStep)
            if self.vis_recording and self.vis_recordPattern is not None:
                self.save_image()
            self.tk_root.after(100, self.animate)

    def save_image(self):
        extmap = {'.jpg' : vtkJPEGWriter,
                  '.jpeg' : vtkJPEGWriter,
                  '.png' : vtkPNGWriter,
                  '.pnm' : vtkPNMWriter}
        _, ext = splitext(self.vis_recordPattern)
        try: writer = extmap[ext.lower()]()
        except KeyError:
            print('ERROR: Can\'t handle %s extension. Recording disabled.' % ext)
            self.vis_recordPattern = None
            return

        win = self.vtk_renderer.GetRenderWindow()
        w2i = vtkWindowToImageFilter()
        w2i.SetInput(win)
        w2i.Update()
        writer.SetInput(w2i.GetOutput())
        writer.SetFileName(self.vis_recordPattern % self.vis_frame)
        win.Render()
        writer.Write()

    ### Things subclasses need to override ###

    def setupGrid(self):
        '''
        Populate the vtkCellArray instance at
        self.vtk_cells. Subclasses are required to override this
        function to read from their source as appropriate.
        '''
        raise NotImplementedError('Subclass needs to override Visualiser::setupGrid!')

    def getMaxFrameNumber(self):
        '''
        Return the maximum frame number. This will need to be defined
        by a subclass.
        '''
        raise NotImplementedError('Subclass needs to override Visualiser::getMaxFrameNumber!')

    def getQuantityPoints(self, quantityName, dynamic=True, frameNumber=0):
        '''
        Return the points of a quantity at a given frame as a list
        [float]. Subclasses need to override this.
        '''
        raise NotImplementedError('Subclass needs to override Visualiser::getQuantityPoints!')

    def getQuantityDict(self):
        '''
        Return the values of all quantities at a given time as a
        dictionary. Sublclasses need to override this.
        '''
        raise NotImplementedError('Subclass needs to override Visualiser::getQuantityDict!')
class AdjustFrame(Toplevel):
    def __init__(self, master=None):
        Toplevel.__init__(self, master=master)

        self.brightness_value = 0
        self.previous_brightness_value = 0

        self.original_image = self.master.processed_image
        self.processing_image = self.master.processed_image

        self.brightness_label = Label(self, text="Brightness")
        self.brightness_scale = Scale(self,
                                      from_=0,
                                      to_=2,
                                      length=250,
                                      resolution=0.1,
                                      orient=HORIZONTAL)

        self.r_label = Label(self, text="R")
        self.r_scale = Scale(self,
                             from_=-100,
                             to_=100,
                             length=250,
                             resolution=1,
                             orient=HORIZONTAL)

        self.g_label = Label(self, text="G")
        self.g_scale = Scale(self,
                             from_=-100,
                             to_=100,
                             length=250,
                             resolution=1,
                             orient=HORIZONTAL)

        self.b_label = Label(self, text="B")
        self.b_scale = Scale(self,
                             from_=-100,
                             to_=100,
                             length=250,
                             resolution=1,
                             orient=HORIZONTAL)

        self.apply_button = Button(self, text="Apply")
        self.preview_button = Button(self, text="Preview")
        self.cancel_button = Button(self, text="Cancel")

        self.brightness_scale.set(1)

        self.apply_button.bind("<ButtonRelease>", self.apply_button_released)
        self.preview_button.bind("<ButtonRelease>", self.show_button_released)
        self.cancel_button.bind("<ButtonRelease>", self.cancel_button_released)

        self.brightness_label.pack()
        self.brightness_scale.pack()
        self.r_label.pack()
        self.r_scale.pack()
        self.g_label.pack()
        self.g_scale.pack()
        self.b_label.pack()
        self.b_scale.pack()
        self.cancel_button.pack(side=RIGHT)
        self.preview_button.pack(side=RIGHT)
        self.apply_button.pack()

    def apply_button_released(self, event):
        self.master.processed_image = self.processing_image
        self.close()

    def show_button_released(self, event):
        self.processing_image = cv2.convertScaleAbs(
            self.original_image, alpha=self.brightness_scale.get())
        b, g, r = cv2.split(self.processing_image)

        for b_value in b:
            cv2.add(b_value, self.b_scale.get(), b_value)
        for g_value in g:
            cv2.add(g_value, self.g_scale.get(), g_value)
        for r_value in r:
            cv2.add(r_value, self.r_scale.get(), r_value)

        self.processing_image = cv2.merge((b, g, r))
        self.show_image(self.processing_image)

    def cancel_button_released(self, event):
        self.close()

    def show_image(self, img=None):
        self.master.image_viewer.show_image(img=img)

    def close(self):
        self.show_image()
        self.destroy()
Beispiel #33
0
class ColoredBar(tk.Frame):
    RANGE = [0, 1000]

    def __init__(self, *args):
        super().__init__(*args)

        # firmware value
        self.firmware_value = Label(
            self, text="(Pad's firmware sens)", justify="center"
        )
        self.firmware_value.pack(expand=True, fill="both")

        # current value
        self.canvas = Canvas(self, bd=1, relief="solid", width=98, height=15)
        self.canvas.pack(expand=True, fill="both")
        self.critical = 800

        # frame the slider and entry together
        frame = tk.Frame(self, highlightthickness=3, relief=tk.RIDGE, bg="black")
        frame.pack(expand=True, fill="both")

        self.slider = Scale(
            frame,
            from_=0,
            to=1000,
            orient="horizontal",
            command=self.set_critical,
            showvalue=0,
        )
        self.slider.pack(expand=True, fill="both")

        self.entry = Entry(frame, justify="center")
        self.entry.bind("<FocusOut>", self.set_critical_entry)
        self.entry.bind("<Return>", self.set_critical_entry)
        self.entry.pack(expand=True, fill="both")
        self.valid_range = self.RANGE

    def set_firmware_value(self, value):
        self.firmware_value["text"] = value

    def set_range(self, valid_range):
        """valid range for raw and cutoff"""
        self.valid_range = valid_range

    def set_critical_entry(self, *args):
        value = self.entry.get()
        try:
            value = int(value)
            value = clamp(value, *self.valid_range)
        except:
            value = self.critical
            raise
        self.set_critical(value)

    def set_critical(self, value):
        self.critical = int(value)
        # update entries text
        self.entry.delete(0, tk.END)
        self.entry.insert(0, str(value))
        self.slider.set(value)
        # debug only:
        # self.set_value(value)

    def set_value(self, value):
        """
        sets the raw value
        """
        value = float(value)
        self.canvas.delete(tk.ALL)
        width, height = self.canvas.winfo_width(), self.canvas.winfo_height()
        perc = float(value) / 1000.0
        x_right = lerp(SLIDER_WIDTH, width - SLIDER_WIDTH, perc)

        text_anchor = "w" if value < 500 else "e"

        if value < self.critical:
            fill = "yellow"
        else:
            fill = "green"

        self.canvas.create_rectangle(SLIDER_WIDTH, 5, x_right, height - 5, fill=fill)
        self.canvas.create_text(
            x_right + 5, height / 2, text=str(int(value)), anchor=text_anchor
        )
Beispiel #34
0
class GUI():
    def __init__(self):
        self.root = ThemedTk(theme="radiance")
        INIT_WIDTH, INIT_HEIGHT = self.root.winfo_screenwidth(
        ), self.root.winfo_screenheight()
        boldStyle = ttk.Style()
        boldStyle.configure("Bold.TButton", font=('Sans', '12', 'bold'))
        #icon_loc = os.path.join(os.getcwd(),ICON_NAME)
        #img = ImageTk.PhotoImage(master = self.root, file=icon_loc)
        #self.root.wm_iconbitmap(img)
        #self.root.ttk.call('wm', 'iconphoto', self.root._w, img)
        self.root.title("Form Labeller")
        self.root.maxsize(INIT_WIDTH, INIT_HEIGHT)
        self.supported_formats = SUPPORTED_FORMATS

        self.left_frame = Frame(self.root, width=BUTTON_WIDTH)
        self.top_frame1 = Frame(self.left_frame,
                                width=BUTTON_WIDTH,
                                height=int(INIT_HEIGHT / 2))
        self.top_frame = Frame(self.left_frame,
                               width=BUTTON_WIDTH,
                               height=INIT_HEIGHT - int(INIT_HEIGHT / 2))
        self.bottom_frame = Frame(self.root, width=INIT_WIDTH - BUTTON_WIDTH)

        self.load_image_directory_button = Button(self.top_frame1,
                                                  text='Open Folder',
                                                  command=self.load_directory,
                                                  width=int(BUTTON_WIDTH),
                                                  style="Bold.TButton")
        self.load_image_directory_button.grid(row=OPEN_FOLDER_ROW,
                                              columnspan=2,
                                              sticky=tk.W + tk.E)

        self.prev_img_button = Button(self.top_frame1,
                                      text='← Prev',
                                      command=self.previous_img,
                                      state=tk.DISABLED,
                                      width=int(BUTTON_WIDTH / 2),
                                      style="Bold.TButton")
        self.prev_img_button.grid(row=PREV_ROW, column=0, sticky=tk.W + tk.E)

        self.next_img_button = Button(self.top_frame1,
                                      text='Next → ',
                                      command=self.next_img,
                                      width=int(BUTTON_WIDTH / 2),
                                      style="Bold.TButton")
        self.next_img_button.grid(row=NEXT_COL, column=1, sticky=tk.W + tk.E)

        self.save_image_button = Button(self.top_frame1,
                                        text='Save ',
                                        command=self.saver,
                                        width=int(BUTTON_WIDTH),
                                        style="Bold.TButton")
        self.save_image_button.grid(row=SAVE_ROW,
                                    columnspan=2,
                                    sticky=tk.W + tk.E)

        self.delete_poly_button = Button(self.top_frame,
                                         text='Delete Selected',
                                         command=self.delete_selected,
                                         width=int(BUTTON_WIDTH),
                                         style="Bold.TButton")
        self.delete_poly_button.grid(row=DEL_SELECTED_ROW,
                                     columnspan=2,
                                     sticky=tk.W + tk.E)

        self.type_choices = TYPE_CHOICES
        self.variable = StringVar(self.top_frame)
        self.variable.set(self.type_choices[0])
        self.type_options = OptionMenu(self.top_frame,
                                       self.variable,
                                       *self.type_choices,
                                       style="Bold.TButton")
        self.type_options.config(width=int(BUTTON_WIDTH / 2))
        self.type_options.grid(row=DROP_DOWN_ROW, column=0)

        self.save_type_button = Button(self.top_frame,
                                       text='Save Type',
                                       command=self.save_type,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")
        self.save_type_button.grid(row=SAVE_TYPE_ROW,
                                   column=1,
                                   sticky=tk.W + tk.E)

        self.deselect_all_button = Button(self.top_frame,
                                          text='Deselect All',
                                          command=self.deselect_all,
                                          width=BUTTON_WIDTH,
                                          style="Bold.TButton")
        self.deselect_all_button.grid(row=DESELECT_ALL_ROW,
                                      columnspan=2,
                                      sticky=tk.W + tk.E)

        self.select_all_button = Button(self.top_frame,
                                        text='Select All',
                                        command=self.select_all,
                                        width=BUTTON_WIDTH,
                                        style="Bold.TButton")
        self.select_all_button.grid(row=SELECT_ALL_ROW,
                                    columnspan=2,
                                    sticky=tk.W + tk.E)

        self.draw_poly_button = Button(self.top_frame,
                                       text='Draw Poly',
                                       command=self.draw_poly_func,
                                       width=BUTTON_WIDTH,
                                       style="Bold.TButton")
        self.draw_poly_button.grid(row=DRAW_POLY_ROW,
                                   columnspan=2,
                                   sticky=tk.W + tk.E)

        self.draw_rect_button = Button(self.top_frame,
                                       text='Draw Rectangle',
                                       command=self.draw_rect_func,
                                       width=BUTTON_WIDTH,
                                       style="Bold.TButton")
        self.draw_rect_button.grid(row=DRAW_RECT_ROW,
                                   columnspan=2,
                                   sticky=tk.W + tk.E)

        self.delete_all_button = Button(self.top_frame,
                                        text='Delete All',
                                        command=self.delete_all,
                                        width=BUTTON_WIDTH,
                                        style="Bold.TButton")

        self.save_poly_button = Button(self.top_frame,
                                       text='Save Poly',
                                       command=self.save_drawing,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")

        self.discard_poly_button = Button(self.top_frame,
                                          text='Discard Poly',
                                          command=self.discard_drawing,
                                          width=int(BUTTON_WIDTH / 2),
                                          style="Bold.TButton")

        self.save_rect_button = Button(self.top_frame,
                                       text='Save Rect',
                                       command=self.save_drawing,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")

        self.discard_rect_button = Button(self.top_frame,
                                          text='Discard Rect',
                                          command=self.discard_drawing,
                                          width=int(BUTTON_WIDTH / 2),
                                          style="Bold.TButton")

        self.show_type_button = Button(self.top_frame,
                                       text='Show Type',
                                       command=self.show_type,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")
        self.show_type_button.grid(row=SHOW_TYPE_ROW,
                                   column=0,
                                   columnspan=1,
                                   sticky=tk.W + tk.E)

        self.hide_type_button = Button(self.top_frame,
                                       text='Hide Type',
                                       command=self.hide_type,
                                       width=int(BUTTON_WIDTH / 2),
                                       style="Bold.TButton")
        self.hide_type_button.grid(row=HIDE_TYPE_ROW,
                                   columnspan=1,
                                   column=1,
                                   sticky=tk.W + tk.E)

        self.make_tight_button = Button(self.top_frame,
                                        text='Make Tight',
                                        command=self.make_tight,
                                        width=int(BUTTON_WIDTH / 2),
                                        style="Bold.TButton")
        self.make_tight_button.grid(row=MAKE_TIGHT_ROW,
                                    columnspan=2,
                                    column=0,
                                    sticky=tk.W + tk.E)

        self.threshold_scale = Scale(self.top_frame,
                                     from_=0,
                                     to=255,
                                     orient=HORIZONTAL,
                                     width=int(BUTTON_WIDTH / 2),
                                     label="Binary Threshold")
        self.threshold_scale.set(128)
        self.threshold_scale.grid(row=THRESHOLD_ROW,
                                  columnspan=2,
                                  column=0,
                                  sticky=tk.W + tk.E)

        self.tight_save_button = Button(self.top_frame,
                                        text='Accept Tight',
                                        command=self.save_tight)

        self.tight_discard_button = Button(self.top_frame,
                                           text='Discard Tight',
                                           command=self.discard_tight)

        self.canvas = Canvas(self.bottom_frame,
                             width=INIT_WIDTH - BUTTON_WIDTH,
                             height=INIT_HEIGHT,
                             borderwidth=1)
        self.image_name = None
        #self.image_path = os.path.join('imgs','img1.jpg')
        self.image_dir = None
        self.images_in_dir = None
        self.curr_idx = None
        self.img_cnv = None
        #self.img_cnv = ImageOnCanvas(self.root,self.canvas,self.image_path)
        self.drawing_obj = None
        self.tight_box_obj = None

        self.left_frame.pack(side=tk.LEFT)
        self.top_frame1.pack(side=tk.TOP)
        self.top_frame.pack(side=tk.BOTTOM)
        self.bottom_frame.pack(side=tk.LEFT)
        self.canvas.pack()
        self.hide_buttons()
        self.load_image_directory_button.config(state="normal")

    def save_tight(self):
        self.tight_box_obj.save_tight_box()
        self.tight_save_button.grid_forget()
        self.tight_discard_button.grid_forget()
        self.make_tight_button.grid(row=MAKE_TIGHT_ROW,
                                    columnspan=2,
                                    sticky=tk.W + tk.E)
        self.show_buttons()
        self.tight_box_obj = None

    def discard_tight(self):
        self.tight_box_obj.discard_tight_box()
        self.tight_save_button.grid_forget()
        self.tight_discard_button.grid_forget()
        self.make_tight_button.grid(row=MAKE_TIGHT_ROW,
                                    columnspan=2,
                                    sticky=tk.W + tk.E)
        self.show_buttons()
        self.tight_box_obj = None

    def show_type(self):
        for poly in self.img_cnv.polygons:
            if poly.select_poly:
                poly.show_type()

    def hide_type(self):
        for poly in self.img_cnv.polygons:
            poly.unshow_type()

    def hide_buttons(self):
        self.load_image_directory_button.config(state=tk.DISABLED)
        self.save_image_button.config(state=tk.DISABLED)
        self.delete_poly_button.config(state=tk.DISABLED)
        self.save_type_button.config(state=tk.DISABLED)
        self.deselect_all_button.config(state=tk.DISABLED)
        self.select_all_button.config(state=tk.DISABLED)
        self.delete_all_button.config(state=tk.DISABLED)
        self.show_type_button.config(state=tk.DISABLED)
        self.hide_type_button.config(state=tk.DISABLED)
        self.make_tight_button.config(state=tk.DISABLED)

    def show_buttons(self):
        self.load_image_directory_button.config(state="normal")
        self.save_image_button.config(state="normal")
        self.delete_poly_button.config(state="normal")
        self.save_type_button.config(state="normal")
        self.deselect_all_button.config(state="normal")
        self.select_all_button.config(state="normal")
        self.delete_all_button.config(state="normal")
        self.show_type_button.config(state="normal")
        self.hide_type_button.config(state="normal")
        self.draw_poly_button.config(state="normal")
        self.draw_rect_button.config(state="normal")
        self.make_tight_button.config(state="normal")

    def select_all(self):
        for poly in self.img_cnv.polygons:
            poly.select_polygon()

    def deselect_all(self):
        self.hide_type()
        for poly in self.img_cnv.polygons:
            poly.deselect_poly()

    def delete_all(self):
        result = messagebox.askyesno("Confirm Delete All",
                                     "Delete All Annotations?")
        if not result:
            return
        self.select_all()
        self.delete_selected()
        #self.img_cnv.polygons_mutex.acquire()
        #for poly in self.img_cnv.polygons:
        #    poly.delete_self()
        #self.img_cnv.polygons_mutex.release()

    def save_type(self):
        selected_option = self.variable.get()
        self.img_cnv.polygons_mutex.acquire()
        for poly in self.img_cnv.polygons:
            if poly.select_poly == True:
                if selected_option == "None":
                    poly.poly_type = None
                else:
                    poly.poly_type = selected_option
                #poly.unshow_type()
                #poly.show_type()
        self.img_cnv.polygons_mutex.release()
        self.variable.set(self.type_choices[0])
        #self.deselect_all()

    def load_new_img(self):
        self.canvas.delete('all')
        self.img_cnv = None
        path = os.path.join(self.image_dir, self.image_name)
        self.img_cnv = ImageOnCanvas(self.root, self.canvas, path)
        logger("LOADED: " + self.img_cnv.image_path)

    def load_directory(self):
        while True:
            selection = filedialog.askdirectory()
            if selection == () or selection == '':
                return
            self.root.directory = selection
            self.image_dir = self.root.directory
            file_names = os.listdir(self.image_dir)
            self.images_in_dir = []
            self.curr_idx = None
            self.image_name = None
            for name in file_names:
                if name.split('.')[-1] in self.supported_formats:
                    self.images_in_dir.append(name)
            if len(self.images_in_dir) == 0:
                self.pop_up("No supported images in the selected directory")
            else:
                break
        self.show_buttons()
        self.next_img()

    def pop_up(self, text):
        top = Toplevel()
        top.title("ERROR")
        msg = Message(top, text=text)
        msg.pack()
        button = Button(top, text="Dismiss", command=top.destroy)
        button.pack()

    def next_img(self):
        if self.curr_idx == None:
            self.curr_idx = -1
        self.curr_idx = self.curr_idx + 1
        if self.curr_idx >= len(self.images_in_dir):
            self.pop_up("Done with Images in this directory")
            self.curr_idx = self.curr_idx - 1
            return
        if self.curr_idx > 0:
            self.prev_img_button.config(state="normal")
        self.image_name = self.images_in_dir[self.curr_idx]
        self.load_new_img()
        self.root.title("Form Labeller - " + self.image_name + "(" +
                        str(self.curr_idx + 1) + "/" +
                        str(len(self.images_in_dir)) + ")")

    def previous_img(self):
        if self.curr_idx == 1:
            self.curr_idx = -1
            self.prev_img_button.config(state=tk.DISABLED)
        else:
            self.curr_idx = self.curr_idx - 2
        self.next_img()

    def delete_selected(self):
        to_be_deleted = []
        for i, poly in enumerate(self.img_cnv.polygons):
            if poly.select_poly == True:
                poly.delete_self()
                to_be_deleted.append(i)
        j = 0
        for idx in to_be_deleted:
            self.img_cnv.polygons.pop(idx - j)
            self.img_cnv.bbs.pop(idx - j)
            self.img_cnv.poly_type.pop(idx - j)
            j = j + 1

    def start_gui(self):
        self.root.mainloop()

    def saver(self):
        logger("Saving: " + self.img_cnv.image_path)
        self.save_image_button.config(state=tk.DISABLED)
        self.img_cnv.save_json(self.root.directory)
        self.save_image_button.config(state="normal")

    def draw_poly_func(self):
        self.deselect_all()
        self.img_cnv.drawing_polygon = True
        self.draw_poly_button.grid_forget()
        self.save_poly_button.grid(row=DRAW_POLY_ROW,
                                   column=0,
                                   sticky=tk.W + tk.E)
        self.discard_poly_button.grid(row=DRAW_POLY_ROW,
                                      column=1,
                                      sticky=tk.W + tk.E)
        self.hide_buttons()
        self.draw_rect_button.config(state=tk.DISABLED)
        self.drawing_obj = DrawPoly(self.bottom_frame, self.canvas,
                                    self.img_cnv, RADIUS)

    def draw_rect_func(self):
        self.deselect_all()
        self.img_cnv.drawing_polygon = True
        self.draw_rect_button.grid_forget()
        self.save_rect_button.grid(row=DRAW_RECT_ROW,
                                   column=0,
                                   sticky=tk.W + tk.E)
        self.discard_rect_button.grid(row=DRAW_RECT_ROW,
                                      column=1,
                                      sticky=tk.W + tk.E)
        self.hide_buttons()
        self.draw_poly_button.config(state=tk.DISABLED)
        self.drawing_obj = DrawRect(self.bottom_frame, self.canvas,
                                    self.img_cnv, RADIUS)

    def save_drawing(self):
        self.show_buttons()
        self.img_cnv.drawing_polygon = False
        new_poly_pts = self.drawing_obj.pt_coords
        print("Trying to save polygon with pts:", str(new_poly_pts))
        for pt in self.drawing_obj.points:
            self.canvas.delete(pt)
        if self.img_cnv.scale_factor != None:
            for i in range(len(new_poly_pts)):
                for j in range(2):
                    new_poly_pts[i][
                        j] = new_poly_pts[i][j] / self.img_cnv.scale_factor
        self.img_cnv.add_poly(new_poly_pts)
        #self.img_cnv.bbs.append(new_poly_pts)
        #self.img_cnv.draw_bbs([self.img_cnv.bbs[-1]])
        #debug (1, str(type(self.drawing_obj)))
        if isinstance(self.drawing_obj, DrawRect):
            self.save_rect_button.grid_forget()
            self.discard_rect_button.grid_forget()
            self.draw_rect_button.grid(row=DRAW_RECT_ROW,
                                       columnspan=2,
                                       sticky=tk.W + tk.E)
        elif isinstance(self.drawing_obj, DrawPoly):
            self.save_poly_button.grid_forget()
            self.discard_poly_button.grid_forget()
            self.draw_poly_button.grid(row=DRAW_POLY_ROW,
                                       columnspan=2,
                                       sticky=tk.W + tk.E)
        self.drawing_obj.delete_self()
        self.drawing_obj = None

    def discard_drawing(self):
        self.show_buttons()
        self.img_cnv.drawing_polygon = False
        #for pt in self.drawing_obj.points:
        #    self.canvas.delete(pt)
        self.drawing_obj.delete_self()
        if isinstance(self.drawing_obj, DrawRect):
            self.save_rect_button.grid_forget()
            self.discard_rect_button.grid_forget()
            self.draw_rect_button.grid(row=DRAW_RECT_ROW,
                                       columnspan=2,
                                       sticky=tk.W + tk.E)
        elif isinstance(self.drawing_obj, DrawPoly):
            self.save_poly_button.grid_forget()
            self.discard_poly_button.grid_forget()
            self.draw_poly_button.grid(row=DRAW_POLY_ROW,
                                       columnspan=2,
                                       sticky=tk.W + tk.E)
        self.drawing_obj = None

    def make_tight(self):
        self.hide_buttons()
        self.tight_box_obj = TightBox(self.root, self.img_cnv,
                                      self.threshold_scale.get())
        self.tight_box_obj.tight_box()
        self.make_tight_button.grid_forget()
        self.tight_save_button.grid(row=MAKE_TIGHT_ROW,
                                    column=0,
                                    columnspan=1,
                                    sticky=tk.W + tk.E)
        self.tight_discard_button.grid(row=MAKE_TIGHT_ROW,
                                       column=1,
                                       columnspan=1,
                                       sticky=tk.W + tk.E)
Beispiel #35
0
for t in range(len(hsv_types)):
    sliders[hsv_types[t]] = []
    for i in range(3):
        if t == 0:
            Label(window, text=hsv_labels[i],
                  font=("Arial Bold", 20)).grid(column=init_col,
                                                row=current_row + i)

        slider = Scale(window,
                       from_=0,
                       to=255,
                       orient=HORIZONTAL,
                       command=gui.update_factory(hsv_types[t], i),
                       cursor='hand2')
        slider.set(gui.params[hsv_types[t]][i])
        slider.grid(column=t + init_col + 1, row=current_row + i)
        sliders[hsv_types[t]].append(slider)
current_row += 3

# Luminosity sliders
lum_types = ["lum_lower", "lum_upper"]
Label(window, text="Luminosity", font=("Arial Bold", 20)).grid(column=init_col,
                                                               row=current_row)
for t in range(len(lum_types)):
    slider = Scale(window,
                   from_=0,
                   to=255,
                   orient=HORIZONTAL,
                   command=gui.update_factory(lum_types[t]),
                   cursor='hand2')
Beispiel #36
0
    def __init__(self, parent, data, stepname):
        super().__init__(parent, data, stepname)

        lbl1 = Label(
            self,
            text=
            'Click on each scale at the point that best indicates your experience of the task'
        )
        lbl1.grid(row=1, column=1)

        lbl2 = Label(self, text="(1=extremely low,5=extremely high)")
        lbl2.grid(row=2, column=1)
        ###########################
        lbl3 = Label(
            self,
            text=
            'Mental demand: How much mental and perceptual activity was required?'
        )
        lbl3.grid(row=3, column=1)
        mentalscale = Scale(self,
                            from_=1,
                            to=10,
                            length=200,
                            tickinterval=1,
                            orient=HORIZONTAL,
                            command=self.updatemental)
        mentalscale.set(5)
        mentalscale.grid(row=3, column=2)

        self.data[self.stepname]["mental demand weight"] = mentalscale.get()
        ###########
        lbl4 = Label(
            self,
            text='Physical demand: How much physical activity was required?')
        lbl4.grid(row=4, column=1)
        physicalscale = Scale(self,
                              from_=1,
                              to=10,
                              length=200,
                              tickinterval=1,
                              orient=HORIZONTAL,
                              command=self.updatephysical)
        physicalscale.set(5)
        physicalscale.grid(row=4, column=2)

        self.data[
            self.stepname]["physical demand weight"] = physicalscale.get()
        ###########
        ###########
        lbl5 = Label(
            self,
            text=
            'Temporal demand: How much time pressure did you feel due to the rate of pace at which the tasks or task elements occurred?'
        )
        lbl5.grid(row=5, column=1)
        temporalscale = Scale(self,
                              from_=1,
                              to=10,
                              length=200,
                              tickinterval=1,
                              orient=HORIZONTAL,
                              command=self.updatetemporal)
        temporalscale.set(5)
        temporalscale.grid(row=5, column=2)

        self.data[
            self.stepname]["temporal demand weight"] = temporalscale.get()
        ###########
        ###########
        lbl6 = Label(
            self,
            text=
            'Performance: How successful do you think you were in accomplishing the goals?'
        )
        lbl6.grid(row=6, column=1)
        perforscale = Scale(self,
                            from_=1,
                            to=10,
                            length=200,
                            tickinterval=1,
                            orient=HORIZONTAL,
                            command=self.updateperformance)
        perforscale.set(5)
        perforscale.grid(row=6, column=2)

        self.data[self.stepname]["performance weight"] = perforscale.get()
        ###########
        ###########
        lbl7 = Label(
            self,
            text=
            'Effort: How hard did you have to work (mentally and physically) to accomplish your level of performance?'
        )
        lbl7.grid(row=7, column=1)
        effortscale = Scale(self,
                            from_=1,
                            to=10,
                            length=200,
                            tickinterval=1,
                            orient=HORIZONTAL,
                            command=self.updateeffort)
        effortscale.set(5)
        effortscale.grid(row=7, column=2)

        self.data[self.stepname]["effort weight"] = effortscale.get()
        ###########
        ###########
        lbl8 = Label(
            self,
            text=
            'Frustration: How insecure, discouraged, irritated, stressed,and annoyed were you?'
        )
        lbl8.grid(row=8, column=1)
        frustrationscale = Scale(self,
                                 from_=1,
                                 to=10,
                                 length=200,
                                 tickinterval=1,
                                 orient=HORIZONTAL,
                                 command=self.updatefrustration)
        frustrationscale.set(5)
        frustrationscale.grid(row=8, column=2)

        self.data[self.stepname]["frustration weight"] = frustrationscale.get()
        ###########

        self.data[self.stepname]["choose mental times"] = 0
        self.data[self.stepname]["choose physical times"] = 0
        self.data[self.stepname]["choose temporal times"] = 0
        self.data[self.stepname]["choose performance times"] = 0
        self.data[self.stepname]["choose effort times"] = 0
        self.data[self.stepname]["choose frustration times"] = 0
    def initui(self):

        self.parent.title("Light pollution map")
        self.style = Style()
        self.style.theme_use("alt")

        self.grid(row=0, column=0)

        padding = {'padx':'5', 'pady':'5'}
        big_heading_font = ("Arial", 14, 'bold')
        small_heading_font = ("Arial", 10, 'bold')

        # Create frames.
        # There are three frames for settings - preprocessing, convolve, and contour.
        # Each also has an image frame underneath it.
        # Layout is as follows:
        #
        #             --------------------------------------------------------------------------
        #             |                 |                 |                 |                  |
        #             |                 |                 |                 |                  |
        #             |   import_body   |   process_body  |   contour_body  |   export_body    |
        #             |                 |                 |                 |                  |
        #             |                 |                 |                 |                  |
        #             --------------------------------------------------------------------------

        # Settings frames

        top = self.winfo_toplevel()
        top.rowconfigure(0, weight=1)
        top.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.columnconfigure(2, weight=1)
        self.columnconfigure(3, weight=1)

        import_body = Frame(self, relief=RAISED, borderwidth=1)
        import_body.grid(row=0, column=0, sticky=N+S+E+W)

        process_body = Frame(self, relief=RAISED, borderwidth=1)
        process_body.grid(row=0, column=1, sticky=N+S+E+W)

        contour_body = Frame(self, relief=RAISED, borderwidth=1)
        contour_body.grid(row=0, column=2, sticky=N+S+E+W)

        export_body = Frame(self, relief=RAISED, borderwidth=1)
        export_body.grid(row=0, column=3, sticky=N+S+E+W)

         # =============================================================================================================
        #
        # Contents of load_image_frame
        #
        # =============================================================================================================

        # Heading

        processing_frame_header = Label(import_body, text="Import", font=big_heading_font)
        processing_frame_header.grid(row=0, column=0, sticky=N, **padding)

        filename_variable = StringVar()

        # Import image

        import_canvas = Canvas(import_body, width=canvas_size, height=canvas_size, background='black')
        import_canvas.grid(row=1, column=0, sticky=N, **padding)

        # Load file method

        def choosefile():
            filename_variable.set(filedialog.askopenfilename(parent=import_body))
            image = Image.open(filename_variable.get())
            thumbnail = create_thumbnail(image, canvas_size)
            import_canvas.create_image(0, 0, image=thumbnail, anchor=NW)

        load_image_button = Button(import_body, text="Import image", command=choosefile)
        load_image_button.grid(row=2, column=0, columnspan=2, sticky=E+W+S, **padding)
        import_body.rowconfigure(2, weight=1)

        # =============================================================================================================
        #
        # Contents of processing_frame
        #
        # =============================================================================================================

        processing_frame_header = Label(process_body, text="Process", font=big_heading_font)
        processing_frame_header.grid(row=0, column=0, columnspan=2, sticky=N, **padding)

        clipping_variable = IntVar()

        constants_label = Label(process_body, text="Clipping",
                                font=("Arial", 10, 'bold'))
        constants_label.grid(row=1, column=0, sticky=E, **padding)

        clipping_label = Label(process_body, text="Remove pixels with \n brightness under")
        clipping_label.grid(row=2, column=0, sticky=E, **padding)

        clipping_entry = Entry(process_body, textvariable=clipping_variable, width=4)
        clipping_entry.grid(row=2, column=1, sticky=W, **padding)

        clipping_variable.set(value=default_clipping_value)

        convolve_header = Label(process_body, text="Kernel", font=small_heading_font)
        convolve_header.grid(row=4, column=0, sticky=E, **padding)

        kernel_size_variable = IntVar()

        kernel_size_label = Label(process_body, text="Convolve kernel size", justify=RIGHT)
        kernel_size_label.grid(row=5, column=0, sticky=E, **padding)

        kernel_size_entry = Entry(process_body, textvariable=kernel_size_variable, width=4)
        kernel_size_entry.grid(row=5, column=1, sticky=W, **padding)
        kernel_size_variable.set(value=default_kernel_size)

        # Constants for convolve equation

        constants_label = Label(process_body, text="Falloff",
                                font=("Arial", 10, 'bold'))
        constants_label.grid(row=6, column=0, sticky=E, **padding)

        constant_a_label = Label(process_body, text="Constant A:")
        constant_b_label = Label(process_body, text="Constant B:")
        constant_c_label = Label(process_body, text="Constant C:")

        constant_a_label.grid(row=7, column=0, sticky=E, **padding)
        constant_b_label.grid(row=8, column=0, sticky=E, **padding)
        constant_c_label.grid(row=9, column=0, sticky=E, **padding)

        constant_a_variable = DoubleVar()
        constant_b_variable = DoubleVar()
        constant_c_variable = DoubleVar()

        constant_a_entry = Entry(process_body, textvariable=constant_a_variable, width=4)
        constant_b_entry = Entry(process_body, textvariable=constant_b_variable, width=4)
        constant_c_entry = Entry(process_body, textvariable=constant_c_variable, width=4)

        constant_a_variable.set(default_constant_a)
        constant_b_variable.set(default_constant_b)
        constant_c_variable.set(default_constant_c)

        constant_a_entry.grid(row=7, column=1, **padding)
        constant_b_entry.grid(row=8, column=1, **padding)
        constant_c_entry.grid(row=9, column=1, **padding)

        constants_note = Label(process_body, text="Falloff equation is (Ax^B)-C", font=("Arial", 9))
        constants_note.grid(row=10, column=0, columnspan=2, sticky=E, **padding)

        # Start button!

        def process():
            print("Filename was " + filename_variable.get())
            image_data =  process_image(filename=filename_variable.get(),
                                        kernel_size=kernel_size_variable.get(),
                                        clipping_value=clipping_variable.get(),
                                        constant_a=constant_a_variable.get(),
                                        constant_b=constant_b_variable.get(),
                                        constant_c=constant_c_variable.get()
                                        )

            image_data = Image.open("processed_image.png")
            thumbnail = create_thumbnail(image_data, canvas_size)
            export_canvas.create_image(0, 0, image=thumbnail, anchor=NW)

        start_button = Button(process_body, text="Process image", command=process)
        start_button.grid(row=11, column=0, columnspan=3, sticky=E+W+S, **padding)
        process_body.rowconfigure(11, weight=1)

        # =============================================================================================================
        #
        # Contents of contour_frame
        #
        # =============================================================================================================

        contour_header = Label(contour_body, text="Contour", font=big_heading_font)
        contour_header.grid(row=0, column=0, sticky=S, columnspan=2, **padding)

        contour_note = Label(contour_body, text="(optional)")
        contour_note.grid(row=1, column=0, sticky=S, columnspan=2)

        scale_options = {"width":"5", "length":"150"}
        slider_padding = {"padx":"2", "pady":"0"}

        scale_list = []
        scale_values_list = []

        default_scale_values = [5, 7, 10, 20, 30, 40, 60, 100, 200]

        for i in range(9):
            scale = Scale(contour_body, from_=0, to_=255, orient=HORIZONTAL, **scale_options)
            scale.grid(row=i+2, column=0, columnspan=2, sticky=S, **slider_padding)
            scale.set(default_scale_values[i])
            scale_list.append(scale)

        for scale in scale_list:
            print(scale)
            print(type(scale))
            #print(scale.get())

        def contour():

            scale_values_list.clear()

            for scale in scale_list:
                scale_values_list.append(scale.get())

            contour_image(scale_values_list)

            image_data = Image.open("Contoured_image.png")
            thumbnail = create_thumbnail(image_data, canvas_size)
            export_canvas.create_image(0, 0, image=thumbnail, anchor=NW)

        contour_button = Button(contour_body, text="Contour image", command=contour)
        contour_button.grid(row=11, column=0, columnspan=2, sticky=E+S+W, **padding)
        contour_body.rowconfigure(11, weight=1)
        contour_body.columnconfigure(1, weight=1)

        # =============================================================================================================
        #
        # Contents of export_body
        #
        # =============================================================================================================

        filename_export_variable = StringVar()

        def export_file():
            filename_options = {}
            filename_options['filetypes'] = [('PNG', '.png')]
            filename_options['initialfile'] = 'output.png'
            filename_options['parent'] = self
            filename_export_variable.set(filedialog.asksaveasfilename(**filename_options))
            image_data = Image.open("Contoured_image.png")
            image_data.save(filename_export_variable.get())

        export_header = Label(export_body, text="Export", font=big_heading_font)
        export_header.grid(row=0, column=0, sticky=N, **padding)

        export_canvas = Canvas(export_body, width=canvas_size, height=canvas_size, background='black')
        export_canvas.grid(row=1, column=0, **padding)

        export_button = Button(export_body, text="Export image", command=export_file)
        export_button.grid(row=2, column=0, columnspan=2, sticky=E+W+S, **padding)
        export_body.rowconfigure(2, weight=1)