Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New database #57

Open
wants to merge 11 commits into
base: newScalingMethod
Choose a base branch
from
3 changes: 2 additions & 1 deletion taplt/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@

def main(_args):
app = QApplication(sys.argv)
_ = MainLogic() # the labeling window
dev_mode = True # Skips all dialogue windows and opens an example project
_ = MainLogic(dev_mode) # the labeling window
sys.exit(app.exec())


Expand Down
16 changes: 10 additions & 6 deletions taplt/macros/macros.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ class Macros(QObject):
def __init__(self):
super(Macros, self).__init__()

def example_project(self):
def example_project(self, dev_mode=False):
"""lets the user choose a directory containing some images and creates a project with them"""
dlg = ExampleProjectDialog()
dlg.exec()
if dlg.accepted:
if not dev_mode:
dlg.exec()
else:
dlg.accept()
if dlg.accepted or dev_mode:
database_path = str(Path.home()) + "/ExampleProject/database.db"

# collect all example files and assign a patient name
Expand All @@ -27,7 +30,7 @@ def example_project(self):
files = [examples_path + file for file in files if not file.startswith(".")]
files_dict = dict()
for i in range(len(files)):
patient = "Patient {}".format(str(i))
patient = i + 10000
files_dict[files[i]] = patient

# create a project with limited functions
Expand All @@ -39,5 +42,6 @@ def example_project(self):
"Patients", "Labels"])

project_path = str(Path(database_path).parents[0])
msg = ExampleProjectMessageBox(project_path)
msg.exec()
if not dev_mode:
msg = ExampleProjectMessageBox(project_path)
msg.exec()
2 changes: 1 addition & 1 deletion taplt/media_viewing_widgets
7 changes: 5 additions & 2 deletions taplt/src/main_logic.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@


class MainLogic:
def __init__(self):
def __init__(self, dev_mode=False):

# active elements
self.main_window = LabelingMainWindow()
self.dev_mode = dev_mode
self.main_window = LabelingMainWindow(dev_mode)
self.database = SQLiteDatabase()
self.connect_events()
if self.dev_mode:
self.main_window.open_example_project_on_startup()

self.main_window.show()

Expand Down
27 changes: 23 additions & 4 deletions taplt/ui/annotation_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,25 @@ def create_shape(self):
else:
pass

def create_shape_for_slide(self, top_left: QPoint, zoom: float, offset: QPointF):
if not self.drawing:
self.drawing = True
s = self.scene() # type: QGraphicsScene
self.temp_shape = Shape(image_size=QSize(int(s.width()), int(s.height())),
shape_type=self.shapeType,
mode=Shape.ShapeMode.CREATE,
color=self.draw_new_color,
modality=self.modality,
anchor_dist=top_left,
zoom=zoom,
offset=offset)
self.add_shapes(self.temp_shape)
self.temp_shape.drawingDone.connect(self.set_drawing_to_false)
self.sToolTip.emit("Press right click to end the annotation.")
self.temp_shape.grabMouse()
else:
pass

