arthropod_describer.common package

Submodules

arthropod_describer.common.blocking_operation module

class BlockingOperation(storage: Storage, idxs: List[int], operation: Callable[[Storage, int], Any], result_handler: Callable[[Storage, int, Any], None], parent: QWidget)[source]

Bases: object

start()[source]
class ProgressReport(count: int, title_text: str, parent: Optional[QWidget] = None)[source]

Bases: object

increment()[source]

arthropod_describer.common.common module

class Info(name: str = '', description: str = '', key: str = '')[source]

Bases: object

description: str = ''
key: str = ''
classmethod load_from_dict(doc_dict: Dict[str, str]) Info[source]
classmethod load_from_doc_str(doc_str: str) Info[source]
name: str = ''

arthropod_describer.common.computations_scheduler module

class ComputationsScheduler(props_by_regions: Dict[int, List[PropertyComputation]])[source]

Bases: object

run(photo: Photo, label_name: str) List[RegionProperty][source]

arthropod_describer.common.edit_command_executor module

class EditCommandExecutor(state: State, parent: Optional[QObject] = None)[source]

Bases: QObject

Executes edit commands (CommandEntry) and handles undo/redo stacks.

change_labels(label_img: ndarray, change: LabelChange)[source]

Change the values in label_img according to change

do_command(command: CommandEntry) Optional[CommandEntry][source]
do_commands(commands: List[CommandEntry], img_name: Optional[str] = None)[source]
enforce_within_mask(photo: Photo, label_name: str)[source]
initialize(state: State)[source]
label_approval_changed = <PySide2.QtCore.Signal object>
label_image_modified = <PySide2.QtCore.Signal object>
staticMetaObject = <PySide2.QtCore.QMetaObject object>
update()[source]
update_dependencies()[source]

arthropod_describer.common.image_operation_binding module

class ImageOperation(widg_parent: Optional[QWidget], parent: Optional[QObject] = None)[source]

Bases: QObject

init(photo: Photo)[source]
operation_finished = <PySide2.QtCore.Signal object>
operation_running = <PySide2.QtCore.Signal object>
photo_resized = <PySide2.QtCore.Signal object>
photo_resolution_changed = <PySide2.QtCore.Signal object>
photo_rotated = <PySide2.QtCore.Signal object>
resize()[source]
rotate(clockwise: bool)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
class ResizeWidget(parent: ~typing.Optional[~PySide2.QtWidgets.QWidget] = None, f: ~PySide2.QtCore.Qt.WindowFlags = <PySide2.QtCore.Qt.WindowFlags object>)[source]

Bases: QWidget

invalid_input = <PySide2.QtCore.Signal object>
set_photo(photo: Photo)[source]
set_size(size: Tuple[int, int], factor: float = 1.0, max_factor: float = 1.0)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
valid_input = <PySide2.QtCore.Signal object>

arthropod_describer.common.label_change module

class CommandEntry(change_chain: ~typing.List[~arthropod_describer.common.label_change.LabelChange] = <factory>, do_type: ~arthropod_describer.common.label_change.DoType = DoType.Do, _bbox: ~typing.Optional[~typing.Tuple[int, int, int, int]] = None, update_canvas: bool = True, source: str = '', image_name: str = '', label_name: str = '', old_approval: str = '', new_approval: str = '', command_kind: ~arthropod_describer.common.label_change.CommandKind = CommandKind.LabelImgChange)[source]

Bases: object

A class representing an edit command.

