def _on_release(self, event): ''' This handles when the mouse left-button has been released, which adds a new bounding box or resizes an existing box. Parameters ---------- event : tkinter Event Event that handles the mouse being clicked, creating the first of two bounding box corners Attributes ---------- None Raises ------ None Returns ------- complete : bool Returns True for unittesting ''' if self.box_resize_mode == 'NEW': top = min(self.clicked[1], event.y) bottom = max(self.clicked[1], event.y) left = min(self.clicked[0], event.x) right = max(self.clicked[0], event.x) label = self.class_list.index(self.selected_class.get()) color = self.colorspace[label] box = InteractiveBox(self, left, top, right, bottom, color) self.canvas.delete(self.rect) del self.rect box.draw_box(len(self.annotations[self.current_file].roi)) top = self.aspect_ratio * top bottom = self.aspect_ratio * bottom left = self.aspect_ratio * left right = self.aspect_ratio * right roi = ROI() roi.push(left, top) roi.push(right, bottom) self.annotations[self.current_file].push(roi,label) self.class_count[label] = self.class_count[label] + 1 self.draw_canvas() self.saved = False self.box_resize_mode = 'NEW' return True
def test_init(self): tool = AnnotationTool() tool.load_app(True) tool.annotations = [] tool.class_list = ['winston', 'prince', 'duckie'] tool.colorspace = ['#0000FF', '#FF0000', '#00FF00'] tool.class_count = [5, 5, 5] tool.top_colors_free = ['#00FFFF', '#FF00FF', '#FFFF00'] tool.top_colors_used = ['#0000FF', '#FF0000', '#00FF00'] ibox = InteractiveBox(tool, 10, 10, 200, 200, tool.colorspace[0]) self.assertTrue(hasattr(ibox, 'root_app')) self.assertTrue(hasattr(ibox, 'left')) self.assertTrue(hasattr(ibox, 'right')) self.assertTrue(hasattr(ibox, 'top')) self.assertTrue(hasattr(ibox, 'bottom')) self.assertTrue(hasattr(ibox, 'color')) self.assertTrue(hasattr(ibox, 'close_button_size')) self.assertTrue(hasattr(ibox, 'line_width')) self.assertTrue(hasattr(ibox, 'height')) self.assertTrue(hasattr(ibox, 'width')) self.assertEqual(ibox.close_button_size, 20) self.assertEqual(ibox.line_width, 5) self.assertEqual(ibox.height, 195) self.assertEqual(ibox.width, 195)
def test_top_clicked(self): tool = AnnotationTool() tool.load_app(True) tool.colorspace = ['#0000FF', '#FF0000', '#00FF00'] ibox = InteractiveBox(tool, 10, 10, 200, 200, tool.colorspace[0]) self.assertTrue(ibox.top_clicked(8, 10)) self.assertTrue(ibox.top_clicked(202, 10)) self.assertTrue(ibox.top_clicked(100, 8)) self.assertTrue(ibox.top_clicked(100, 12)) self.assertFalse(ibox.top_clicked(7, 10)) self.assertFalse(ibox.top_clicked(203, 10)) self.assertFalse(ibox.top_clicked(100, 7)) self.assertFalse(ibox.top_clicked(100, 13))
def test_draw_box(self): tool = AnnotationTool() tool.load_app(True) # Annotation added tool.annotations = [] tool.file_list = [] tool.class_list = ['winston', 'prince', 'duckie'] tool.colorspace = ['#0000FF', '#FF0000', '#00FF00'] tool.current_file = 0 tool.class_count = [5, 5, 5] for i in range(5): a = Annotation() a.rotation = 3 tool.file_list.append('file%d.jpg' % i) for p in range(3): roi = ROI() roi.push(0, 0) roi.push(100.0, 100.0) a.push(roi, p % len(tool.class_list)) tool.annotations.append(a) tool.top_colors_free = ['#00FFFF', '#FF00FF', '#FFFF00'] tool.top_colors_used = ['#0000FF', '#FF0000', '#00FF00'] tool.img = MockImg() tool._draw_workspace() canvas_children = tool.canvas.winfo_children() ibox = InteractiveBox(tool, 10, 10, 200, 200, tool.colorspace[0]) self.assertEqual(len(canvas_children), 3) ibox.draw_box(0) canvas_children = tool.canvas.winfo_children() self.assertTrue(hasattr(ibox, 'rect')) self.assertTrue(hasattr(ibox, 'close_button')) self.assertEqual(len(canvas_children), 4)
def test_bottom_clicked(self): tool = AnnotationTool() tool.load_app(True) tool.colorspace = ['#0000FF', '#FF0000', '#00FF00'] ibox = InteractiveBox(tool, 10, 10, 200, 200, tool.colorspace[0]) self.assertTrue(ibox.bottom_clicked(202, 200)) self.assertTrue(ibox.bottom_clicked(8, 200)) self.assertTrue(ibox.bottom_clicked(100, 198)) self.assertTrue(ibox.bottom_clicked(100, 202)) self.assertFalse(ibox.bottom_clicked(100, 197)) self.assertFalse(ibox.bottom_clicked(100, 203)) self.assertFalse(ibox.bottom_clicked(7, 200)) self.assertFalse(ibox.bottom_clicked(203, 200))
def draw_canvas(self): ''' This draws the canvas in the main window. Parameters ---------- None Attributes ---------- canvas : tkinter Canvas object This is what the image is drawn on aspect_ratio : float Compute the scale factor to shrink/increase the image to fit in the canvas boxes : list A list for the OpenAnnotation InteractiveBox objects Raises ------ None Returns ------- complete : bool Returns True for unittesting ''' # Draw Canvas on Right canvas_frame = Frame(self.background, bg='green', width=self.canvas_width, height=self.canvas_height) canvas_frame.place(x=0, y=self.toolbar_height, width = self.canvas_width, height = self.canvas_height, ) self.canvas = Canvas(canvas_frame, width=self.canvas_width, height=self.canvas_height) self.canvas.place(x=0, y=0, width = self.canvas_width, height = self.canvas_height, ) if len(self.annotations): self.aspect_ratio = max(self.img.size[0]/(self.canvas_width), self.img.size[1]/(self.canvas_height)) new_size = (int(self.img.size[0]/self.aspect_ratio), int(self.img.size[1]/self.aspect_ratio)) if self.window.winfo_ismapped(): pil_img = ImageTk.PhotoImage(self.img.resize(new_size, Image.ANTIALIAS)) else: pil_img = None self.canvas.image = pil_img self.canvas.create_image(0, 0, anchor=tk.NW, image=pil_img) self.boxes = [] for i, roi in enumerate(self.annotations[self.current_file].roi): left, top, right, bottom = roi.getBox() lbl = self.annotations[self.current_file].label[i] left = left / self.aspect_ratio top = top / self.aspect_ratio right = right / self.aspect_ratio bottom = bottom / self.aspect_ratio color = self.colorspace[lbl] box = InteractiveBox(self, left, top, right, bottom, color) box.draw_box(i) self.boxes.append(box) # Only allow bounding boxes to be drawn if they can be tied to a class if len(self.class_list) and len(self.annotations): self.canvas.bind("<Button-1>",self._on_click) self.canvas.bind("<ButtonRelease-1>",self._on_release) self.canvas.bind("<B1-Motion>", self._on_move_press) return True