Module API

Annotation of Regions

A keypoint annotation tool for images

This tool allows you to annotate batches of images using keypoints. A keypoint is placed everytime you click (left-mouse button) on the image being annotated. The tool can be used to annotate single points and sequences of points making up a line or a polygon. This tool does not record the type of annotation, just the keypoints are stored. You can select during display the type of decoration to use for highlighting the annotation (line or polygon). In this sense, the connections drawn and the polygon filling are just there for semantical interpretation of hand-placed keypoints.

This tool treats any number of image inputs, one after the other. As images are loaded, annotations for the previous image are automatically saved on a text file, following a simple format (y,x) keeping the order in which they where inserted.

It is recommended you familiarize yourself with the keyboard and pointer (mouse use is recommended) bellow so you can use this tool more efficiently. A few key actions are displayed on the left of the tool canvas and provides a faster start for new users.

You can start this application in editing (default) or viewing mode. If you use it to view annotations only, you will not be able to edit the keypoints.

Keyboard shortcuts

?
opens a dialog with this help message
a | Zero | <KP_Zero>
places new point under pointer cursor, on the currently active (annotation) object
i | <Shift>-Zero | <Shift>-KP_Zero
inserts new point on a currently active object, before the current active point
d | <Del>
deletes the currently active point on the currently active object (marked in different color)
o
edits the next object
O
edits the previous object
m
toogles current object between “polygon” and “line” modes
c
creates a new (annotation) object
D
deletes current (annotation) object
X
deletes all annotated objects
n
moves to the next image
p
moves to the previous image
t
turns-on keypoint decoration (lines or polygon depending on current mode)
T
turns-off keypoint decoration
f
turns-on image filtering
F
turns-off image filtering
s
saves current annotations
q
quits the application, saving annotations for the current image
<Alt>
Temporarily shows line connections or polygon decorations (while pressed)
<Esc>
Quits the application without saving

Annotation movement

Note

Only works with the last annotated point (or the one closest to pointer)

h | Left
moves active annotation by 1 pixel to the left
l | Right
moves active annotation by 1 pixel to the right
k | Up
moves active annotation by 1 pixel up
j | Down
moves active annotation by 1 pixel down
<Shift> + motion keys
moves active annotation by 5 pixels on that direction

Pointer shortcuts

Note

Tested with a mouse. Trackpads do not normally offer these keys.

<Left>
places new annotation under the pointer cursor
<Shift>-<Left>
inserts new annotation before the current annotation
<Right>
deletes the currently active annotation
<Wheel Down>
moves to the next image
<Wheel Up>
moves to the previous image
class bob.ip.annotator.gui.AnnotatorApp(images, extension, annotations, readonly=False, zoom=1.0, marker_radius=1, pixel_skip=5, default_mode='line', *args, **kwargs)[source]

Bases: tkinter.Tk

A wrapper for the annotation application

Parameters:
  • images (str) – A base directory where I am going to search for images
  • extension (str) – The extension to use when searching for images inside the images folder
  • annotations (str) – Base directory where annotations are going to be saved
  • readonly (bool, Optional) – If set to True, then does not allow the creation of and deletion of annotations. Saving is also disabled.
  • zoom (float, Optional) – The zoom level for the image. In case it is greater than 1.0, then the image will be zoomed in (increased in size). Otherwise, it will be zoomed out (reduced in size). Annotations will be taken relatively to the original image. This setting only affects the displaying of images, the loading/saving of annotations. Annotated values are temporarily stored in memory using actual coordinate (untransformed) values.
  • marker_radius (int, Optional) – The number of pixels in the original image each annotation marker will occupy.
  • pixel_skip (int, Optional) – The number of pixels skipped every time the user uses a motion key with the Shift key pressed.
  • default_mode (str, Optional) – If the default object mode during object creation is “line” or “polygon”
reset_annotation_zoom(zoom)[source]

Resets the zoom of each annotation

save(*args, **kwargs)[source]

Action executed when we need to save the current annotations

on_quit_no_saving(*args, **kwargs)[source]

On quit we either dump the output to screen or to a file.

on_quit(*args, **kwargs)[source]

On quit we either dump the output to screen or to a file.

on_help(event=None)[source]

Creates a help dialog box with the currently enabled commands

previous_frame(event=None)[source]

Rewinds to the previous frame, wraps around if needed

next_frame(event=None)[source]

Advances to the next frame, wraps around if needed