change_chain: see LabelChange do_type: whether this command is either Undo or Do(Redo) _bbox: a box enclosing all modified pixels update_canvas: whether to update the view source: name of the tool/plugin that is responsible for the change. Will appear in Edit menu as e.g. ‘Undo {source}` image_name: name of the photo that was of whose label image was modified label_name: name of the label image that this command pertains to old_approval: what was the approval before this change? new_approval: what is the approval after this change? command_kind: see CommandKind

add_label_change(change: LabelChange)[source]
property bbox: Tuple[int, int, int, int]
change_chain: List[LabelChange]
command_kind: CommandKind = 0
do_type: DoType = 0
classmethod from_dict(obj: Dict[str, Any]) CommandEntry[source]
image_name: str = ''
label_name: str = ''
new_approval: str = ''
old_approval: str = ''
source: str = ''
update_canvas: bool = True
class CommandEntryJsonEncoder(*, skipkeys=False, ensure_ascii=True, check_circular=True, allow_nan=True, sort_keys=False, indent=None, separators=None, default=None)[source]

Bases: JSONEncoder

default(o: Any) Any[source]

Implement this method in a subclass such that it returns a serializable object for o, or calls the base implementation (to raise a TypeError).

For example, to support arbitrary iterators, you could implement default like this:

def default(self, o):
    try:
        iterable = iter(o)
    except TypeError:
        pass
    else:
        return list(iterable)
    # Let the base class default method raise the TypeError
    return JSONEncoder.default(self, o)
class CommandKind(value)[source]

Bases: IntEnum

An enumeration.

LabelImgChange = 0
Rot_90_CCW = -1
Rot_90_CW = 1
invert() CommandKind[source]
class DoType(value)[source]

Bases: IntEnum

An enumeration.

Do = 0
Undo = 1
class LabelChange(coords: Tuple[ndarray, ndarray], new_label: int, old_label: int, label_name: str, _change_bbox: Optional[Tuple[int, int, int, int]] = None)[source]

Bases: object

Class representing a set of pixels (coords) changing their value from old_label to new_label.

coords: the pixels that changed their value new_label: their new value old_label: their previous value label_name: which label image this change pertains to _change_bbox: a bounding box enclosing the pixels (coords)

property bbox: Tuple[int, int, int, int]
coords: Tuple[ndarray, ndarray]
classmethod from_dict(obj: Dict[str, Any]) LabelChange[source]
label_name: str
local_coords(bbox: Optional[Tuple[int, int, int, int]]) Tuple[ndarray, ndarray][source]
new_label: int
old_label: int
swap_labels() LabelChange[source]
ce_object_hook(obj: Dict[str, Any]) Union[CommandEntry, LabelChange][source]
compute_label_difference(old_label: ndarray, new_label: ndarray) ndarray[source]

Returns an image that contains values from new_label where new_label has different values from old_label, otherwise contains -1.

decode_rle(rle: List[int]) List[int][source]
encode_into_rle(arr: List[int]) List[int][source]
generate_change_command(old_lab_img: LabelImg, new_label: ndarray) Optional[CommandEntry][source]
generate_command_from_coordinates(label_img: LabelImg, coords_x: List[int], coords_y: List[int], new_label: int) CommandEntry[source]
label_difference_to_command(label_diff: ndarray, label_img: LabelImg, bbox: Optional[Tuple[int, int, int, int]] = None) CommandEntry[source]
label_difference_to_label_changes(label_diff: ndarray, label_img: LabelImg, bbox: Optional[Tuple[int, int, int, int]] = None) List[LabelChange][source]

For a label difference image and a LabelImg returns a list of LabelChange. What is a label difference image, see the function compute_label_difference.

remove_coords(cmd: CommandEntry) Tuple[CommandEntry, List[Tuple[ndarray, ndarray]]][source]
restrict_label_to_mask(label: Union[LabelImg, ndarray], mask: Union[LabelImg, ndarray]) Optional[CommandEntry][source]

Checks whether label-s non-zero entries are located entirely within mask and if not, returns a CommandEntry which, when performed on label will modify label so that it is contained inside mask. :param label: LabelImg or np.ndarray :param mask: LabelImg or np.ndarray :return: CommandEntry if label is not contained within mask else None

arthropod_describer.common.label_hierarchy module

class LabelHierarchy[source]

Bases: object

Class representing a particular hierarchy of labels.

Lorem ipsum dolor sit amet all the waaaaaaaaaaaay.

ROOT: int = -1
add_child_label(parent: int, name: str, color: Tuple[int, int, int]) Node[source]

Adds a new child label to the label parent.

add_label(label: int, name: str, color: Tuple[int, int, int] = (255, 255, 255))[source]

Adds a new label to the hierarchy.

classmethod are_valid_masks(masks: List[int], n_bits: int = 32) bool[source]

Checks whether masks represents a valid distribution of masks for n_bits-bit labels For masks to be a valid list of masks:

  1. each mask must have only one sequence of ones, e.g. 11110000 is valid, 11110011 is not valid

  2. no two distinct masks can overlap, e.g. 11110000, 00001111 is a valid distribution;

    11110000, 00111111 is not a valid mask distribution

  3. masks[i] and masks[i+1] must have their one-bit sequences adjacent, ie. 11110000 00001111 is valid

    11110000, 00000111 is not valid

  4. bit-wise union of all masks must equal to 2^n_bits - 1

code(label: int) str[source]

Returns the textual code representation of label.

compute_children()[source]

Establishes descendant relations between label nodes.

classmethod create(masks: List[int], mask_names: Optional[List[str]] = None, n_bits: int = 32) Optional[LabelHierarchy][source]

Creates a new label hierarchy with the given masks in masks, named by mask_names and with a total of n_bits bits per mask.

classmethod designate_bits(counts_of_bits: List[int], mask_names: Optional[List[str]] = None, n_bits: int = 32) Optional[LabelHierarchy][source]

Generates len(counts_of_bits) masks and designates each of them its corresponding number of bits as specified in counts_of_bits out of total number of bits as specified in n_bits. Optionally gives them names as specified in mask_names.

classmethod from_dict(label_hier_info: Dict[str, Any]) LabelHierarchy[source]
get_ancestors(label: int) List[int][source]

Returns the list of ancestor labels for label.

get_available_label(parent: int) int[source]

Returns the next available child label for parent.

get_label_mask_up_to(level: int, label: int) int[source]

Returns the bitwise AND of level_mask(level) and `label.

get_level(label: int) int[source]

Returns the level the label label belongs to in this hierarchy.

get_level_name(label_or_code: Union[int, str]) str[source]

Returns the name of the level that the label as specified by label_or_code belongs to.

Parameters

label_or_code (int or str) – either the integer representation of the label or its textual code.

Returns

name of the level the input label belongs to

Return type

str

get_mask(label: int) int[source]

Returns the mask of the level that the label belongs to.

get_parent(label_or_code: Union[int, str]) int[source]

Returns the parent label of the label represented by label_or_code.

group_by_level(labels: Union[List[int], Set[int]]) Dict[int, Set[int]][source]

Groups the labels based on their level in the hierarchy.

classmethod has_unique_sequence_of_ones(mask: int, n_bits: int = 32) bool[source]

Checks whether mask contains a single contiguous run of 1-s.

is_ancestor_of(ance: int, label: int) bool[source]

Checks whether the label ance is actually the ancestor of the label label.

is_descendant_of(desc: int, ance: int) bool[source]

Checks whether the label desc is actually a descendant of the label ance.

label(code: str) int[source]

Returns the label that is represented by code.

label_mask(label: int) int[source]

Returns the union of self.masks[0],…,self.masks[self.get_level(label)]

property level_groups: List[Set[int]]

Returns sets of labels grouped by level, so level_groups[1] is a set of labels that are on level 1 in the hierarchy.

level_mask(level: int) int[source]

Returns the union of self.masks[0],…,self.masks[level]. :param level: Number indicating the level a level mask should be returned for. :type level: int :return: The mask for the level. :rtype: int