def get_color_for_label(self, label_name: str):
r"""Get a Color based on a label_name"""
if label_name not in self.classes:
Expand Down Expand Up @@ -184,13 +203,13 @@ def set_modality(self, modality: Modality):
"""
self.modality = modality

def update_annotations(self, current_labels: List[Shape]):
def update_annotations(self, current_annotations: List[Shape]):
self.clear()

# for some reason, bugs emerge when you pass the labels as a list
for lbl in current_labels:
self.add_shapes(lbl)
self.updateShapes.emit(current_labels)
for annotation in current_annotations:
self.add_shapes(annotation)
self.updateShapes.emit(current_annotations)

@Slot(QPointF)
def pixmap_compensation(self, compensation: QPointF):
Expand Down
55 changes: 42 additions & 13 deletions taplt/ui/file_display.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
from taplt.utils.project_structure import modality, Modality


# TODO: We need to store the current top_left corner when we switch modality in the database that way we can guarantee that the annotations are loaded correctly

class CenterDisplayWidget(QWidget):
""" widget to manage the central display in the GUI
controls a QGraphicsView and a QGraphicsScene for drawing on top of a pixmap """
Expand Down Expand Up @@ -44,7 +46,7 @@ def __init__(self, *args):
self.scene.addItem(self.annotations)
self.annotations.sToolTip.connect(self.sDrawingTooltip.emit)

# self.slide_viewer.pix_move_compensated.connect(self.annotations.pixmap_compensation)
# self.slide_viewer.pix_move_compensated.connect(self.annotations.pixmap_compensation)

# QLabel displaying the patient's id/name/alias
self.patient_label = QLabel()
Expand All @@ -71,7 +73,12 @@ def __init__(self, *args):
def mousePressEvent(self, event: QMouseEvent):
if self.annotations.mode == AnnotationGroup.AnnotationMode.DRAW:
if event.button() == Qt.MouseButton.LeftButton:
self.annotations.create_shape()
if self.file_type == Modality.slide:
self.annotations.create_shape_for_slide(self.slide_viewer.anchor_point,
self.slide_viewer.cur_downsample,
QPointF(self.slide_viewer.width, self.slide_viewer.height))
else:
self.annotations.create_shape()
event.accept()

def clear(self):
Expand All @@ -85,9 +92,10 @@ def clear(self):
def get_pixmap_dimensions(self):
return [self.pixmap.pixmap().width(), self.pixmap.pixmap().height()]

def init_image(self, filepath: str, patient: str, labels: list, classes: list):
def init_image(self, filepath: str, patient: str, annotation_ids: list, classes: list, annotation_dict: dict):
"""initializes the pixmap to display the image in the center widget
return the current labels as shape objects"""
# TODO: For some reason this is triggered when saving the annotations to the database and then triggered again when loading the next file
self.set_initialized()
self.annotations.classes = classes

Expand All @@ -100,19 +108,34 @@ def init_image(self, filepath: str, patient: str, labels: list, classes: list):
pixmap = QPixmap()
self.image_size = self.slide_viewer.frameRect().size()

self.switch_to_modality(filepath)

self.pixmap.setPixmap(pixmap)

labels = [Shape(image_size=self.image_size,
label_dict=_label,
color=self.annotations.get_color_for_label(_label['label']))
for _label in labels]

self.annotations.update_annotations(labels)
if self.file_type == Modality.slide:
# print(self.slide_viewer.cur_downsample)
annotations = [Shape(image_size=self.image_size,
annotation_dict=annotation_dict[annotation_id],
annotation_id=annotation_id,
color=self.annotations.get_color_for_label(annotation_dict[annotation_id]['label']),
modality=self.file_type,
anchor_dist=QPointF(0, 0),
zoom=self.slide_viewer.cur_downsample,
offset=QPointF(self.slide_viewer.width, self.slide_viewer.height))
for annotation_id in annotation_ids]
else:
annotations = [Shape(image_size=self.image_size,
annotation_dict=annotation_dict[annotation_id],
annotation_id=annotation_id,
color=self.annotations.get_color_for_label(annotation_dict[annotation_id]['label']),
modality=self.file_type)
for annotation_id in annotation_ids]

self.annotations.update_annotations(annotations)
self.hide_button.raise_()

self.switch_to_modality(filepath)
self.patient_label.setText(patient)
return labels
return annotations

def is_empty(self):
return self.image_viewer.b_isEmpty
Expand All @@ -139,17 +162,23 @@ def switch_to_modality(self, filepath: str):
self.file_type = modality(filepath)
self.annotations.set_modality(self.file_type)

self.image_viewer.resetTransform()
self.video_player.resetTransform()
self.slide_viewer.resetTransform()

if self.file_type == Modality.image:
self.modalitySwitched.emit('image')
self.slide_viewer.allow_resize = False
self.image_viewer.setHidden(False)
self.video_player.setHidden(True)
self.slide_viewer.setHidden(True)

self.video_player.pause()

self.image_viewer.image_size = self.image_size
self.image_viewer.fitInView(rect)

elif self.file_type == Modality.video:
self.slide_viewer.allow_resize = False
self.modalitySwitched.emit('video')

self.image_viewer.setHidden(True)
Expand All @@ -162,7 +191,7 @@ def switch_to_modality(self, filepath: str):
self.video_player.play()

elif self.file_type == Modality.slide:

self.slide_viewer.allow_resize = True
self.modalitySwitched.emit('slide')

self.image_viewer.setHidden(True)
Expand Down
14 changes: 11 additions & 3 deletions taplt/ui/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ class Changes:
ANNOTATION_SHIFTED: int = 2
COMMENT: int = 3

def __init__(self):
def __init__(self, dev_mode=False):
super(LabelingMainWindow, self).__init__()
self.dev_mode = dev_mode
self.setWindowTitle("The All-Purpose Labeling Tool")
self.resize(1276, 968)
self.setTabShape(QTabWidget.TabShape.Rounded)
Expand Down Expand Up @@ -156,6 +157,13 @@ def __init__(self):
self.menubar.sCloseProject.connect(self.close_project)
self.menubar.sExampleProject.connect(self.macros.example_project)

def open_example_project_on_startup(self):
"""Automatically opens the example project when the application starts."""
# Call the method that opens the example project
self.macros.example_project(True)
self.set_welcome_screen(False)
self.menubar.enable_tools()

def set_tool_tip(self, tip: str):
# TODO: This is kind of working, but not really. You have to hover out of the display widget.
self.main_widget.setStatusTip(tip)
Expand Down Expand Up @@ -331,15 +339,15 @@ def set_welcome_screen(self, b: bool):
self.right_menu_widget.setHidden(b)
self.welcome_screen.setHidden(not b)

def update_window(self, files: list, img_idx, patient: str, classes: list, labels: list):
def update_window(self, files: list, img_idx, patient: str, classes: list, annotation_ids: list, annotation_dict: dict):
"""main updating function: all necessary information is passed to the main window"""
self.img_idx = img_idx
color_map, new_color = colormap_rgb(n=NUM_COLORS)
self.labels_list.label_list.update_with_classes(classes, color_map)
self.file_list.update_list(files, self.img_idx)
if files:
self.set_no_files_screen(False)
current_labels = self.file_display.init_image(files[self.img_idx][0], patient, labels, classes)
current_labels = self.file_display.init_image(files[self.img_idx][0], patient, annotation_ids, classes, annotation_dict)
self.polygons.update_polygons(current_labels)
else:
self.set_no_files_screen(True)
Expand Down
Loading