PyImageLabeling 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- PyImageLabeling/__init__.py +22 -0
- PyImageLabeling/config.json +289 -0
- PyImageLabeling/controller/Controller.py +25 -0
- PyImageLabeling/controller/Events.py +147 -0
- PyImageLabeling/controller/FileEvents.py +69 -0
- PyImageLabeling/controller/ImageEvents.py +32 -0
- PyImageLabeling/controller/LabelEvents.py +219 -0
- PyImageLabeling/controller/LabelingEvents.py +123 -0
- PyImageLabeling/controller/settings/ContourFillinSetting.py +93 -0
- PyImageLabeling/controller/settings/CoutourFillingApplyCancel.py +37 -0
- PyImageLabeling/controller/settings/EraserSetting.py +73 -0
- PyImageLabeling/controller/settings/LabelSetting.py +91 -0
- PyImageLabeling/controller/settings/MagicPenSetting.py +125 -0
- PyImageLabeling/controller/settings/OpacitySetting.py +66 -0
- PyImageLabeling/controller/settings/PaintBrushSetting.py +66 -0
- PyImageLabeling/icons/apply.png +0 -0
- PyImageLabeling/icons/asterisk-green.png +0 -0
- PyImageLabeling/icons/asterisk-red.png +0 -0
- PyImageLabeling/icons/back.png +0 -0
- PyImageLabeling/icons/border.png +0 -0
- PyImageLabeling/icons/cancel.png +0 -0
- PyImageLabeling/icons/cleaner.png +0 -0
- PyImageLabeling/icons/close.png +0 -0
- PyImageLabeling/icons/down.png +0 -0
- PyImageLabeling/icons/ellipse.png +0 -0
- PyImageLabeling/icons/eraser.png +0 -0
- PyImageLabeling/icons/filling.png +0 -0
- PyImageLabeling/icons/logoMAIA.png +0 -0
- PyImageLabeling/icons/magic.png +0 -0
- PyImageLabeling/icons/maia.png +0 -0
- PyImageLabeling/icons/maia1.png +0 -0
- PyImageLabeling/icons/maia3.ico +0 -0
- PyImageLabeling/icons/maia_icon.png +0 -0
- PyImageLabeling/icons/move.png +0 -0
- PyImageLabeling/icons/opacity.png +0 -0
- PyImageLabeling/icons/open_image.png +0 -0
- PyImageLabeling/icons/open_layer.png +0 -0
- PyImageLabeling/icons/paint.png +0 -0
- PyImageLabeling/icons/plus.png +0 -0
- PyImageLabeling/icons/polygon.png +0 -0
- PyImageLabeling/icons/rectangle.png +0 -0
- PyImageLabeling/icons/reset.png +0 -0
- PyImageLabeling/icons/save.png +0 -0
- PyImageLabeling/icons/setting.png +0 -0
- PyImageLabeling/icons/transparency.png:Zone.Identifier +4 -0
- PyImageLabeling/icons/up.png +0 -0
- PyImageLabeling/icons/visibility.png +0 -0
- PyImageLabeling/icons/zoom_minus.png +0 -0
- PyImageLabeling/icons/zoom_plus.png +0 -0
- PyImageLabeling/model/Core.py +795 -0
- PyImageLabeling/model/File/Files.py +166 -0
- PyImageLabeling/model/File/NextImage.py +36 -0
- PyImageLabeling/model/File/PreviousImage.py +19 -0
- PyImageLabeling/model/Image/MoveImage.py +32 -0
- PyImageLabeling/model/Image/ResetMoveZoomImage.py +16 -0
- PyImageLabeling/model/Image/ZoomMinus.py +25 -0
- PyImageLabeling/model/Image/ZoomPlus.py +16 -0
- PyImageLabeling/model/Labeling/ClearAll.py +22 -0
- PyImageLabeling/model/Labeling/ContourFilling.py +135 -0
- PyImageLabeling/model/Labeling/Ellipse.py +350 -0
- PyImageLabeling/model/Labeling/Eraser.py +131 -0
- PyImageLabeling/model/Labeling/MagicPen.py +131 -0
- PyImageLabeling/model/Labeling/PaintBrush.py +207 -0
- PyImageLabeling/model/Labeling/Polygon.py +279 -0
- PyImageLabeling/model/Labeling/Rectangle.py +248 -0
- PyImageLabeling/model/Labeling/Undo.py +12 -0
- PyImageLabeling/model/Model.py +40 -0
- PyImageLabeling/model/Utils.py +40 -0
- PyImageLabeling/old_version/label_rectangle_properties.json +6 -0
- PyImageLabeling/old_version/main.py +2073 -0
- PyImageLabeling/old_version/models/EraseSettingsDialog.py +51 -0
- PyImageLabeling/old_version/models/LabeledRectangle.py +80 -0
- PyImageLabeling/old_version/models/MagicSettingsDialog.py +119 -0
- PyImageLabeling/old_version/models/OverlayOpacityDialog.py +63 -0
- PyImageLabeling/old_version/models/PaintSettingsDialog.py +289 -0
- PyImageLabeling/old_version/models/PointItem.py +66 -0
- PyImageLabeling/old_version/models/ProcessWorker.py +52 -0
- PyImageLabeling/old_version/models/ZoomableGraphicsView.py +1214 -0
- PyImageLabeling/old_version/models/tools/ContourTool.py +279 -0
- PyImageLabeling/old_version/models/tools/EraserTool.py +290 -0
- PyImageLabeling/old_version/models/tools/MagicPenTool.py +199 -0
- PyImageLabeling/old_version/models/tools/OverlayTool.py +179 -0
- PyImageLabeling/old_version/models/tools/PaintTool.py +68 -0
- PyImageLabeling/old_version/models/tools/PolygonTool.py +786 -0
- PyImageLabeling/old_version/models/tools/RectangleTool.py +1036 -0
- PyImageLabeling/parameters.json +1 -0
- PyImageLabeling/style.css +611 -0
- PyImageLabeling/view/Builder.py +333 -0
- PyImageLabeling/view/QBackgroundItem.py +30 -0
- PyImageLabeling/view/QWidgets.py +10 -0
- PyImageLabeling/view/View.py +226 -0
- PyImageLabeling/view/ZoomableGraphicsView.py +91 -0
- PyImageLabeling/view/__init__.py +0 -0
- pyimagelabeling-1.0.0.dist-info/METADATA +55 -0
- pyimagelabeling-1.0.0.dist-info/RECORD +99 -0
- pyimagelabeling-1.0.0.dist-info/WHEEL +5 -0
- pyimagelabeling-1.0.0.dist-info/licenses/LICENCE +22 -0
- pyimagelabeling-1.0.0.dist-info/top_level.txt +2 -0
- pypi/publish_pypi.py +18 -0
|
@@ -0,0 +1,795 @@
|
|
|
1
|
+
|
|
2
|
+
from PyQt6.QtGui import QPainter, QBitmap, QImage, QPixmap, QColor, QPainter, QBrush, QPen
|
|
3
|
+
from PyQt6.QtCore import Qt, QSize
|
|
4
|
+
from PyQt6.QtWidgets import QFileDialog
|
|
5
|
+
from PyImageLabeling.view.QBackgroundItem import QBackgroundItem
|
|
6
|
+
|
|
7
|
+
from PIL import Image
|
|
8
|
+
import numpy
|
|
9
|
+
from collections import deque
|
|
10
|
+
|
|
11
|
+
from PyImageLabeling.model.Utils import Utils
|
|
12
|
+
|
|
13
|
+
import os
|
|
14
|
+
import json
|
|
15
|
+
|
|
16
|
+
KEYWORD_SAVE_LABEL = ".label."
|
|
17
|
+
|
|
18
|
+
class LabelingOverlay():
|
|
19
|
+
###
|
|
20
|
+
# A LabelingOverlay is composed of a QPixmap, a QGraphicItem, a QPainter and a previous QPixmap
|
|
21
|
+
###
|
|
22
|
+
|
|
23
|
+
def __init__(self, label, scene, width, height, from_file=None):
|
|
24
|
+
self.label = label
|
|
25
|
+
|
|
26
|
+
self.scene = scene # The associated QGraphicScene of the QGraphicsView
|
|
27
|
+
self.width = width # The width of the Labeling Overlay QPixmap
|
|
28
|
+
self.height = height # The height of the Labeling Overlay QPixmap
|
|
29
|
+
self.zvalue = 3 # The default ZValue
|
|
30
|
+
self.opacity = Utils.load_parameters()["labeling_opacity"]/100 # To normalize
|
|
31
|
+
|
|
32
|
+
#self.label_id = label_id
|
|
33
|
+
#self.name = name
|
|
34
|
+
#self.labeling_mode = labeling_mode
|
|
35
|
+
#self.color = QColor(color) # The color of labels in the Labeling Overlay
|
|
36
|
+
# Note: The color is in RGB, the alpha is set at only the end for the view part :)
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# Initialize the QPixmap
|
|
40
|
+
self.labeling_overlay_pixmap = QPixmap(QSize(self.width, self.height))
|
|
41
|
+
if from_file is None:
|
|
42
|
+
self.labeling_overlay_pixmap.fill(Qt.GlobalColor.transparent)
|
|
43
|
+
else:
|
|
44
|
+
# Load the the file in the pixmap
|
|
45
|
+
self.labeling_overlay_pixmap.load(from_file)
|
|
46
|
+
pass
|
|
47
|
+
self.labeling_overlay_item = None
|
|
48
|
+
|
|
49
|
+
# Initialize the deque for the `undo` feature
|
|
50
|
+
self.undo_deque = deque()
|
|
51
|
+
self.undo_deque.append(self.labeling_overlay_pixmap.copy())
|
|
52
|
+
|
|
53
|
+
# Initialize the associated QPainter
|
|
54
|
+
self.labeling_overlay_painter = QPainter(self.labeling_overlay_pixmap)
|
|
55
|
+
self.reset_pen()
|
|
56
|
+
|
|
57
|
+
# Initialize the previous pixmap for the `undo` feature
|
|
58
|
+
self.previous_labeling_overlay_pixmap = None
|
|
59
|
+
|
|
60
|
+
# Initialize others pixmaps and painters to change the color or opacity operations
|
|
61
|
+
self.labeling_overlay_opacity_pixmap = QPixmap(self.width, self.height)
|
|
62
|
+
self.labeling_overlay_opacity_painter = QPainter()
|
|
63
|
+
|
|
64
|
+
self.labeling_overlay_color_pixmap = QPixmap(self.width, self.height)
|
|
65
|
+
self.labeling_overlay_color_painter = QPainter()
|
|
66
|
+
|
|
67
|
+
self.is_displayed_in_scene = False
|
|
68
|
+
self.is_edited = False
|
|
69
|
+
|
|
70
|
+
def set_is_edited(self, is_edited):
|
|
71
|
+
self.is_edited = is_edited
|
|
72
|
+
|
|
73
|
+
def get_is_edited(self):
|
|
74
|
+
return self.is_edited
|
|
75
|
+
|
|
76
|
+
def update_scene(self):
|
|
77
|
+
if self.is_displayed_in_scene is False:
|
|
78
|
+
self.labeling_overlay_item = self.scene.addPixmap(self.generate_opacity_pixmap())
|
|
79
|
+
self.labeling_overlay_item.setZValue(self.zvalue)
|
|
80
|
+
self.is_displayed_in_scene = True
|
|
81
|
+
|
|
82
|
+
self.labeling_overlay_item.setVisible(self.label.get_visible())
|
|
83
|
+
|
|
84
|
+
#def change_visible(self):
|
|
85
|
+
# if self.labeling_overlay_item.isVisible() is True:
|
|
86
|
+
# self.labeling_overlay_item.setVisible(False)
|
|
87
|
+
# else:
|
|
88
|
+
# self.labeling_overlay_item.setVisible(True)
|
|
89
|
+
|
|
90
|
+
def reset(self):
|
|
91
|
+
#self.labeling_overlay_painter.end()
|
|
92
|
+
|
|
93
|
+
self.labeling_overlay_pixmap.fill(Qt.GlobalColor.transparent)
|
|
94
|
+
if self.is_displayed_in_scene is True:
|
|
95
|
+
self.labeling_overlay_item.setPixmap(self.labeling_overlay_pixmap)
|
|
96
|
+
|
|
97
|
+
first_labeling_overlay_pixmap = self.undo_deque[0].copy()
|
|
98
|
+
self.undo_deque.clear()
|
|
99
|
+
self.undo_deque.append(first_labeling_overlay_pixmap)
|
|
100
|
+
|
|
101
|
+
self.previous_labeling_overlay_pixmap = None
|
|
102
|
+
|
|
103
|
+
if self.get_is_edited() is False:
|
|
104
|
+
self.set_is_edited(True)
|
|
105
|
+
|
|
106
|
+
def remove(self):
|
|
107
|
+
if self.is_displayed_in_scene is True:
|
|
108
|
+
self.scene.removeItem(self.labeling_overlay_item)
|
|
109
|
+
self.labeling_overlay_item = None
|
|
110
|
+
|
|
111
|
+
self.labeling_overlay_painter.end()
|
|
112
|
+
|
|
113
|
+
def set_opacity(self, opacity):
|
|
114
|
+
self.opacity = opacity
|
|
115
|
+
|
|
116
|
+
# Change and update the QPixmap
|
|
117
|
+
if self.is_displayed_in_scene is True:
|
|
118
|
+
self.labeling_overlay_item.setPixmap(self.generate_opacity_pixmap())
|
|
119
|
+
|
|
120
|
+
def get_opacity(self):
|
|
121
|
+
return self.opacity
|
|
122
|
+
|
|
123
|
+
def undo(self):
|
|
124
|
+
if len(self.undo_deque) > 0:
|
|
125
|
+
self.labeling_overlay_painter.end()
|
|
126
|
+
|
|
127
|
+
self.labeling_overlay_pixmap = self.undo_deque.pop()
|
|
128
|
+
self.previous_labeling_overlay_pixmap = self.labeling_overlay_pixmap.copy()
|
|
129
|
+
|
|
130
|
+
if len(self.undo_deque) == 0:
|
|
131
|
+
self.undo_deque.append(self.labeling_overlay_pixmap.copy())
|
|
132
|
+
|
|
133
|
+
# Create a new pixmap for opacity
|
|
134
|
+
|
|
135
|
+
self.labeling_overlay_item.setPixmap(self.generate_opacity_pixmap())
|
|
136
|
+
self.labeling_overlay_painter.begin(self.labeling_overlay_pixmap)
|
|
137
|
+
self.reset_pen()
|
|
138
|
+
|
|
139
|
+
def generate_opacity_pixmap(self):
|
|
140
|
+
# Now we can fill the pixmap
|
|
141
|
+
self.labeling_overlay_opacity_pixmap.fill(Qt.GlobalColor.transparent)
|
|
142
|
+
|
|
143
|
+
# Restart the painter
|
|
144
|
+
self.labeling_overlay_opacity_painter.begin(self.labeling_overlay_opacity_pixmap)
|
|
145
|
+
self.labeling_overlay_opacity_painter.setOpacity(self.get_opacity())
|
|
146
|
+
self.labeling_overlay_opacity_painter.drawPixmap(0, 0, self.labeling_overlay_pixmap)
|
|
147
|
+
self.labeling_overlay_opacity_painter.end()
|
|
148
|
+
|
|
149
|
+
return self.labeling_overlay_opacity_pixmap
|
|
150
|
+
|
|
151
|
+
def update_color(self):
|
|
152
|
+
# We change this labeling overlay
|
|
153
|
+
if self.get_is_edited() is False:
|
|
154
|
+
self.set_is_edited(True)
|
|
155
|
+
|
|
156
|
+
# Apply Color
|
|
157
|
+
self.labeling_overlay_color_pixmap.fill(self.label.get_color())
|
|
158
|
+
self.labeling_overlay_painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
|
|
159
|
+
self.labeling_overlay_painter.drawPixmap(0, 0, self.labeling_overlay_color_pixmap)
|
|
160
|
+
self.labeling_overlay_painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceOver)
|
|
161
|
+
|
|
162
|
+
# Update
|
|
163
|
+
if self.is_displayed_in_scene is True:
|
|
164
|
+
self.labeling_overlay_item.setPixmap(self.generate_opacity_pixmap())
|
|
165
|
+
|
|
166
|
+
# Apply the color on the undo pixmaps
|
|
167
|
+
for pixmap in self.undo_deque:
|
|
168
|
+
self.labeling_overlay_color_painter.begin(pixmap)
|
|
169
|
+
self.labeling_overlay_color_painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
|
|
170
|
+
self.labeling_overlay_color_painter.drawPixmap(0, 0, self.labeling_overlay_color_pixmap)
|
|
171
|
+
self.labeling_overlay_color_painter.end()
|
|
172
|
+
|
|
173
|
+
# do not forget the previous undo pixmap :)
|
|
174
|
+
if self.previous_labeling_overlay_pixmap is not None:
|
|
175
|
+
self.labeling_overlay_color_painter.begin(self.previous_labeling_overlay_pixmap)
|
|
176
|
+
self.labeling_overlay_color_painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
|
|
177
|
+
self.labeling_overlay_color_painter.drawPixmap(0, 0, self.labeling_overlay_color_pixmap)
|
|
178
|
+
self.labeling_overlay_color_painter.end()
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
def update(self):
|
|
182
|
+
# We change this labeling overlay
|
|
183
|
+
if self.get_is_edited() is False:
|
|
184
|
+
self.set_is_edited(True)
|
|
185
|
+
|
|
186
|
+
# Change and update the QPixmap
|
|
187
|
+
self.labeling_overlay_item.setPixmap(self.generate_opacity_pixmap())
|
|
188
|
+
|
|
189
|
+
# For the `undo` feature, if we have a previous, add it in the deque
|
|
190
|
+
if self.previous_labeling_overlay_pixmap is not None:
|
|
191
|
+
self.undo_deque.append(self.previous_labeling_overlay_pixmap)
|
|
192
|
+
|
|
193
|
+
# Create a copy to keep it in the previous pixmap variable
|
|
194
|
+
self.previous_labeling_overlay_pixmap = self.labeling_overlay_pixmap.copy()
|
|
195
|
+
|
|
196
|
+
#def get_color(self):
|
|
197
|
+
# return self.color
|
|
198
|
+
|
|
199
|
+
#def set_color(self, color):
|
|
200
|
+
# self.color = color
|
|
201
|
+
|
|
202
|
+
#def get_name(self):
|
|
203
|
+
# return self.name
|
|
204
|
+
|
|
205
|
+
# def set_name(self, name):
|
|
206
|
+
# self.name = name
|
|
207
|
+
|
|
208
|
+
# def get_labeling_mode(self):
|
|
209
|
+
# return self.labeling_mode
|
|
210
|
+
|
|
211
|
+
# def set_labeling_mode(self, labeling_mode):
|
|
212
|
+
# self.labeling_mode = labeling_mode
|
|
213
|
+
|
|
214
|
+
# def get_label_id(self):
|
|
215
|
+
# return self.label_id
|
|
216
|
+
|
|
217
|
+
def get_painter(self):
|
|
218
|
+
return self.labeling_overlay_painter
|
|
219
|
+
|
|
220
|
+
def set_zvalue(self, zvalue):
|
|
221
|
+
self.zvalue = zvalue
|
|
222
|
+
print("esss:", zvalue)
|
|
223
|
+
self.labeling_overlay_item.setZValue(self.zvalue)
|
|
224
|
+
|
|
225
|
+
def reset_pen(self):
|
|
226
|
+
self.labeling_overlay_painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceOver)
|
|
227
|
+
self.labeling_overlay_painter.setPen(QPen(self.label.color, 2, Qt.PenStyle.SolidLine, Qt.PenCapStyle.RoundCap, Qt.PenJoinStyle.RoundJoin))
|
|
228
|
+
self.labeling_overlay_painter.setBrush(self.label.color)
|
|
229
|
+
|
|
230
|
+
def set_is_displayed_in_scene(self, is_displayed_in_scene):
|
|
231
|
+
self.is_displayed_in_scene = is_displayed_in_scene
|
|
232
|
+
|
|
233
|
+
def set_visible(self, is_visible):
|
|
234
|
+
if self.labeling_overlay_item is not None:
|
|
235
|
+
self.labeling_overlay_item.setVisible(is_visible)
|
|
236
|
+
|
|
237
|
+
def save(self, current_file_path, path_image):
|
|
238
|
+
name = os.path.basename(path_image)
|
|
239
|
+
name, format = name.split(".")
|
|
240
|
+
format = "png"
|
|
241
|
+
save_file = current_file_path + os.sep+name + KEYWORD_SAVE_LABEL + str(self.label.get_label_id()) + "." + format
|
|
242
|
+
self.labeling_overlay_pixmap.save(save_file, format)
|
|
243
|
+
|
|
244
|
+
def remove_save(self, current_file_path, path_image):
|
|
245
|
+
name = os.path.basename(path_image)
|
|
246
|
+
name, format = name.split(".")
|
|
247
|
+
format = "png"
|
|
248
|
+
save_file = current_file_path + os.sep+name + KEYWORD_SAVE_LABEL + str(self.label.get_label_id()) + "." + format
|
|
249
|
+
if os.path.isfile(save_file):
|
|
250
|
+
os.remove(save_file)
|
|
251
|
+
|
|
252
|
+
class ImageItem():
|
|
253
|
+
|
|
254
|
+
def __init__(self, view, controller, path_image, icon_button, labeling_overview_was_loaded, labeling_overview_file_paths):
|
|
255
|
+
self.view = view
|
|
256
|
+
self.controller = controller
|
|
257
|
+
self.path_image = path_image
|
|
258
|
+
self.icon_button = icon_button
|
|
259
|
+
self.labeling_overview_was_loaded = labeling_overview_was_loaded
|
|
260
|
+
self.labeling_overview_file_paths = labeling_overview_file_paths
|
|
261
|
+
|
|
262
|
+
self.zoomable_graphics_view = view.zoomable_graphics_view
|
|
263
|
+
|
|
264
|
+
self.image_pixmap = QPixmap(path_image) # The current pixmap of the image
|
|
265
|
+
self.image_item = None # The current pixmap item of the image in the scene
|
|
266
|
+
self.image_numpy_pixels_rgb = None # The current RGB numpy matrix of the image
|
|
267
|
+
|
|
268
|
+
self.backgroung_item = None # The QBackgroundItem behind the images
|
|
269
|
+
|
|
270
|
+
self.labeling_overlays = dict() # dict of LabelingOverlay instance
|
|
271
|
+
|
|
272
|
+
self.current_labeling_overlay = None # The current selected LabelingOverlay
|
|
273
|
+
|
|
274
|
+
self.image_qrect = self.image_pixmap.rect() # Integer size in Qrect
|
|
275
|
+
self.image_qrectf = self.image_qrect.toRectF() # Float size in QRectF
|
|
276
|
+
|
|
277
|
+
# the background item
|
|
278
|
+
self.alpha_color = Utils.load_parameters()["load"]["alpha_color"]
|
|
279
|
+
|
|
280
|
+
#save a numpy matrix of colors
|
|
281
|
+
self.image_numpy_pixels_rgb = numpy.array(Image.open(path_image).convert("RGB"))
|
|
282
|
+
|
|
283
|
+
self.is_displayed_in_scene = False
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def get_edited(self):
|
|
287
|
+
for label_id in self.labeling_overlays:
|
|
288
|
+
if self.labeling_overlays[label_id].get_is_edited() is True:
|
|
289
|
+
return True
|
|
290
|
+
return False
|
|
291
|
+
|
|
292
|
+
def get_image_pixmap(self):
|
|
293
|
+
return self.image_pixmap
|
|
294
|
+
|
|
295
|
+
def get_qrectf(self):
|
|
296
|
+
return self.image_qrectf
|
|
297
|
+
|
|
298
|
+
def get_labeling_overlays(self):
|
|
299
|
+
return list(self.labeling_overlays.values())
|
|
300
|
+
|
|
301
|
+
def update_scene(self):
|
|
302
|
+
if self.is_displayed_in_scene is False:
|
|
303
|
+
# Add the backgroung_item in the scene
|
|
304
|
+
self.backgroung_item = QBackgroundItem(self.image_qrectf, self.controller, self.alpha_color)
|
|
305
|
+
self.view.zoomable_graphics_view.scene.addItem(self.backgroung_item)
|
|
306
|
+
self.backgroung_item.setZValue(0) # Base layer
|
|
307
|
+
|
|
308
|
+
# Add the image in the scene
|
|
309
|
+
self.image_item = self.zoomable_graphics_view.scene.addPixmap(self.image_pixmap)
|
|
310
|
+
self.image_item.setZValue(1) # Image layer
|
|
311
|
+
|
|
312
|
+
# Set the Event listener in the background item to the image item
|
|
313
|
+
self.image_item.installSceneEventFilter(self.backgroung_item)
|
|
314
|
+
|
|
315
|
+
# Set the good visual parameters for the scene
|
|
316
|
+
self.zoomable_graphics_view.setSceneRect(self.image_qrectf)
|
|
317
|
+
self.zoomable_graphics_view.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
318
|
+
self.zoomable_graphics_view.centerOn(self.image_qrect.width()/2,self.image_qrect.height()/2)
|
|
319
|
+
|
|
320
|
+
self.initialyse_zoom_factor()
|
|
321
|
+
self.is_displayed_in_scene = True
|
|
322
|
+
# for label_id in self.labeling_overlays:
|
|
323
|
+
# self.labeling_overlays[label_id].update_scene()
|
|
324
|
+
|
|
325
|
+
# # Apply the label's visibility state using existing change_visible logic
|
|
326
|
+
# if label_id in self.controller.model.get_label_items():
|
|
327
|
+
# label_item = self.controller.model.get_label_items()[label_id]
|
|
328
|
+
# overlay = self.labeling_overlays[label_id]
|
|
329
|
+
|
|
330
|
+
# # Only change if current visibility doesn't match desired state
|
|
331
|
+
# if overlay.labeling_overlay_item.isVisible() != label_item.get_visible():
|
|
332
|
+
# overlay.change_visible()
|
|
333
|
+
|
|
334
|
+
# Update the labeling overlays
|
|
335
|
+
for label_id in self.labeling_overlays:
|
|
336
|
+
self.labeling_overlays[label_id].update_scene()
|
|
337
|
+
|
|
338
|
+
print("update scene")
|
|
339
|
+
|
|
340
|
+
def clear_scene(self):
|
|
341
|
+
self.is_displayed_in_scene = False
|
|
342
|
+
for label_id in self.labeling_overlays:
|
|
343
|
+
self.labeling_overlays[label_id].set_is_displayed_in_scene(False)
|
|
344
|
+
|
|
345
|
+
def initialyse_zoom_factor(self):
|
|
346
|
+
self.view.min_zoom = self.view.zoomable_graphics_view.data_parameters["zoom"]["min_zoom"]
|
|
347
|
+
self.view.max_zoom = self.view.zoomable_graphics_view.data_parameters["zoom"]["max_zoom"]
|
|
348
|
+
|
|
349
|
+
viewport_width = self.view.zoomable_graphics_view.viewport().width()
|
|
350
|
+
viewport_height = self.view.zoomable_graphics_view.viewport().height()
|
|
351
|
+
diagonal_viewport = numpy.sqrt(viewport_width**2 + viewport_height**2)
|
|
352
|
+
diagonal_pixmap = numpy.sqrt(self.image_qrect.width()**2 + self.image_qrect.height()**2)
|
|
353
|
+
|
|
354
|
+
self.view.zoom_factor = diagonal_pixmap / diagonal_viewport
|
|
355
|
+
if self.view.zoom_factor < self.view.min_zoom: self.view.min_zoom = self.view.zoom_factor
|
|
356
|
+
self.view.max_zoom = diagonal_pixmap/self.view.max_zoom
|
|
357
|
+
self.view.initial_zoom_factor = self.view.zoom_factor
|
|
358
|
+
|
|
359
|
+
def update_labeling_overlays(self, label_items, selected_label_id):
|
|
360
|
+
# Ensure all existing labels have an overlay
|
|
361
|
+
for label_id in label_items:
|
|
362
|
+
print("label_id:", label_id)
|
|
363
|
+
if label_id not in self.labeling_overlays:
|
|
364
|
+
basename_key = ".".join(os.path.basename(self.path_image).split(".")[:-1])+KEYWORD_SAVE_LABEL+str(label_id)+".png"
|
|
365
|
+
print("basename_key:", basename_key)
|
|
366
|
+
if basename_key in self.labeling_overview_was_loaded and self.labeling_overview_was_loaded[basename_key] is False:
|
|
367
|
+
print("We have to load this labeling overlay")
|
|
368
|
+
self.labeling_overlays[label_id] = LabelingOverlay(
|
|
369
|
+
label_items[label_id],
|
|
370
|
+
self.view.zoomable_graphics_view.scene,
|
|
371
|
+
self.image_qrect.width(),
|
|
372
|
+
self.image_qrect.height(),
|
|
373
|
+
self.labeling_overview_file_paths[basename_key]
|
|
374
|
+
)
|
|
375
|
+
self.labeling_overview_was_loaded[basename_key] = True
|
|
376
|
+
else:
|
|
377
|
+
print("We have not to load this labeling overlay")
|
|
378
|
+
self.labeling_overlays[label_id] = LabelingOverlay(
|
|
379
|
+
label_items[label_id],
|
|
380
|
+
self.view.zoomable_graphics_view.scene,
|
|
381
|
+
self.image_qrect.width(),
|
|
382
|
+
self.image_qrect.height()
|
|
383
|
+
)
|
|
384
|
+
self.current_labeling_overlay = self.labeling_overlays[selected_label_id]
|
|
385
|
+
self.current_label_id = selected_label_id
|
|
386
|
+
|
|
387
|
+
def foreground_current_labeling_overlay(self):
|
|
388
|
+
for label_id in self.labeling_overlays:
|
|
389
|
+
if label_id == self.current_label_id:
|
|
390
|
+
self.labeling_overlays[label_id].set_zvalue(3)
|
|
391
|
+
else:
|
|
392
|
+
self.labeling_overlays[label_id].set_zvalue(2)
|
|
393
|
+
# Force the visibility
|
|
394
|
+
# self.current_labeling_overlay.labeling_overlay_item.setVisible(True)
|
|
395
|
+
# print("update_labeling_overlays end")
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
# def new_labeling_overlay(self, label_id, name, labeling_mode, color):
|
|
400
|
+
# # Add a new labeling overlay
|
|
401
|
+
# self.current_labeling_overlay =
|
|
402
|
+
|
|
403
|
+
# # Add the data of this new label in the label dictionnary
|
|
404
|
+
# self.labeling_overlays[label_id] = self.current_labeling_overlay
|
|
405
|
+
|
|
406
|
+
# # Set the current label
|
|
407
|
+
# self.current_label_id = label_id
|
|
408
|
+
|
|
409
|
+
# # Put at the first plan the current label
|
|
410
|
+
# self.foreground_current_labeling_overlay()
|
|
411
|
+
|
|
412
|
+
# # Change the current labeling overlay
|
|
413
|
+
# def select_labeling_overlay(self, label_id):
|
|
414
|
+
# self.current_label_id = label_id
|
|
415
|
+
|
|
416
|
+
# self.current_labeling_overlay = self.labeling_overlays[label_id]
|
|
417
|
+
# self.current_labeling_overlay.labeling_overlay_item.setVisible(True)
|
|
418
|
+
# self.foreground_current_labeling_overlay()
|
|
419
|
+
|
|
420
|
+
def n_labeling_overlays(self):
|
|
421
|
+
return len(self.labeling_overlays)
|
|
422
|
+
|
|
423
|
+
def get_labeling_overlay(self):
|
|
424
|
+
return self.current_labeling_overlay
|
|
425
|
+
|
|
426
|
+
def update_icon_file(self):
|
|
427
|
+
if self.get_edited() is True:
|
|
428
|
+
self.icon_button.setPixmap(self.view.icon_asterisk_red)
|
|
429
|
+
else:
|
|
430
|
+
self.icon_button.setPixmap(self.view.icon_asterisk_green)
|
|
431
|
+
|
|
432
|
+
# Update the current labeling overlay
|
|
433
|
+
def update_labeling_overlay(self):
|
|
434
|
+
self.current_labeling_overlay.update()
|
|
435
|
+
self.update_icon_file()
|
|
436
|
+
|
|
437
|
+
# # Put at the foreground the current labeling overlay
|
|
438
|
+
# def foreground_current_labeling_overlay(self):
|
|
439
|
+
# for label_id in self.labeling_overlays:
|
|
440
|
+
# if label_id == self.current_label_id:
|
|
441
|
+
# self.labeling_overlays[label_id].set_zvalue(3)
|
|
442
|
+
# else:
|
|
443
|
+
# self.labeling_overlays[label_id].set_zvalue(2)
|
|
444
|
+
# self.view.zoomable_graphics_view.scene.update()
|
|
445
|
+
|
|
446
|
+
# Return QPixmap of all labeling overlay except the current one in a ordered list.
|
|
447
|
+
def get_labeling_overlay_pixmaps(self):
|
|
448
|
+
if self.n_labeling_overlays() == 1:
|
|
449
|
+
return []
|
|
450
|
+
result = [labeling_overlay for labeling_overlay in self.labeling_overlays.values() if labeling_overlay != self.current_labeling_overlay]
|
|
451
|
+
result.sort(key=lambda x: x.label.get_label_id())
|
|
452
|
+
return [element.labeling_overlay_pixmap for element in result]
|
|
453
|
+
|
|
454
|
+
def set_opacity(self, opacity):
|
|
455
|
+
for labeling_overlay in self.labeling_overlays.values():
|
|
456
|
+
labeling_overlay.set_opacity(opacity)
|
|
457
|
+
|
|
458
|
+
def update_color(self, label_id):
|
|
459
|
+
self.labeling_overlays[label_id].update_color()
|
|
460
|
+
self.update_icon_file()
|
|
461
|
+
|
|
462
|
+
def get_image_numpy_pixels_rgb(self):
|
|
463
|
+
return self.image_numpy_pixels_rgb
|
|
464
|
+
|
|
465
|
+
def get_width(self):
|
|
466
|
+
return self.image_qrect.width()
|
|
467
|
+
|
|
468
|
+
def get_height(self):
|
|
469
|
+
return self.image_qrect.height()
|
|
470
|
+
|
|
471
|
+
def save_overlays(self, current_file_path):
|
|
472
|
+
for labeling_overlay in self.labeling_overlays.values():
|
|
473
|
+
if labeling_overlay.get_is_edited() is True:
|
|
474
|
+
#img = labeling_overlay.labeling_overlay_pixmap.toImage()
|
|
475
|
+
#if not img.isNull() and not img.allGray():
|
|
476
|
+
#print("save:", current_file_path, self.path_image)
|
|
477
|
+
labeling_overlay.save(current_file_path, self.path_image)
|
|
478
|
+
#else:
|
|
479
|
+
# print("remove:", current_file_path, self.path_image)
|
|
480
|
+
# labeling_overlay.remove_save(current_file_path, self.path_image)
|
|
481
|
+
labeling_overlay.set_is_edited(False)
|
|
482
|
+
|
|
483
|
+
self.update_icon_file()
|
|
484
|
+
|
|
485
|
+
class LabelItem():
|
|
486
|
+
|
|
487
|
+
static_label_id = 0
|
|
488
|
+
used_ids = set()
|
|
489
|
+
|
|
490
|
+
def __init__(self, name, labeling_mode, color, id = None):
|
|
491
|
+
if id is None:
|
|
492
|
+
while LabelItem.static_label_id in LabelItem.used_ids:
|
|
493
|
+
LabelItem.static_label_id += 1
|
|
494
|
+
self.label_id = LabelItem.static_label_id
|
|
495
|
+
LabelItem.used_ids.add(self.label_id)
|
|
496
|
+
LabelItem.static_label_id += 1
|
|
497
|
+
else:
|
|
498
|
+
self.label_id = id
|
|
499
|
+
LabelItem.used_ids.add(self.label_id)
|
|
500
|
+
if id >= LabelItem.static_label_id:
|
|
501
|
+
LabelItem.static_label_id = id + 1
|
|
502
|
+
self.name = name
|
|
503
|
+
self.labeling_mode = labeling_mode
|
|
504
|
+
self.color = QColor(color) # The color of labels in the Labeling Overlay
|
|
505
|
+
self.is_visible = True
|
|
506
|
+
|
|
507
|
+
|
|
508
|
+
def to_dict(self):
|
|
509
|
+
return {"name": self.name, "labeling_mode": self.labeling_mode, "color": [self.color.red(), self.color.green(), self.color.blue()]}
|
|
510
|
+
|
|
511
|
+
def get_label_id(self):
|
|
512
|
+
return self.label_id
|
|
513
|
+
|
|
514
|
+
def get_color(self):
|
|
515
|
+
return self.color
|
|
516
|
+
|
|
517
|
+
def set_color(self, color):
|
|
518
|
+
self.color = color
|
|
519
|
+
|
|
520
|
+
def get_name(self):
|
|
521
|
+
return self.name
|
|
522
|
+
|
|
523
|
+
def set_name(self, name):
|
|
524
|
+
self.name = name
|
|
525
|
+
|
|
526
|
+
def get_labeling_mode(self):
|
|
527
|
+
return self.labeling_mode
|
|
528
|
+
|
|
529
|
+
def set_labeling_mode(self, labeling_mode):
|
|
530
|
+
self.labeling_mode = labeling_mode
|
|
531
|
+
|
|
532
|
+
def set_visible(self, is_visible):
|
|
533
|
+
self.is_visible = is_visible
|
|
534
|
+
|
|
535
|
+
def get_visible(self):
|
|
536
|
+
return self.is_visible
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
class Core():
|
|
540
|
+
|
|
541
|
+
def __init__(self):
|
|
542
|
+
|
|
543
|
+
#self.labels = dict() # All labels in the form of {'label1': {'name': 'label1', 'color': <PyQt6.QtGui.QColor>, 'labeling_mode': 'Pixel-by-pixel'}, ...}
|
|
544
|
+
|
|
545
|
+
self.checked_button = None # The current button checked => usefull to know the labelinf tool to use
|
|
546
|
+
|
|
547
|
+
self.file_paths = [] # List of file paths of images (in the good order)
|
|
548
|
+
|
|
549
|
+
self.image_items = dict() # Dictionnary: (key: file_path) -> (value: ImageItem or None)
|
|
550
|
+
self.label_items = dict() # Dictionnary: (key: label_id) -> (value: LabelItem)
|
|
551
|
+
|
|
552
|
+
self.current_label_item = None # The current label selected
|
|
553
|
+
self.current_image_item = None # The current ImageItem that is display
|
|
554
|
+
|
|
555
|
+
self.icon_button_files = dict()
|
|
556
|
+
|
|
557
|
+
self.save_directory = ""
|
|
558
|
+
|
|
559
|
+
# For a file_path, say if a labeling overview was loaded or not
|
|
560
|
+
self.labeling_overview_was_loaded = dict() # Dictionnary: (key: basename) -> (value: True or False)
|
|
561
|
+
|
|
562
|
+
# To obtain the file path
|
|
563
|
+
self.labeling_overview_file_paths = dict() # Dictionnary: (key: basename) -> (value: file_path)
|
|
564
|
+
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
def reset(self):
|
|
568
|
+
|
|
569
|
+
for file in self.file_paths:
|
|
570
|
+
if self.image_items[file] is not None:
|
|
571
|
+
to_delete = []
|
|
572
|
+
for labeling_overlay_key in self.image_items[file].labeling_overlays:
|
|
573
|
+
self.image_items[file].labeling_overlays[labeling_overlay_key].reset()
|
|
574
|
+
self.image_items[file].labeling_overlays[labeling_overlay_key].remove()
|
|
575
|
+
to_delete.append(labeling_overlay_key)
|
|
576
|
+
|
|
577
|
+
for labeling_overlay_key in to_delete:
|
|
578
|
+
|
|
579
|
+
del self.image_items[file].labeling_overlays[labeling_overlay_key]
|
|
580
|
+
|
|
581
|
+
|
|
582
|
+
|
|
583
|
+
def get_edited(self):
|
|
584
|
+
for file in self.file_paths:
|
|
585
|
+
if self.image_items[file] is not None and self.image_items[file].get_edited() is True:
|
|
586
|
+
return True
|
|
587
|
+
return False
|
|
588
|
+
|
|
589
|
+
def get_label_items(self):
|
|
590
|
+
return self.label_items
|
|
591
|
+
|
|
592
|
+
def get_image_items(self):
|
|
593
|
+
return self.image_items
|
|
594
|
+
|
|
595
|
+
def get_current_label_item(self):
|
|
596
|
+
return self.current_label_item
|
|
597
|
+
|
|
598
|
+
def set_current_label_item(self, current_label_item):
|
|
599
|
+
self.current_label_item = current_label_item
|
|
600
|
+
|
|
601
|
+
def get_current_image_item(self):
|
|
602
|
+
return self.current_image_item
|
|
603
|
+
|
|
604
|
+
def get_current_labeling_overlay(self, label_id):
|
|
605
|
+
return self.current_image_item.labeling_overlays[label_id]
|
|
606
|
+
|
|
607
|
+
def get_static_label_id(self):
|
|
608
|
+
return LabelItem.static_label_id
|
|
609
|
+
|
|
610
|
+
def set_view(self, view):
|
|
611
|
+
self.view = view
|
|
612
|
+
self.zoomable_graphics_view = view.zoomable_graphics_view # short-cut
|
|
613
|
+
|
|
614
|
+
def set_controller(self, controller):
|
|
615
|
+
self.controller = controller
|
|
616
|
+
|
|
617
|
+
def set_opacity(self, opacity):
|
|
618
|
+
for file in self.file_paths:
|
|
619
|
+
if self.image_items[file] is not None:
|
|
620
|
+
self.image_items[file].set_opacity(opacity)
|
|
621
|
+
|
|
622
|
+
def update_icon_file(self):
|
|
623
|
+
for file in self.file_paths:
|
|
624
|
+
image_item = self.image_items[file]
|
|
625
|
+
if image_item is not None:
|
|
626
|
+
image_item.update_icon_file()
|
|
627
|
+
|
|
628
|
+
def update_color(self, label_id):
|
|
629
|
+
for file in self.file_paths:
|
|
630
|
+
image_item = self.image_items[file]
|
|
631
|
+
if image_item is not None:
|
|
632
|
+
image_item.update_color(label_id)
|
|
633
|
+
# We save the image in this case
|
|
634
|
+
image_item.save()
|
|
635
|
+
image_item.update_icon_file()
|
|
636
|
+
else:
|
|
637
|
+
#TODO: if a file (ImageItem) is not open, the color is not update.
|
|
638
|
+
# We have to open the good file and change the color of this file (only the file of the good label_id)
|
|
639
|
+
pass
|
|
640
|
+
|
|
641
|
+
def name_already_exists(self, name):
|
|
642
|
+
for label_id, label_item in self.label_items.items():
|
|
643
|
+
if label_item.get_name() == name:
|
|
644
|
+
return True
|
|
645
|
+
return False
|
|
646
|
+
|
|
647
|
+
def save_labels(self, current_file_path):
|
|
648
|
+
# Get the dictionnary of labels
|
|
649
|
+
labels_dict = {}
|
|
650
|
+
for label_id, label_item in self.label_items.items():
|
|
651
|
+
labels_dict[label_id] = label_item.to_dict()
|
|
652
|
+
|
|
653
|
+
# Save it
|
|
654
|
+
with open(current_file_path+os.sep+"labels.json", 'w') as fp:
|
|
655
|
+
json.dump(labels_dict, fp)
|
|
656
|
+
|
|
657
|
+
def save_overlays(self, current_file_path):
|
|
658
|
+
for file in self.file_paths:
|
|
659
|
+
image_item = self.image_items[file]
|
|
660
|
+
if image_item is not None:
|
|
661
|
+
if image_item.get_edited() is True:
|
|
662
|
+
image_item.save_overlays(current_file_path)
|
|
663
|
+
image_item.update_icon_file()
|
|
664
|
+
|
|
665
|
+
def save(self):
|
|
666
|
+
self.save_labels(self.save_directory)
|
|
667
|
+
self.save_overlays(self.save_directory)
|
|
668
|
+
|
|
669
|
+
def load_labels_json(self, file):
|
|
670
|
+
with open(file, "r") as fp:
|
|
671
|
+
labels_dict = json.load(fp)
|
|
672
|
+
|
|
673
|
+
for lid_str, info in labels_dict.items():
|
|
674
|
+
label_id = int(lid_str)
|
|
675
|
+
name = info.get("name")
|
|
676
|
+
labeling_mode = info.get("labeling_mode")
|
|
677
|
+
color_list = info.get("color")
|
|
678
|
+
color = QColor(*color_list[:3]) if isinstance(color_list, list) else QColor(255, 0, 0)
|
|
679
|
+
|
|
680
|
+
if self.name_already_exists(name) or label_id in self.label_items:
|
|
681
|
+
continue
|
|
682
|
+
|
|
683
|
+
self.label_items[label_id] = LabelItem(name, labeling_mode, color, id = label_id)
|
|
684
|
+
self.view.builder.build_new_layer_label_bar(
|
|
685
|
+
label_id, name, labeling_mode, color
|
|
686
|
+
)
|
|
687
|
+
|
|
688
|
+
def load_labels_images(self, label_file_path):
|
|
689
|
+
# filename = os.path.basename(label_file_path)
|
|
690
|
+
|
|
691
|
+
# # Split to get the parts
|
|
692
|
+
# parts = filename.split(KEYWORD_SAVE_LABEL)
|
|
693
|
+
# if len(parts) != 2:
|
|
694
|
+
# return
|
|
695
|
+
|
|
696
|
+
# original_name = parts[0]
|
|
697
|
+
# label_part = parts[1]
|
|
698
|
+
# label_id = label_part.split('.')[0]
|
|
699
|
+
|
|
700
|
+
# # Find the corresponding image file path
|
|
701
|
+
# image_file_path = None
|
|
702
|
+
# for file_path in self.file_paths:
|
|
703
|
+
# base_name = os.path.basename(file_path).split('.')[0]
|
|
704
|
+
# if base_name == original_name:
|
|
705
|
+
# image_file_path = file_path
|
|
706
|
+
# break
|
|
707
|
+
|
|
708
|
+
# Initialize labeling_overview_loaded if needed
|
|
709
|
+
|
|
710
|
+
basename = os.path.basename(label_file_path)
|
|
711
|
+
print("basename:", basename)
|
|
712
|
+
if label_file_path not in self.labeling_overview_was_loaded:
|
|
713
|
+
self.labeling_overview_was_loaded[basename] = False
|
|
714
|
+
self.labeling_overview_file_paths[basename] = label_file_path
|
|
715
|
+
# # Check if we have an ImageItem for this image file
|
|
716
|
+
# if self.image_items[image_file_path] is not None and label_id in self.label_items:
|
|
717
|
+
# image_item = self.image_items[image_file_path]
|
|
718
|
+
|
|
719
|
+
# if os.path.exists(label_file_path):
|
|
720
|
+
# # Remove the existing overlay if it exists
|
|
721
|
+
# if label_id in image_item.labeling_overlays:
|
|
722
|
+
# old_overlay = image_item.labeling_overlays[label_id]
|
|
723
|
+
# old_overlay.remove()
|
|
724
|
+
|
|
725
|
+
# # Create new overlay with the saved file
|
|
726
|
+
# image_item.labeling_overlays[label_id] = LabelingOverlay(
|
|
727
|
+
# self.label_items[label_id],
|
|
728
|
+
# self.view.zoomable_graphics_view.scene,
|
|
729
|
+
# image_item.get_width(),
|
|
730
|
+
# image_item.get_height(),
|
|
731
|
+
# from_file=label_file_path
|
|
732
|
+
# )
|
|
733
|
+
|
|
734
|
+
# # Update the scene to reflect the loaded overlays
|
|
735
|
+
# image_item.update_scene()
|
|
736
|
+
|
|
737
|
+
# # Mark as loaded
|
|
738
|
+
# self.labeling_overview_loaded[image_file_path] = True
|
|
739
|
+
|
|
740
|
+
|
|
741
|
+
def new_label(self, name, labeling_mode, color):
|
|
742
|
+
label = LabelItem(name, labeling_mode, color)
|
|
743
|
+
self.label_items[label.get_label_id()] = label
|
|
744
|
+
return label
|
|
745
|
+
|
|
746
|
+
def update_labeling_overlays(self, selected_label_id):
|
|
747
|
+
print("update_labeling_overlays")
|
|
748
|
+
for file in self.file_paths:
|
|
749
|
+
if self.image_items[file] is not None:
|
|
750
|
+
print("for file:", file)
|
|
751
|
+
self.image_items[file].update_labeling_overlays(self.label_items, selected_label_id)
|
|
752
|
+
|
|
753
|
+
self.current_label_item = self.label_items[selected_label_id]
|
|
754
|
+
if self.current_image_item is not None:
|
|
755
|
+
self.current_image_item.update_scene()
|
|
756
|
+
self.current_image_item.foreground_current_labeling_overlay()
|
|
757
|
+
|
|
758
|
+
def select_image(self, path_image):
|
|
759
|
+
print("select_image")
|
|
760
|
+
if self.checked_button == "contour_filling":
|
|
761
|
+
self.remove_contour()
|
|
762
|
+
|
|
763
|
+
self.zoomable_graphics_view.scene.clear()
|
|
764
|
+
self.zoomable_graphics_view.resetTransform()
|
|
765
|
+
for file in self.file_paths:
|
|
766
|
+
if self.image_items[file] is not None:
|
|
767
|
+
self.image_items[file].clear_scene()
|
|
768
|
+
|
|
769
|
+
if self.image_items[path_image] is None:
|
|
770
|
+
print("select_image new")
|
|
771
|
+
# We have to load image and theses labels
|
|
772
|
+
self.image_items[path_image] = ImageItem(self.view,
|
|
773
|
+
self.controller,
|
|
774
|
+
path_image,
|
|
775
|
+
self.icon_button_files[path_image],
|
|
776
|
+
self.labeling_overview_was_loaded,
|
|
777
|
+
self.labeling_overview_file_paths)
|
|
778
|
+
self.current_image_item = self.image_items[path_image]
|
|
779
|
+
self.image_items[path_image].update_scene()
|
|
780
|
+
if len(self.label_items) != 0:
|
|
781
|
+
self.image_items[path_image].update_labeling_overlays(
|
|
782
|
+
self.label_items,
|
|
783
|
+
self.current_label_item.get_label_id())
|
|
784
|
+
else:
|
|
785
|
+
print("select_image already exists")
|
|
786
|
+
# Image and these labels are already loaded, display it
|
|
787
|
+
self.image_items[path_image].update_scene()
|
|
788
|
+
self.current_image_item = self.image_items[path_image]
|
|
789
|
+
|
|
790
|
+
if self.checked_button == "contour_filling":
|
|
791
|
+
self.apply_contour()
|
|
792
|
+
|
|
793
|
+
|
|
794
|
+
|
|
795
|
+
|