classmethod load(path_to_json: Path) Optional[LabelHierarchy][source]
classmethod masks_are_adjacent(masks: List[int]) bool[source]

Checks whether the neighboring masks in sorted(masks) are adjacent w.r.t. to their one-bit sequences. see 3. in the docstring of are_valid_masks

classmethod masks_cover_nbits(masks: List[int], n_bits: int = 32) bool[source]

Checks whether the total number of 1-bits in all masks in masks is equal to n_bits.

classmethod masks_overlap(masks: List[int]) bool[source]

Checks whether the sorted masks in masks have nonempty bitwise intersection.

save(path_to_json: Path)[source]
set_labels(labels: List[int])[source]
to_dict() Dict[str, Any][source]
class Node[source]

Bases: object

Label representation.

to_dict() Dict[str, Any][source]

arthropod_describer.common.label_image module

class LabelImg(image_size: Tuple[int, int])[source]

Bases: object

A class representing a label image.

image_size: (int, int) in format (height, width) format

clear_region_props()[source]
clone() LabelImg[source]
classmethod create2(path: Path, image_size: Tuple[int, int], label_info: LabelImgInfo, label_name: str) LabelImg[source]

Creates new LabelImg object.

path: Path - where this label image should be stored image_size: (height, width) label_info: LabelImgInfo label_name: str - not used, stored in label_info

property filename: str
get_region_props(region_label: int) Optional[Dict[str, RegionProperty]][source]