on_pointer_motion(event)[source]

Constantly calculates where pointer is, update label that can be changed

append_point_on_active_annotation(event)[source]

Adds the given annotation position immediately

insert_point_on_active_annotation(event)[source]

Inserts the given annotation position immediately, between two other

remove_point_from_active_annotation(event)[source]

Removes the active point under the currently active annotation

remove_active_annotation(event=None)[source]

Removes all points under the currently active annotation

remove_all_annotations(event=None)[source]

Delete all current annotation and reset the view

toggle_decorations(*args)[source]

Toggles current decoration status

on_show_all(event=None)[source]

Shows all elements

on_hide_all(event=None)[source]

Hides all elements

move_active_annotation(event)[source]

Moves the last annotated keypoint using the keyboard

activate_next_annotation(event=None)[source]

Activates (for editing, possibly) the next object - wraps around

activate_previous_annotation(event=None)[source]

Activates (for editing, possibly) the previous object - wraps around

create_new_annotation(event=None)[source]

Creates a new annotation, make it active

toggle_active_annotation_mode(event=None)[source]
toggle_filter(*args)[source]

Togglers filter/no-filter on the displayed image

turn_filter_on(event=None)[source]

Turns filtering on

turn_filter_off(event=None)[source]

Turns filtering off

Re-usable Widgets

Widgets for easing the annotation of objects in the image

bob.ip.annotator.widgets.zoom_point(zoom, p)[source]

Helper to return a zoom-compensated values

The point p may represent a single point or a tuple of values.

bob.ip.annotator.widgets.unzoom_point(zoom, p)[source]

Helper to return a zoom-decompensated values

The point p may represent a single point or a tuple of values.

bob.ip.annotator.widgets.zoom_points(zoom, points)[source]

Helper that returns zoom-compensated sets of points

Points should be a list of coordinates, typically, each in (y,x) format, but not necessarily. The procedure is agnostic to this.

bob.ip.annotator.widgets.unzoom_points(zoom, points)[source]

Helper that returns zoom-decompensated sets of points

Points should be a list of coordinates, typically, each in (y,x) format, but not necessarily. The procedure is agnostic to this.

class bob.ip.annotator.widgets.Annotation(canvas, shape, points, zoom, active=False, marker_radius=1, pixel_skip=5, mode='line')[source]

Bases: object

An annotation is a collection of points where the user clicked

The points are assumed to be scaled-down or up according to the zoom of the displayed image. It is the job of the caller to apply the correct conversion ratios necessary for this operation.

An annotation can be drawn, made active and inactive on the screen. When active, the annotation is editable with keyboard shortcuts.

Parameters:
  • canvas (object) – The canvas object where I’m drawing myself in
  • shape (tuple) – The shape of the image where I’m drawing mysel of top of. To be specified as (height, width). This should correspond to the shape of the original image, not the shape of the zoomed image on the screen.
  • points (numpy.ndarray, Optional) – A numpy array (or a list of lists) in which rows represent each point annotated and columns represent annotations in (y,x) format. This should correspond to the original annotated coordinates, in integer precision. The zooming factor is applied only for displaying purposes.
  • zoom (float) – The zoom level for the image. In case it is greater than 1.0, then the image will be zoomed in (increased in size). Otherwise, it will be zoomed out (reduced in size). Annotations will be taken relatively to the original image. This setting only affects the displaying of images, the loading/saving of annotations. Annotated values are temporarily stored in memory using actual coordinate (untransformed) values.
  • active (bool, Optional) – If set to True, then makes this object look in active state.
  • marker_radius (int, Optional) – The number of pixels in the original image each annotation marker will occupy.
  • pixel_skip (int, Optional) – The number of pixels skipped every time the user uses a motion key with the Shift key pressed.
  • mode (str, Optional) – If the default object mode is “line” or “polygon”
activate(p=None)[source]

Makes the current widgets look “active”

If a point p is passed in format (y,x), then it is used to search fora point and highlight that one. Otherwise, highligths the last annotated point.

deactivate()[source]

Makes the current widgets look “inactive”

append_point(p)[source]

Appends a new point (y,x) to the annotation object

insert_point(p)[source]

Inserts the given annotation immediately, between two other

The point p should be given in (y,x) format

on_pointer_motion(p)[source]

Constantly calculates where mouse is, update label that can be changed.

The point should be supplied in (y,x) format

toggle_mode()[source]

Toggles current drawing mode between known modes

