class InputDialog(_TkDialog): def __init__(self, message, default='', hidden=False): _TkDialog.__init__(self, message, default, hidden=hidden) def _create_selector(self, parent, default, hidden): self._entry = Entry(parent, show='*' if hidden else '') self._entry.insert(0, default) self._entry.select_range(0, END) return self._entry def _get_value(self): return self._entry.get()
class InputDialog(_TkDialog): def __init__(self, message, default=''): _TkDialog.__init__(self, message, default) def _create_selector(self, parent, default): self._entry = Entry(parent) self._entry.insert(0, default) self._entry.select_range(0, END) return self._entry def _get_value(self): return self._entry.get()
class InputDialog(_TkDialog): def __init__(self, message, default='', hidden=False): _TkDialog.__init__(self, message, default, hidden=hidden) def _create_selector(self, parent, default, hidden): self._entry = Entry(parent, show='*' if hidden else '') self._entry.insert(0, default) self._entry.select_range(0, END) return self._entry def _get_value(self): return self._entry.get()
class InputDialog(_TkDialog): def __init__(self, message, default=''): _TkDialog.__init__(self, message, default) def _create_selector(self, parent, default): self._entry = Entry(parent) self._entry.insert(0, default) self._entry.select_range(0, END) return self._entry def _get_value(self): return self._entry.get()
class _QueryPassword(_QueryString): def body(self, master): w = Label(master, text=self.prompt, justify=LEFT) w.grid(row=0, padx=5, sticky=W) self.entry = Entry(master, name="entry",show="*") self.entry.grid(row=1, padx=5, sticky=W+E) if self.initialvalue: self.entry.insert(0, self.initialvalue) self.entry.select_range(0, END) return self.entry
class _QueryPassword(_QueryString): def body(self, master): w = Label(master, text=self.prompt, justify=LEFT) w.grid(row=0, padx=5, sticky=W) self.entry = Entry(master, name="entry", show="*") self.entry.grid(row=1, padx=5, sticky=W + E) if self.initialvalue: self.entry.insert(0, self.initialvalue) self.entry.select_range(0, END) return self.entry
class ROIApp(object): def __init__(self, source_dir): self.state = "Selecting" self.image_types = ["ppm", "jpg", "jpeg", "png", "bmp"] # Add more self.source_dir = source_dir self.gt_filename = os.path.join(self.source_dir, "gt.txt") images = self.get_images() self.image_fullpaths = ( os.path.join(self.source_dir, image_filename) for image_filename in images) self.current_image_fullpath = None self.gt_file = open(self.gt_filename, 'a') self.gt_writer = csv.writer(self.gt_file, delimiter=";") self.root = Tk() self.root.bind("<Escape>", lambda e: self.quit()) self.root.bind("<KP_Enter>", self.on_kp_enter) self.root.bind("<Return>", self.on_kp_enter) self.root.wm_title("ROI Tool") self.root.protocol("WM_DELETE_WINDOW", self.quit) # Confirm? # Frame for the input field and buttons self.input_frame = Frame(self.root) self.input_frame.pack(side="top") self.label = Label(self.input_frame, text="Class:") self.label.pack(side="left") self.entry_field = Entry(self.input_frame) self.entry_field.pack(side="left") self.image_label = Label(self.root) self.image_label.pack(side="bottom") self.image_label.bind("<ButtonPress-1>", self.on_button_press) self.image_label.bind("<ButtonRelease-1>", self.on_button_release) self.image = None self.imagetk = None self.draw = None self.ref_pts = [] self.ref_start = None self.ref_pts_iter = None self.current_ref_pt = None self.gt_rows = [] try: self.next_image() except StopIteration: print("No images were found (extensions %s) " "or all the images found were already parsed, check file " "%s" % (", ".join(self.image_types), self.gt_filename)) self.quit() sys.exit(1) self.show_frame() def quit(self): self.gt_file.close() self.root.quit() def ask_for_next_category(self): """Ask for next category if another ref point exists, else move onto next image""" try: self.current_ref_pt = self.ref_pts_iter.next() self.draw.rectangle(self.current_ref_pt, outline="red") self.entry_field.select_range(0, "end") self.entry_field.focus() except StopIteration: self.state = "Selecting" try: self.next_image() except StopIteration: print( "Done, regions of interest written in %s" % self.gt_filename) self.quit() def on_kp_enter(self, event): if self.state == "Categorizing": category = self.entry_field.get() image_path = self.current_image_fullpath.split("/")[-1] data = ((image_path,) + self.current_ref_pt[0] + self.current_ref_pt[1] + (category,)) self.gt_rows.append(data) self.draw.rectangle(self.current_ref_pt, outline="blue") self.ask_for_next_category() else: self.state = "Categorizing" self.ref_pts_iter = iter(self.ref_pts) self.ref_pts = [] self.ask_for_next_category() def get_images(self): try: gt_file = open(self.gt_filename, 'r') reader = csv.reader(gt_file, delimiter=";") already_parsed = [row[0] for row in reader] except IOError: already_parsed = [] return [filename for filename in os.listdir(self.source_dir) if (filename.split(".")[-1] in self.image_types and filename not in already_parsed)] def next_image(self): self.gt_writer.writerows(self.gt_rows) self.gt_rows = [] self.current_image_fullpath = self.image_fullpaths.next() self.image = Image.open(self.current_image_fullpath) self.draw = ImageDraw.Draw(self.image) def show_frame(self): self.imagetk = ImageTk.PhotoImage(image=self.image) self.image_label.configure(image=self.imagetk) self.image_label.after(10, self.show_frame) def on_button_press(self, event): if self.state == "Selecting": self.ref_start = (event.x, event.y) def on_button_release(self, event): if self.state == "Selecting": # Make sure ROI doesn't exceed pixture coordinates and that # the corners go from top left to bottom right ref_end = (event.x, event.y) ref_pt = self.top_left_to_bottom_right(ref_end) self.ref_pts.append(ref_pt) # Draw rectangle around ROI self.draw.rectangle( self.ref_pts[-1], outline="green") def top_left_to_bottom_right(self, ref_end): """Returns the tuple: (top_left, bottom_right) where top_left and bottom_right are coordinate tuples""" x1 = max(0, min(self.ref_start[0], ref_end[0])) x2 = min(max(self.ref_start[0], ref_end[0]), self.image.size[0]) y1 = max(0, min(self.ref_start[1], ref_end[1])) y2 = min(max(self.ref_start[1], ref_end[1]), self.image.size[1]) return ((x1, y1), (x2, y2))
class StatePopup(object): def __init__(self, master, default_value, state_probs): top = self.top = Toplevel(master.canvas) self.master = master self.l = Label(top, text="New State") self.l.grid(row=0, column=0, columnspan=2) self.lb = Listbox( top ) # OptionMenu(top, Tkinter.StringVar().set(self.states[-1]), *self.states) self.lb.insert("end", "0") for i, (state, color) in enumerate(self.master.trail.colorlist.items()): str = ",".join(["{:x}".format(x) for x in state]) self.lb.insert("end", str) self.lb.itemconfig(i + 1, {"bg": color}) self.lb.grid(row=1, column=1, padx=MARGIN_LR / 2, pady=MARGIN_TB) self.lb.config(height=5, width=8) self.lb.bind( "<Double-Button-1>", lambda x: self.set_text(self.lb.get(self.lb.curselection()))) self.e = Entry(top) self.e.insert(0, default_value) self.e.bind("<Control-KeyRelease-a>", lambda x: self.select_all()) self.e.grid(row=1, column=0, sticky=N, padx=MARGIN_LR / 2, pady=MARGIN_TB) self.e.select_range(0, 'end') self.e.icursor('end') self.e.focus() self.b = Button(top, text='Ok', command=self.check_cleanup) self.top.protocol("WM_DELETE_WINDOW", self.close) self.b.grid(row=3, column=0, columnspan=2) self.l2 = Label(top, text="Probabilities") self.l2.grid(row=4, column=0, columnspan=2) for i, x in enumerate(state_probs): # if x > 0: # l = Label(top, text=hex(i)[2:] + ":" + str(x)) # l.pack() pass self.top.bind("<Return>", lambda x: self.check_cleanup()) self.top.bind("<Escape>", lambda x: self.close()) self.value = None self.top.wait_visibility() # stop interaction in other gui self.top.grab_set() def set_text(self, text): self.e.delete(0, 'end') self.e.insert(0, text) def select_all(event): event.e.select_range(0, 'end') # move cursor to the end event.e.icursor('end') return 'break' def check_cleanup(self): newstate = self.e.get() if newstate == "": self.value = range( 0, 2**(self.master.trail.statebitsize / self.master.trail.statesize)) elif newstate == "*": self.value = range( 1, 2**(self.master.trail.statebitsize / self.master.trail.statesize)) else: try: state = [] for x in newstate.split(","): x = x.strip() x = int(x, 16) assert x < 2**(self.master.trail.statebitsize / self.master.trail.statesize) state.append(x) assert len(state) > 0 self.value = state except Exception as e: print "Exception: " + str(e) self.value = None return self.close() def close(self): self.top.grab_release() self.top.destroy()