Returns (property_key -> RegionProperty) for `region_label.

property has_unsaved_changed: bool
property is_set: bool
property label_hierarchy: LabelHierarchy
property label_image: ndarray
make_empty(size: Tuple[int, int])[source]
mask_for(label: int) ndarray[source]

Returns a binary (np.bool) image where True values mark pixels whose value is label or are descendants of label.

property path: Optional[Path]
property region_props: Dict[int, Dict[str, RegionProperty]]

Returns a dictionary of (label -> (property_key -> RegionProperty) pairs.

reload()[source]
resize(factor: float)[source]
rotate(ccw: bool)[source]
save()[source]
set_dirty()[source]
set_image(img: ndarray)[source]
set_region_prop(region_label: int, prop: RegionProperty)[source]
unload()[source]
property used_labels: Optional[Set[int]]

Returns the set of labels that are present in this label image.

class LabelImgInfo(label_name: str, is_default: bool, always_constrain_to: Optional[str] = None, allow_constrain_to: Optional[List[str]] = None)[source]

Bases: object

Info about a particular LabelImg object.

property can_be_constrained: bool
class LabelImgType(value)[source]

Bases: IntEnum

An enumeration.

Mask = 0
Regions = 1
class PropertyType(value)[source]

Bases: IntEnum

An enumeration.

Intensity = 3
IntensityHSV = 6
NDArray = 5
Other = 4
Scalar = 1
String = 0
Vector = 2
class RegionProperty[source]

Bases: object

format_value() str[source]
classmethod from_dict(dict_obj: Dict[str, Any]) RegionProperty[source]
property info: Optional[Info]

arthropod_describer.common.label_tree_model module

class LabelTreeMode(value)[source]

Bases: IntEnum

An enumeration.

Choosing = 0
ChoosingAndConstraint = 1
class LabelTreeModel(state: State, mode: LabelTreeMode = LabelTreeMode.ChoosingAndConstraint, parent: Optional[QObject] = None)[source]

Bases: QAbstractItemModel

columnCount(self, parent: PySide2.QtCore.QModelIndex = Invalid(PySide2.QtCore.QModelIndex)) int[source]
data(self, index: PySide2.QtCore.QModelIndex, role: int = PySide2.QtCore.Qt.ItemDataRole.DisplayRole) Any[source]
find_index(label: int) QModelIndex[source]
flags(self, index: PySide2.QtCore.QModelIndex) PySide2.QtCore.Qt.ItemFlags[source]
handle_label_color_changed(label: int, color: QColor)[source]
index(self, row: int, column: int, parent: PySide2.QtCore.QModelIndex = Invalid(PySide2.QtCore.QModelIndex)) PySide2.QtCore.QModelIndex[source]
parent(self) PySide2.QtCore.QObject[source]
parent(self, child: PySide2.QtCore.QModelIndex) PySide2.QtCore.QModelIndex
rowCount(self, parent: PySide2.QtCore.QModelIndex = Invalid(PySide2.QtCore.QModelIndex)) int[source]
set_constraint(label: int)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>

arthropod_describer.common.label_tree_view module

class LabelTreeView(state: State, parent: Optional[QWidget] = None)[source]

Bases: QTreeView

accept_constraint()[source]
choose_label(label: Union[int, QModelIndex])[source]
constraint_requested = <PySide2.QtCore.Signal object>
label_clicked = <PySide2.QtCore.Signal object>
label_color_change = <PySide2.QtCore.Signal object>
label_dbl_click = <PySide2.QtCore.Signal object>
leaveEvent(self, event: PySide2.QtCore.QEvent)[source]
mouseDoubleClickEvent(self, event: PySide2.QtGui.QMouseEvent)[source]
remove_unset_constraint_btn()[source]
setModel(self, model: PySide2.QtCore.QAbstractItemModel)[source]
set_constraint(index: QModelIndex)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
unset_constraint = <PySide2.QtCore.Signal object>

arthropod_describer.common.layer module

class Layer(state: State, parent: Optional[QGraphicsItem] = None)[source]

Bases: QGraphicsObject

boundingRect(self) PySide2.QtCore.QRectF[source]
hover_enter(event: QGraphicsSceneHoverEvent)[source]
hover_leave(event: QGraphicsSceneHoverEvent)[source]
hover_move(event: QGraphicsSceneHoverEvent)[source]
initialize()[source]
mouse_double_click(event: QGraphicsSceneMouseEvent)[source]
mouse_move(event: QGraphicsSceneMouseEvent)[source]
mouse_press(event: QGraphicsSceneMouseEvent)[source]
mouse_release(event: QGraphicsSceneMouseEvent)[source]
paint(self, painter: PySide2.QtGui.QPainter, option: PySide2.QtWidgets.QStyleOptionGraphicsItem, widget: Union[PySide2.QtWidgets.QWidget, NoneType] = None)[source]
reset()[source]
abstract set_photo(photo: Optional[Photo], reset_tool: bool = True)[source]
abstract set_tool(tool: Optional[Tool], reset_current: bool = True)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
class MouseEventLayer(state: State, parent: Optional[QGraphicsItem] = None)[source]

Bases: Layer

boundingRect(self) PySide2.QtCore.QRectF[source]
hoverEnterEvent(self, event: PySide2.QtWidgets.QGraphicsSceneHoverEvent)[source]
hoverLeaveEvent(self, event: PySide2.QtWidgets.QGraphicsSceneHoverEvent)[source]
hoverMoveEvent(self, event: PySide2.QtWidgets.QGraphicsSceneHoverEvent)[source]
initialize()[source]
mouseDoubleClickEvent(self, event: PySide2.QtWidgets.QGraphicsSceneMouseEvent)[source]
mouseMoveEvent(self, event: PySide2.QtWidgets.QGraphicsSceneMouseEvent)[source]
mousePressEvent(self, event: PySide2.QtWidgets.QGraphicsSceneMouseEvent)[source]
mouseReleaseEvent(self, event: PySide2.QtWidgets.QGraphicsSceneMouseEvent)[source]
set_photo(photo: Photo, reset_tool: bool = True)[source]
set_tool(tool: Tool, reset_current: bool = True)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>

arthropod_describer.common.local_photo module

class LocalPhoto(folder: Path, img_name: str, lbl_image_info: Dict[str, LabelImgInfo], subs: Subscriber)[source]

Bases: Photo

add_tag(tag: str)[source]
property approved: Dict[str, Optional[str]]
property bug_bbox: Optional[Tuple[int, int, int, int]]
has_segmentation_for(label_name: str) bool[source]
property has_unsaved_changes: bool
property image: ndarray
property image_name: str
property image_path: Path
property image_scale: Optional[Value]
property image_size: Tuple[int, int]

Should return (width, height)

property label_image_info: Dict[str, LabelImgInfo]
property label_images_: Dict[str, LabelImg]
recompute_bbox()[source]
remove_tag(tag: str)[source]
resize(factor: float)[source]
rotate(ccw: bool)[source]
save()[source]
property scale_setting: Optional[ScaleSetting]
property tags: Set[str]
property thumbnail: Optional[QImage]
toggle_tag(tag: str, enabled: bool)[source]
unload()[source]

arthropod_describer.common.local_storage module

class LocalStorage(folder: Path, lbl_images_info: Path, image_regex: Pattern = re.compile('.*\\.(png|PNG|tiff|TIFF|tif|TIF|jpg|JPG|jpeg|JPEG)$'), scale: Optional[float] = None, parent: Optional[QObject] = None)[source]

Bases: Storage

property default_label_image: str
delete_photo(img_name: str, parent: QWidget) bool[source]
get_approval(name_or_index: Union[str, int], label_name: str) str[source]
get_label_hierarchy2(label_name: str) Optional[LabelHierarchy][source]
get_photo_by_idx(idx: int, load_image: bool = True) Photo[source]
get_photo_by_name(name: str, load_image: bool = True) Photo[source]
property image_count: int
property image_names: List[str]
property image_paths: List[str]
property images: List[Photo]
include_photos(photo_names: List[str], scale: Optional[int])[source]
is_approved(index: int) bool[source]
property label_hierarchy: LabelHierarchy
property label_image_names: Set[str]
property label_img_info: Dict[str, LabelImgInfo]
classmethod load_from(folder: Path, image_regex: Pattern = re.compile('.*\\.(png|PNG|tiff|TIFF|tif|TIF|jpg|JPG|jpeg|JPEG)$')) LocalStorage[source]
classmethod load_label_image_info(path: Path) Tuple[str, Dict[str, LabelImgInfo]][source]
property location: Path
notify(img_name: str, ctx: UpdateContext, data: Optional[Dict[str, Any]] = None)[source]
photos_satisfying_tags(tags: Set[str]) List[Photo][source]
property properties: Dict[str, Dict[str, RegionProperty]]
reset_photo(photo: Photo)[source]
save() bool[source]
set_label_hierarchy2(label_name: str, lab_hier: LabelHierarchy)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
property storage_name: str
used_regions(label_name: str) Set[int][source]
property used_tags: Set[str]
class MockStorage(folder: Path, image_regex: Pattern = re.compile('.*\\.tif'))[source]

Bases: LocalStorage

classmethod load_from(folder: Path, image_regex: Pattern = re.compile('.*\\.tif')) MockStorage[source]
photo_info
staticMetaObject = <PySide2.QtCore.QMetaObject object>
delete_file(fpath: Path, parent: QWidget) bool[source]
get_image_names(folder: Path, image_regex: Pattern = re.compile('.*\\.tif')) List[str][source]
resize(img: ndarray) ndarray[source]
restructure_folder(folder: Path, image_regex: Optional[Pattern] = re.compile('.*\\.(png|PNG|tiff|TIFF|tif|TIF|jpg|JPG|jpeg|JPEG)$'), parents: bool = False, label_folders: Optional[List[str]] = None)[source]
show_imgs(imgs)[source]

arthropod_describer.common.photo module

class Photo[source]

Bases: ABC

add_tag(tag: str)[source]
property approved: Dict[str, Optional[str]]
property bug_bbox: Optional[Tuple[int, int, int, int]]
abstract has_segmentation_for(label_name: str) bool[source]
abstract property has_unsaved_changes: bool
abstract property image: ndarray
abstract property image_name: str
abstract property image_path: Path
property image_scale: Optional[Value]
abstract property image_size: Tuple[int, int]

Should return (width, height)

abstract property label_image_info: Dict[str, LabelImgInfo]
abstract property label_images_: Dict[str, LabelImg]
recompute_bbox()[source]
remove_tag(tag: str)[source]
abstract resize(factor: float)[source]
abstract rotate(ccw: bool)[source]
abstract save()[source]
property scale_setting: Optional[ScaleSetting]
property tags: Set[str]
property thumbnail: Optional[QImage]
toggle_tag(tag: str, enabled: bool)[source]
class Subscriber(parent: Optional[QObject] = None)[source]

Bases: QObject

notify(img_name: str, ctx: UpdateContext, data: Optional[Dict[str, Any]] = None)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
class UpdateContext(value)[source]

Bases: IntEnum

An enumeration.

LabelImg = 1
Measurements = 2
Photo = 0
nd2qimage(nd: ndarray) QImage[source]

arthropod_describer.common.photo_layer module

class PhotoLayer(state: State, parent: Optional[QGraphicsItem] = None)[source]

Bases: Layer

boundingRect(self) PySide2.QtCore.QRectF[source]
initialize()[source]
paint(self, painter: PySide2.QtGui.QPainter, option: PySide2.QtWidgets.QStyleOptionGraphicsItem, widget: Union[PySide2.QtWidgets.QWidget, NoneType] = None)[source]
set_photo(photo: Optional[Photo], reset_tool: bool = True)[source]
set_tool(tool: Optional[Tool], reset_current: bool = True)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>

arthropod_describer.common.plugin module

class GeneralAction(info: Optional[Info] = None)[source]

Bases: object

property group: str
property user_params: List[UserParam]
class Plugin(info: Optional[Info] = None)[source]

Bases: object

property general_actions: Optional[List[GeneralAction]]
property plugin_id: int
property property_computations: Optional[List[PropertyComputation]]
property region_computations: Optional[List[RegionComputation]]
register_computation(cls)[source]
property tools: Optional[List[Tool]]
class PropertyComputation(info: Optional[Info] = None)[source]

Bases: object

abstract property computes: Dict[str, Info]
abstract example(prop_name: str) RegionProperty[source]
property group: str
property region_restricted: bool
target_worksheet(prop_name: str) str[source]
property user_params: List[UserParam]
class RegionComputation(info: Optional[Info] = None)[source]

Bases: object

property region_restricted: bool
property user_params: List[UserParam]
global_computation_key(global_property_key: str) str[source]
local_property_key(global_property_key: str) str[source]

arthropod_describer.common.regions_cache module

class Region(label: int, mask: numpy.ndarray, image: numpy.ndarray, bbox: Tuple[int, int, int, int])[source]

Bases: object

bbox: Tuple[int, int, int, int]
image: ndarray
label: int
mask: ndarray
class RegionsCache(region_labels: Set[int], photo: Photo, label_name: str)[source]

Bases: object

arthropod_describer.common.scale_setting_widget module

class ScaleExtractionResult(photo_idx: int, image_scale: arthropod_describer.common.units.Value, reference_length: arthropod_describer.common.units.Value, px_length: arthropod_describer.common.units.Value, scale_line_p1: Tuple[int, int], scale_line_p2: Tuple[int, int], scale_marker: Union[numpy.ndarray, NoneType], scale_marker_bbox: Union[Tuple[int, int, int, int], NoneType])[source]

Bases: object

image_scale: Value
photo_idx: int
px_length: Value
reference_length: Value
scale_line_p1: Tuple[int, int]
scale_line_p2: Tuple[int, int]
scale_marker: Optional[ndarray]
scale_marker_bbox: Optional[Tuple[int, int, int, int]]
class ScaleItemDelegate(thumbnails: ThumbnailStorage_, scale_set_widget: ScaleSettingWidget, parent: Optional[QObject] = None)[source]

Bases: ThumbnailDelegate

paint(self, painter: PySide2.QtGui.QPainter, option: PySide2.QtWidgets.QStyleOptionViewItem, index: PySide2.QtCore.QModelIndex)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
class ScaleSettingTuple(old_scale_set: arthropod_describer.common.utils.ScaleSetting, new_scale_set: arthropod_describer.common.utils.ScaleSetting)[source]

Bases: object

new_scale_set: ScaleSetting
old_scale_set: ScaleSetting
class ScaleSettingWidget(state: ~arthropod_describer.common.state.State, parent: ~typing.Optional[~PySide2.QtWidgets.QWidget] = None, f: ~PySide2.QtCore.Qt.WindowFlags = <PySide2.QtCore.Qt.WindowFlags object>)[source]

Bases: QWidget

accepted = <PySide2.QtCore.Signal object>
cancelled = <PySide2.QtCore.Signal object>
closeEvent(self, event: PySide2.QtGui.QCloseEvent)[source]
compute_resolution(pixels: Optional[Value])[source]
initialize(storage: Storage)[source]
scale_set = <PySide2.QtCore.Signal object>
set_line(scale_line: ScaleLineInfo, ref_length: Value)[source]
set_line_length(length: Value)[source]
set_photo(photo: Photo)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
unset_line()[source]

arthropod_describer.common.state module

class LabelConstraint(label_name: str, parent: Optional[QObject] = None)[source]

Bases: QObject

constraint_changed = <PySide2.QtCore.Signal object>
property constraint_label_name: Optional[str]
property label: int
property label_node: Optional[Node]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
class LabelState(label_name: str)[source]

Bases: object

property label_name: str
class State(parent: Optional[QObject] = None)[source]

Bases: QObject

property active_tags_filter: List[str]
add_filtering_tag(tag: str)[source]
clear_tag_filter()[source]
property colormap: Optional[Dict[int, Tuple[int, int, int]]]
colormap_changed = <PySide2.QtCore.Signal object>
property constraint_label: int
property current_constraint: LabelConstraint
property current_label_level: int
property current_label_name: str
property current_photo: Photo
property current_photo_index: int
property hidden_photos_count: int
property label_can_be_constrained: bool
label_constraint_changed = <PySide2.QtCore.Signal object>
property label_hierarchy: LabelHierarchy
label_hierarchy_changed = <PySide2.QtCore.Signal object>
property label_img: LabelImg
label_img_changed = <PySide2.QtCore.Signal object>
new_label_constraint = <PySide2.QtCore.Signal object>
photo_changed = <PySide2.QtCore.Signal object>
photo_index_changed = <PySide2.QtCore.Signal object>
property primary_label: int
primary_label_changed = <PySide2.QtCore.Signal object>
remove_filtering_tag(tag: str)[source]
property secondary_label: int
set_label_constraint(label_name: Optional[str], emit: bool = False)[source]
set_level_constraint(label_level: int, emit: bool = False)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
property storage: Storage
storage_changed = <PySide2.QtCore.Signal object>
tags_filter_changed = <PySide2.QtCore.Signal object>
toggle_filtering_tag(tag: str, active: bool)[source]
update_used_label_list = <PySide2.QtCore.Signal object>

arthropod_describer.common.storage module

class Storage(parent: Optional[QObject] = None)[source]

Bases: Subscriber

close_storage()[source]
abstract property default_label_image: str
abstract delete_photo(img_name: str, parent: QWidget) bool[source]
get_approval(name_or_index: Union[str, int], label_name: str) str[source]
get_label_hierarchy2(label_name: str) Optional[LabelHierarchy][source]
abstract get_photo_by_idx(idx: int, load_image: bool = True) Photo[source]
abstract get_photo_by_name(name: str, load_image: bool = True) Photo[source]
abstract property image_count: int
abstract property image_names: List[str]
abstract property image_paths: List[Path]
abstract property images: List[Photo]
include_photos(photo_names: List[str], scale: Optional[int])[source]
is_approved(index: int) bool[source]
property label_hierarchy: LabelHierarchy
property label_image_names: Set[str]
abstract property label_img_info: Dict[str, LabelImgInfo]
classmethod load_from(folder: Path, image_regex: Pattern = re.compile('.*\\.tif'))[source]
abstract property location: Path
notify(img_name: str, ctx: UpdateContext, data: Optional[Dict[str, Any]] = None)[source]
photos_satisfying_tags(tags: Set[str]) List[Photo][source]
property properties: Dict[str, Dict[str, RegionProperty]]
reset_photo(photo: Photo)[source]
save() bool[source]
set_label_hierarchy2(label_name: str, lab_hier: LabelHierarchy)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
abstract property storage_name: str
storage_update = <PySide2.QtCore.Signal object>
property tag_prefixes: Set[str]
update_photo = <PySide2.QtCore.Signal object>
used_regions(label_name: str) Set[int][source]
property used_tags: Set[str]

arthropod_describer.common.tool module

class EditContext(label_img: LabelImg, label: int, image: QImage, colormap: Dict[int, Tuple[int, int, int]], label_viz: QImage, photo: Photo, label_level: int, edit_mask: ndarray, clip_region: Optional[QRegion], clip_mask: ndarray)[source]

Bases: object

class Tool(state: State, parent: Optional[QObject] = None)[source]

Bases: QObject

DEFAULT_AUTO_SCROLL_DISTANCE = 64
property active: bool
color_map_changed(cmap: Dict[int, Tuple[int, int, int]])[source]
current_value = <PySide2.QtCore.Signal object>
cursor_changed = <PySide2.QtCore.Signal object>
property cursor_image: CursorShape'>]]
get_auto_scroll_distance()[source]
left_press(painter: QPainter, pos: QPoint, context: EditContext) Tuple[Optional[CommandEntry], QRect][source]
left_release(painter: QPainter, pos: QPoint, context: EditContext) Tuple[Optional[CommandEntry], QRect][source]
middle_click(painter: QPainter, pos: QPoint, context: EditContext) Tuple[Optional[CommandEntry], QRect][source]
mouse_double_click(painter: QPainter, pos: QPoint, context: EditContext) Tuple[Optional[CommandEntry], QRect][source]
mouse_move(painter: QPainter, new_pos: QPoint, old_pos: QPoint, context: EditContext) Tuple[Optional[CommandEntry], QRect][source]
mouse_wheel(delta: int, painter: QPainter, pos: QPoint, context: EditContext) Tuple[Optional[CommandEntry], QRect][source]
reset_tool()[source]
right_press(painter: QPainter, pos: QPoint, context: EditContext) Tuple[Optional[CommandEntry], QRect][source]
right_release(painter: QPainter, pos: QPoint, context: EditContext) Tuple[Optional[CommandEntry], QRect][source]
set_out_widget(widg: Optional[QWidget]) bool[source]
set_tool_id(tool_id: int)[source]
set_user_param(param_name: str, value: Any)[source]
should_auto_scroll_with_left_button_released()[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
property tool_icon: Optional[QIcon]
abstract property tool_name: str
update_primary_label(label: int)[source]
update_secondary_label(label: int)[source]
update_viz = <PySide2.QtCore.Signal object>
property user_params: Dict[str, UserParam]
property value_storage: Optional[Any]
property viz_active: bool
property viz_commands: List[Callable[[QPainter], None]]
viz_hover_enter(pos: QPoint) List[Callable[[QPainter], None]][source]
viz_hover_leave(pos: QPoint) List[Callable[[QPainter], None]][source]
viz_hover_move(new_pos: QPoint, old_pos: QPoint) List[Callable[[QPainter], None]][source]
viz_left_press(pos: QPoint) List[Callable[[QPainter], None]][source]
viz_left_release(pos: QPoint) List[Callable[[QPainter], None]][source]
viz_mouse_double_click(pos: QPoint) List[Callable[[QPainter], None]][source]
viz_mouse_move(new_pos: QPoint, old_pos: QPoint) List[Callable[[QPainter], None]][source]
viz_mouse_wheel(delta: int, pos: QPoint) List[Callable[[QPainter], None]][source]
viz_right_press(pos: QPoint) List[Callable[[QPainter], None]][source]
viz_right_release(pos: QPoint) List[Callable[[QPainter], None]][source]
class ToolCursor(parent)[source]

Bases: QGraphicsItem

boundingRect(self) PySide2.QtCore.QRectF[source]
paint(self, painter: PySide2.QtGui.QPainter, option: PySide2.QtWidgets.QStyleOptionGraphicsItem, widget: Union[PySide2.QtWidgets.QWidget, NoneType] = None)[source]
set_cursor(curs: ~typing.Optional[~typing.Union[~PySide2.QtGui.QImage, <class 'PySide2.QtCore.Qt.CursorShape'>]])[source]
set_pos(pos: QPoint)[source]
set_shown(shown: bool = True)[source]
clip_mask_from_bool_nd(bin_img: ndarray) QBitmap[source]
fill_path_command(path: QPainterPath, pen: QPen, brush: QBrush) Callable[[QPainter], None][source]
line_command(p1: QPoint, p2: QPoint, pen: QPen) Callable[[QPainter], None][source]
qimage2ndarray(img: QImage) ndarray[source]
text_command(p: QPoint, text: str, pen: QPen) Callable[[QPainter], None][source]

arthropod_describer.common.undo_manager module

class UndoManager(state: State, parent: Optional[QObject] = None)[source]

Bases: QObject

property current_undo_redo: UndoRedo
enable_undo_redo = <PySide2.QtCore.Signal object>
get_all_undo_redo(photo_name: str) Dict[str, UndoRedo][source]
get_undo_redo(photo_name: str, label_name: str) UndoRedo[source]
initialize(storage: Storage)[source]
load()[source]
save()[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
class UndoRedo(photo_name: str, label_name: str, parent: Optional[QObject] = None)[source]

Bases: QObject

clear()[source]
clear_redo()[source]
clear_undo()[source]
enable = <PySide2.QtCore.Signal object>
get(do_type: DoType) List[List[CommandEntry]][source]
has_commands() Tuple[bool, bool][source]
pop(do_type: DoType) Optional[List[CommandEntry]][source]
push(do_type: DoType, cmds: List[CommandEntry])[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>

arthropod_describer.common.units module

class BaseUnit(value)[source]

Bases: IntEnum

An enumeration.

m = 1
none = 2
px = 0
class CompoundUnit(numerator: Set[Unit], denominator: Set[Unit])[source]

Bases: object

class SIPrefix(value)[source]

Bases: IntEnum

An enumeration.

c = -2
d = -1
m = -3
micro = -6
n = -9
none = 0
p = -12
class Unit(base_unit: BaseUnit, prefix: SIPrefix, dim: int)[source]

Bases: object

superscripts: Dict[int, str] = {2: '²', 3: '³'}
class UnitStore[source]

Bases: object

get_default_unit(unit: Union[Unit, CompoundUnit]) Union[Unit, CompoundUnit][source]
class Value(value: Any, unit: Union[Unit, CompoundUnit])[source]

Bases: object

property value: Any
convert_value(value: Value, unit: Union[Unit, CompoundUnit]) Value[source]
convertible(unit1: Union[Unit, CompoundUnit], unit2: Union[Unit, CompoundUnit]) bool[source]

arthropod_describer.common.user_params module

class ParamInstanceCollection(param: UserParam, param_widget: QWidget, state: State)[source]

Bases: object

add_instance() QWidget[source]
remove_instance(idx: int)[source]
class ParamSource(value)[source]

Bases: IntEnum

An enumeration.

Photo = 1
Storage = 2
User = 0
class ParamType(value)[source]

Bases: IntEnum

An enumeration.

BOOL = 2
INT = 0
STR = 1
classmethod from_str(type_str: Union[INT, STR, BOOL]) ParamType[source]
class ParamValueCardinality(value)[source]

Bases: IntEnum

An enumeration.

MultiValue = 1
SingleValue = 0
class UserParam(name: str = '', param_type: ParamType = ParamType.STR, default_value='', min_val: Optional[int] = 0, max_val: Optional[int] = 100, step: int = 1, key: str = '', desc: str = '', param_source: ParamSource = ParamSource.User, param_value_cardinality: ParamValueCardinality = ParamValueCardinality.SingleValue, count: int = 1, min_count: int = 1, max_count: int = 1, param_dict: Optional[Dict[str, Any]] = None, parent: Optional[QObject] = None)[source]

Bases: QObject

add_instance()[source]
converters = {ParamType.INT: <class 'int'>, ParamType.STR: <function UserParam.<lambda>>, ParamType.BOOL: <function convert_to_bool>}
classmethod create_from_dict(param_dict: Dict[str, str]) UserParam[source]
classmethod create_from_str(param_str: str) UserParam[source]
property default_instance: Optional[UserParamInstance]
classmethod load_params_from_doc_str(doc_str: str) Dict[str, UserParam][source]
param_instance_added = <PySide2.QtCore.Signal object>
param_instance_removed = <PySide2.QtCore.Signal object>
remove_instance(idx: int)[source]
set_attr(attr_name: str, value: Any)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
property value: Optional[Any]
value_changed = <PySide2.QtCore.Signal object>
class UserParamInstance(param_key: str, param_type: ParamType, idx: int, value: Any, data_is_collection: bool, min_value: int, max_value: int)[source]

Bases: QObject

converters = {ParamType.INT: <class 'int'>, ParamType.STR: <function UserParamInstance.<lambda>>, ParamType.BOOL: <function convert_to_bool>}
set_attr(attr_name: str, value: Any)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
property value: Any
value_changed = <PySide2.QtCore.Signal object>
class UserParamWidgetBinding(state: State, parent: Optional[QObject] = None)[source]

Bases: QObject

bind(params: List[UserParam], param_widget: QWidget)[source]
bind_control(param: UserParam, param_instance: UserParamInstance)[source]
bind_param_instance(param: UserParam, instance: UserParamInstance)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>
unbind_param_instance(param: UserParam, idx: int)[source]
convert_to_bool(string_or_bool) bool[source]
create_param_control(state: State, param: UserParam, param_instance: UserParamInstance) QWidget[source]
create_params_widget(params: List[UserParam], state: State) QWidget[source]
create_params_widget_with_buttons(params: List[UserParam], state: State) Union[QWidget, QDialogButtonBox, QPushButton][source]
get_instance_adder(param: UserParam)[source]
get_instance_remover(param: UserParam, idx: int)[source]
get_val_setter(param_instance: UserParamInstance)[source]
get_val_setter_combobox(binding: UserParamWidgetBinding, param_instance: UserParamInstance)[source]
get_val_setter_qlistwidget(binding: UserParamWidgetBinding, param_instance: UserParamInstance)[source]

arthropod_describer.common.utils module

class ScaleLineInfo(p1: Tuple[int, int], p2: Tuple[int, int], length: arthropod_describer.common.units.Value)[source]

Bases: object

length: Value
p1: Tuple[int, int]
p2: Tuple[int, int]
rotate(ccw: bool, origin: Tuple[int, int])[source]
scale(f: float, o: Tuple[int, int])[source]
class ScaleSetting(reference_length: Union[arthropod_describer.common.units.Value, NoneType] = None, scale: Union[arthropod_describer.common.units.Value, NoneType] = None, scale_line: Union[arthropod_describer.common.utils.ScaleLineInfo, NoneType] = None, scale_marker_bbox: Union[Tuple[int, int, int, int], NoneType] = None, scale_marker_img: Union[PySide2.QtGui.QImage, NoneType] = None)[source]

Bases: object

classmethod from_dict(obj_dict: Dict[str, Any]) ScaleSetting[source]
reference_length: Optional[Value] = None
scale: Optional[Value] = None
scale_by_factor(fac: float, o: Tuple[int, int])[source]
scale_line: Optional[ScaleLineInfo] = None
scale_marker_bbox: Optional[Tuple[int, int, int, int]] = None
scale_marker_img: Optional[QImage] = None
choose_folder(parent: QWidget, title='Open folder', path: Optional[Path] = None) Optional[Path][source]

Shows a file dialog and lets the user choose a folder.

Parameters
  • parent (QWidget) – Widget parent for the file dialog.

  • title (str) – Title for the file dialog.

  • path (pathlib.Path) – Optional path to set as the initial location of the file dialog.

Returns

Optional path if user confirmed their choice

Return type

pathlib.Path

get_dict_from_doc_str(doc_str: str) Dict[str, str][source]
get_reference_length(img: ndarray) Tuple[str, ndarray][source]
get_scale_line_ends(scale_marker: ndarray) Tuple[int, int, int, int][source]
get_scale_marker_roi(img: ndarray) Tuple[ndarray, Tuple[int, int, int, int]][source]
is_cursor_inside(widget: QWidget) bool[source]
is_valid_annotation_project(path: Path, req_folders: List[str]) bool[source]
vector_to_img(vec: Union[ndarray, List[float]], size: Tuple[int, int]) ndarray[source]
vector_to_img2(vec: Union[ndarray, List[float]], size: Tuple[int, int]) ndarray[source]

arthropod_describer.common.visualization_layer module

class VisualizationLayer(parent: Optional[QGraphicsItem] = None)[source]

Bases: Layer

boundingRect(self) PySide2.QtCore.QRectF[source]
hover_enter(event: QGraphicsSceneHoverEvent)[source]
hover_leave(event: QGraphicsSceneHoverEvent)[source]
hover_move(event: QGraphicsSceneHoverEvent)[source]
initialize()[source]
mouse_move(event: QGraphicsSceneMouseEvent)[source]
mouse_press(event: QGraphicsSceneMouseEvent)[source]
mouse_release(event: QGraphicsSceneMouseEvent)[source]
paint(self, painter: PySide2.QtGui.QPainter, option: PySide2.QtWidgets.QStyleOptionGraphicsItem, widget: Union[PySide2.QtWidgets.QWidget, NoneType] = None)[source]
put_line_segment(p1: QPoint, p2: QPoint, pen: QPen)[source]
put_qt_painter_command(cmd: Callable[[QPainter], None])[source]
put_text(p: QPoint, text: str, pen: QPen)[source]
reset()[source]
set_photo(photo: Optional[Photo], reset_tool: bool = True)[source]
set_tool(tool: Optional[Tool], reset_current: bool = True)[source]
staticMetaObject = <PySide2.QtCore.QMetaObject object>

Module contents