This method will toggle the current mode between known operational modes (such as “line” and “polygon”). Internally, it just creates a hidden mask in case the mode is “polygon” and deletes it otherwise.

reset_zoom_factor(zoom)[source]

Resets the zoom factor and recreates all widgets

remove_active_point(p)[source]

Removes the active point closest to point p in (y,x) format

remove_all_points()[source]

Delete current frame annotations and reset the view

show_decoration()[source]

Shows extra decoration

hide_decoration()[source]

Hides extra decoration

move_active_point(p, key, state)[source]

Moves the keypoint closes to p using the keyboard

Parameters:
  • p (tuple) – point in (y, x) format
  • key – the event keysim value (arrow keys, left right movement)
  • state – the event state value (test for <SHIFT> key pressed)
class bob.ip.annotator.widgets.Tooltip(anchor_widget, text, hover_delay=1000)[source]

Bases: idlelib.tooltip.OnHoverTooltipBase

A tooltip that pops up when a mouse hovers over an anchor widget.

showcontents()[source]

content display hook for sub-classes

class bob.ip.annotator.widgets.ImageCarousel(parent, filelist, zoom=None, filter=None, *args, **kwargs)[source]

Bases: tkinter.Canvas

A sequence of images that can be displayed on a canvas

Parameters:
  • parent – (tkinter.Widget): A tkinter widget that will serve as parent to this canvas
  • filelist (list) – The input image file list
  • zoom (float, Optional) – The zoom level for the displayed image. In case it is greater than 1.0, then the image will be zoomed in (increased in size). Otherwise, it will be zoomed out (reduced in size). Annotations will be taken relatively to the original image. This setting only affects the displaying of images, the loading/saving of annotations. Annotated values are temporarily stored in memory using actual coordinate (untransformed) values.
  • filter (object, Optional) – A callable, that implements a filtering function for the image. The filtering function should accept a PIL.Image.Image as input (data type: is variable) and provide another Image as output, with the same specifications of the input image, in which the filter is applied
  • args (dict) – Extra parameters passed directly to the base tkinter.Canvas object.
  • kwargs (dict) – Extra parameters passed directly to the base tkinter.Canvas object.
reset_zoom_filter(zoom, filter)[source]

Applies a new zoom-level to the existing image

go_to_next_image()[source]

Advances internal pointer to next image on the carousel

go_to_previous_image()[source]

Rewinds internal pointer to previous image on the carousel

relative_pointer_position()[source]

Returns the (y,x) current pointer position with respect to this canvas

pointer_is_outside_image()[source]

Tells if an event is within this canvas window

current_filename()[source]

Returns the current filename being displayed

current_index()[source]

Returns the current index in the filelist being diplayed

current_shape()[source]

Returns the current shape in the format (y,x)

original_shape()[source]

Returns the original image shape in the format (y,x)

class bob.ip.annotator.widgets.Dialog(parent, shape)[source]

Bases: tkinter.Toplevel

A pop-up window dialog - no internal objects

on_close(event=None)[source]
class bob.ip.annotator.widgets.HelpDialog(parent, shape, text)[source]

Bases: bob.ip.annotator.widgets.Dialog

A pop-up specialization for the help message

I/O Routines

A set of utilities and library functions to handle keypoint annotations.

bob.ip.annotator.io.uniq(seq, idfun=None)[source]

Order preserving uniq for lists

See: https://www.peterbe.com/plog/uniqifiers-benchmark

bob.ip.annotator.io.save(data, fp, backup=False)[source]

Saves a given data set to a file

Parameters:

data (list): A list of lists, each containing points in the format (y,x)

fp (file, str): The name of a file, with full path, to be used for recording
the data or an already opened file-like object, that accepts the “write()” call.
backup (boolean, Optional): If set, backs-up a possibly existing file path
before overriding it. Note this is not valid in case ‘fp’ above points to an opened file.
bob.ip.annotator.io.load(fp)[source]

Loads a given data set from file

Parameters:fp (str, object) – The name of a file, with full path, to be used for reading the data or an already opened file-like object, that accepts the “read()” call.
Returns:A list of lists, each containing points in the format (y,x)
Return type:list
bob.ip.annotator.io.find(basedir, name)[source]

Finds all files on basedir that match the given name

Parameters:
  • basedir (str) – Base path to search for files
  • name (str) – A string, maybe a glob, with an expression to search for
Returns:

List of paths that match the given name glob

Return type:

list