diff --git a/isat.yaml b/isat.yaml
index bec54bb..6ea21f0 100644
--- a/isat.yaml
+++ b/isat.yaml
@@ -1,4 +1,4 @@
-contour_mode: all
+contour_mode: external
label:
- color: '#000000'
name: __background__
@@ -21,4 +21,4 @@ label:
- color: '#5c3566'
name: fence
language: en
-mask_alpha: 0.5
+mask_alpha: 0.6
diff --git a/main.py b/main.py
index cea8269..6791910 100644
--- a/main.py
+++ b/main.py
@@ -12,5 +12,5 @@ if __name__ == '__main__':
app = QtWidgets.QApplication([''])
mainwindow = MainWindow()
mainwindow.show()
- sys.exit(app.exec())
+ sys.exit(app.exec_())
diff --git a/ui/MainWindow.py b/ui/MainWindow.py
index 656819d..0930472 100644
--- a/ui/MainWindow.py
+++ b/ui/MainWindow.py
@@ -487,12 +487,12 @@ class Ui_MainWindow(object):
self.actionTo_LabelMe.setToolTip(_translate("MainWindow", "Convert ISAT to LabelMe"))
self.actionTo_LabelMe.setStatusTip(_translate("MainWindow", "Convert ISAT jsons to LabelMe jsons."))
self.actionContour_Max_only.setText(_translate("MainWindow", "Max only"))
- self.actionContour_Max_only.setStatusTip(_translate("MainWindow", "Contour save max only."))
- self.actionContour_Max_only.setWhatsThis(_translate("MainWindow", "Contour save max only."))
+ self.actionContour_Max_only.setStatusTip(_translate("MainWindow", "Max contour save only."))
+ self.actionContour_Max_only.setWhatsThis(_translate("MainWindow", "Max contour save only."))
self.actionContour_External.setText(_translate("MainWindow", "External"))
- self.actionContour_External.setStatusTip(_translate("MainWindow", "Contour save external only."))
- self.actionContour_External.setWhatsThis(_translate("MainWindow", "Contour save external only."))
+ self.actionContour_External.setStatusTip(_translate("MainWindow", "External contour save only."))
+ self.actionContour_External.setWhatsThis(_translate("MainWindow", "External contour save only."))
self.actionContour_All.setText(_translate("MainWindow", "All"))
- self.actionContour_All.setStatusTip(_translate("MainWindow", "Contour save all."))
- self.actionContour_All.setWhatsThis(_translate("MainWindow", "Contour save all."))
+ self.actionContour_All.setStatusTip(_translate("MainWindow", "All contour save."))
+ self.actionContour_All.setWhatsThis(_translate("MainWindow", "All contour save."))
import icons_rc
diff --git a/ui/MainWindow.ui b/ui/MainWindow.ui
index 481b280..210e37b 100644
--- a/ui/MainWindow.ui
+++ b/ui/MainWindow.ui
@@ -803,10 +803,10 @@
Max only
- Contour save max only.
+ Max contour save only.
- Contour save max only.
+ Max contour save only.
@@ -823,10 +823,10 @@
External
- Contour save external only.
+ External contour save only.
- Contour save external only.
+ External contour save only.
@@ -843,10 +843,10 @@
All
- Contour save all.
+ All contour save.
- Contour save all.
+ All contour save.
diff --git a/ui/anno_dock.py b/ui/anno_dock.py
index 7f653f3..cf9be55 100644
--- a/ui/anno_dock.py
+++ b/ui/anno_dock.py
@@ -1,5 +1,7 @@
# -*- coding: utf-8 -*-
+# Form implementation generated from reading ui file '/home/super/PycharmProjects/ISAT_with_segment_anything/ui/anno_dock.ui'
+#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
@@ -12,7 +14,7 @@ from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
- Form.resize(250, 302)
+ Form.resize(339, 302)
self.verticalLayout = QtWidgets.QVBoxLayout(Form)
self.verticalLayout.setContentsMargins(2, 2, 2, 2)
self.verticalLayout.setSpacing(0)
@@ -23,17 +25,37 @@ class Ui_Form(object):
self.horizontalLayout.setContentsMargins(-1, -1, -1, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
self.checkBox_visible = QtWidgets.QCheckBox(self.widget)
+ self.checkBox_visible.setMaximumSize(QtCore.QSize(120, 16777215))
self.checkBox_visible.setObjectName("checkBox_visible")
self.horizontalLayout.addWidget(self.checkBox_visible)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem)
self.comboBox_group_select = QtWidgets.QComboBox(self.widget)
+ self.comboBox_group_select.setMaximumSize(QtCore.QSize(60, 16777215))
self.comboBox_group_select.setObjectName("comboBox_group_select")
self.horizontalLayout.addWidget(self.comboBox_group_select)
self.button_prev_group = QtWidgets.QPushButton(self.widget)
+ self.button_prev_group.setMaximumSize(QtCore.QSize(25, 16777215))
+ self.button_prev_group.setText("")
+ icon = QtGui.QIcon()
+ icon.addPixmap(QtGui.QPixmap(":/icon/icons/上一步_back.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.button_prev_group.setIcon(icon)
self.button_prev_group.setObjectName("button_prev_group")
self.horizontalLayout.addWidget(self.button_prev_group)
self.button_next_group = QtWidgets.QPushButton(self.widget)
+ self.button_next_group.setMaximumSize(QtCore.QSize(25, 16777215))
+ self.button_next_group.setText("")
+ icon1 = QtGui.QIcon()
+ icon1.addPixmap(QtGui.QPixmap(":/icon/icons/下一步_next.svg"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
+ self.button_next_group.setIcon(icon1)
self.button_next_group.setObjectName("button_next_group")
self.horizontalLayout.addWidget(self.button_next_group)
+ self.label = QtWidgets.QLabel(self.widget)
+ self.label.setMinimumSize(QtCore.QSize(3, 0))
+ self.label.setMaximumSize(QtCore.QSize(3, 16777215))
+ self.label.setText("")
+ self.label.setObjectName("label")
+ self.horizontalLayout.addWidget(self.label)
self.verticalLayout.addWidget(self.widget)
self.listWidget = QtWidgets.QListWidget(Form)
self.listWidget.setObjectName("listWidget")
@@ -46,5 +68,4 @@ class Ui_Form(object):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.checkBox_visible.setText(_translate("Form", "Visible"))
- self.button_prev_group.setText(_translate("Form", "Previous"))
- self.button_next_group.setText(_translate("Form", "Next"))
+import icons_rc
diff --git a/ui/anno_dock.ui b/ui/anno_dock.ui
index 119d32d..90b0f5c 100644
--- a/ui/anno_dock.ui
+++ b/ui/anno_dock.ui
@@ -6,7 +6,7 @@
0
0
- 250
+ 339
302
@@ -37,25 +37,90 @@
-
+
+
+ 120
+ 16777215
+
+
Visible
-
-
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 60
+ 16777215
+
+
+
-
+
+
+ 25
+ 16777215
+
+
- Previous
+
+
+
+
+ :/icon/icons/上一步_back.svg:/icon/icons/上一步_back.svg
-
+
+
+ 25
+ 16777215
+
+
- Next
+
+
+
+
+ :/icon/icons/下一步_next.svg:/icon/icons/下一步_next.svg
+
+
+
+ -
+
+
+
+ 3
+ 0
+
+
+
+
+ 3
+ 16777215
+
+
+
+
@@ -67,6 +132,8 @@
-
+
+
+
diff --git a/ui/zh_CN.qm b/ui/zh_CN.qm
index c8c4471..a2527a3 100644
Binary files a/ui/zh_CN.qm and b/ui/zh_CN.qm differ
diff --git a/ui/zh_CN.ts b/ui/zh_CN.ts
index f170f95..cea0114 100644
--- a/ui/zh_CN.ts
+++ b/ui/zh_CN.ts
@@ -526,7 +526,7 @@ p, li { white-space: pre-wrap; }
Form
-
+
Form
@@ -571,7 +571,7 @@ p, li { white-space: pre-wrap; }
跳转到指定图片.
-
+
Visible
显示/隐藏
@@ -579,52 +579,52 @@ p, li { white-space: pre-wrap; }
MainWindow
-
+
ISAT
ISAT 图片分割标注工具
-
+
File
文件
-
+
View
视图
-
+
Help
帮助
-
+
Tools
工具
-
+
Edit
编辑
-
+
toolBar
工具栏
-
+
Info
图片信息
Labels
- 标签列表
+ 标签列表
-
+
Files
文件列表
@@ -639,32 +639,32 @@ p, li { white-space: pre-wrap; }
打开图片文件夹
-
+
Zoom in
放大
-
+
Zoom out
缩小
-
+
Fit window
适应窗口
-
+
F
-
+
Setting
设置
-
+
Exit
退出
@@ -674,12 +674,12 @@ p, li { white-space: pre-wrap; }
标签保存位置
-
+
Save
保存
-
+
S
@@ -689,12 +689,12 @@ p, li { white-space: pre-wrap; }
上一张
-
+
Prev image
上一张图片
-
+
A
@@ -704,17 +704,17 @@ p, li { white-space: pre-wrap; }
下一张
-
+
Next image
下一张图片
-
+
D
-
+
About
关于
@@ -729,72 +729,72 @@ p, li { white-space: pre-wrap; }
创建多边形
-
+
C
-
+
Delete
删除
-
+
Delete polygon
删除多边形
-
+
Del
-
+
Bit map
位图
-
+
Space
-
+
Edit polygon
编辑多边形
-
+
E
-
+
To top
置顶
-
+
Move polygon to top layer
移动多边形到顶层
-
+
T
-
+
To bottom
置底
-
+
Move polygon to bottom layer
移动多边形到底层
-
+
B
@@ -809,12 +809,12 @@ p, li { white-space: pre-wrap; }
将ISAT标注文件转换为png图片.
-
+
Laguage
语言
-
+
Shortcut
快捷键
@@ -824,52 +824,52 @@ p, li { white-space: pre-wrap; }
中文
-
+
English
-
+
中文
-
+
Images dir
图片文件夹
-
+
Open images dir.
打开图片文件夹.
-
+
Zoom in.
放大.
-
+
Zoom out.
缩小.
-
+
Fit window.
适应窗口.
-
+
Label dir
标签文件夹
-
+
Open label dir.
打开标签文件夹.
-
+
Save annotation.
保存.
@@ -884,7 +884,7 @@ p, li { white-space: pre-wrap; }
打开上一张图片.
-
+
Next image.
下一张图片.
@@ -894,142 +894,142 @@ p, li { white-space: pre-wrap; }
打开下一张图片.
-
+
Delete polygon.
删除多边形.
-
+
Show instance or segmeent state.
显示语义与实例结果.
-
+
Edit polygon attribute.
编辑多边形属性.
-
+
Move polygon to top layer.
将多边形移动到最上层.
-
+
Move polygon to bottom layer.
将多边形移动到最下层.
-
+
Setting.
设置.
-
+
Exit.
退出.
-
+
Prev image.
前一张图片.
-
+
Segment anything
-
+
Quick annotate using Segment anything.
使用Segment anything进行快速标注.
-
+
Q
-
+
Backspace
回退
-
+
Backspace.
回退.
-
+
Z
-
+
Cancel
取消
-
+
Annotate canceled
标注取消
-
+
Annotate canceled.
标注取消.
-
+
Esc
-
+
Finish
完成
-
+
Annotate finished
标注完成
-
+
Annotate finished.
标注完成.
-
+
Polygon
多边形
-
+
Draw polygon
绘制多边形
-
+
Accurately annotate by drawing polygon.
通过手动绘制多边形,进行精细标注.
-
+
Visible
显示/隐藏
-
+
V
-
+
To VOC
-
+
Convert ISAT to VOC
ISAT转VOC
@@ -1039,54 +1039,114 @@ p, li { white-space: pre-wrap; }
将ISAT格式json转换为VOC单通道png。
-
+
To COCO
-
+
Convert ISAT to COCO
ISAT转COCO
-
+
Convert ISAT jsons to COCO json.
将ISAT格式json转换为COCO格式json。
-
+
From COCO
-
+
Convert COCO to ISAT
COCO转ISAT
-
+
Convert COCO json to ISAT jsons.
将COCO格式json转换为ISAT格式json。
-
+
Convert ISAT jsons to VOC png images.
将ISAT格式json转换为VOC单通道png图片。
-
+
To LabelMe
-
+
Convert ISAT to LabelMe
ISAT转LabelMe
-
+
Convert ISAT jsons to LabelMe jsons.
将ISAT格式json转换为LabelMe格式json。
+
+
+ Mode
+ 模式
+
+
+
+ Contour mode
+ 轮廓模式
+
+
+
+ SAM
+
+
+
+
+ Annos
+ 标注
+
+
+
+ Categories
+ 类别
+
+
+
+ Visible.
+ 显示/隐藏.
+
+
+
+ Max only
+ 只保存最大轮廓
+
+
+
+ Max contour save only.
+ 只保存最大轮廓.
+
+
+
+ External
+ 只保存外轮廓
+
+
+
+ External contour save only.
+ 只保存外轮廓.
+
+
+
+ All
+ 保存所有轮廓
+
+
+
+ All contour save.
+ 保存所有轮廓.
+
diff --git a/widgets/annos_dock_widget.py b/widgets/annos_dock_widget.py
index bdc85c4..b044b6e 100644
--- a/widgets/annos_dock_widget.py
+++ b/widgets/annos_dock_widget.py
@@ -20,6 +20,9 @@ class AnnosDockWidget(QtWidgets.QWidget, Ui_Form):
self.comboBox_group_select.currentIndexChanged.connect(self.set_group_polygon_visible)
self.button_next_group.clicked.connect(self.go_to_next_group)
self.button_prev_group.clicked.connect(self.go_to_prev_group)
+ self.comboBox_group_select.setStatusTip('Select polygons by group.')
+ self.button_prev_group.setStatusTip('Prev group.')
+ self.button_next_group.setStatusTip('Next group.')
self.listWidget.setContextMenuPolicy(QtCore.Qt.ContextMenuPolicy.CustomContextMenu)
self.listWidget.customContextMenuRequested.connect(
@@ -50,8 +53,10 @@ class AnnosDockWidget(QtWidgets.QWidget, Ui_Form):
category = QtWidgets.QLabel(polygon.category)
group = QtWidgets.QLabel('{}'.format(polygon.group))
-
+ group.setFixedWidth(50)
note = QtWidgets.QLabel('{}'.format(polygon.note))
+ note.setToolTip(polygon.note)
+ note.setFixedWidth(46)
label_iscrowd = QtWidgets.QLabel()
label_iscrowd.setFixedWidth(3)
@@ -61,7 +66,7 @@ class AnnosDockWidget(QtWidgets.QWidget, Ui_Form):
layout.addWidget(category)
layout.addWidget(group)
layout.addWidget(note)
- layout.addWidget(label_iscrowd, alignment=QtCore.Qt.AlignmentFlag.AlignRight)
+ layout.addWidget(label_iscrowd)
item_widget.setLayout(layout)
return item, item_widget
@@ -83,7 +88,8 @@ class AnnosDockWidget(QtWidgets.QWidget, Ui_Form):
unique_groups = {polygon.group for polygon in self.mainwindow.polygons}
self.comboBox_group_select.clear()
self.comboBox_group_select.addItem('All') # add an option to view all groups
- self.comboBox_group_select.addItems(sorted(unique_groups, key=lambda s: [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', s)]))
+ self.comboBox_group_select.addItems(sorted([str(item) for item in unique_groups],
+ key=lambda s: [int(t) if t.isdigit() else t for t in re.split(r'(\d+)', s)]))
def set_selected(self, polygon):
item = self.polygon_item_dict[polygon]
@@ -131,16 +137,24 @@ class AnnosDockWidget(QtWidgets.QWidget, Ui_Form):
for polygon, item in self.polygon_item_dict.items():
widget = self.listWidget.itemWidget(item)
check_box = widget.findChild(QtWidgets.QCheckBox, 'check_box')
-
- if selected_group == 'All' or polygon.group == selected_group:
+ if selected_group == '':
+ return
+ if selected_group == 'All' or polygon.group == int(selected_group):
check_box.setChecked(True)
else:
check_box.setChecked(False)
+ self.zoom_to_group()
+
def zoom_to_group(self):
selected_group = self.comboBox_group_select.currentText()
- polygons_in_group = [polygon for polygon, item in self.polygon_item_dict.items()
- if polygon.group == selected_group]
+ if selected_group == '':
+ return
+ if selected_group == 'All':
+ polygons_in_group = [polygon for polygon, item in self.polygon_item_dict.items()]
+ else:
+ polygons_in_group = [polygon for polygon, item in self.polygon_item_dict.items()
+ if polygon.group == int(selected_group)]
if not polygons_in_group:
return
min_x = min(min(vertex.x() for vertex in polygon.vertexs) for polygon in polygons_in_group)
@@ -157,14 +171,12 @@ class AnnosDockWidget(QtWidgets.QWidget, Ui_Form):
if current_index < max_index:
self.comboBox_group_select.setCurrentIndex(current_index + 1)
self.set_group_polygon_visible()
- self.zoom_to_group()
def go_to_prev_group(self):
current_index = self.comboBox_group_select.currentIndex()
if current_index > 0:
self.comboBox_group_select.setCurrentIndex(current_index - 1)
self.set_group_polygon_visible()
- self.zoom_to_group()
diff --git a/widgets/canvas.py b/widgets/canvas.py
index 166a2a4..e7b4ea6 100644
--- a/widgets/canvas.py
+++ b/widgets/canvas.py
@@ -515,8 +515,8 @@ class AnnotationView(QtWidgets.QGraphicsView):
# 缩放比例
pix_widget = self.transform().scale(factor, factor).mapRect(QtCore.QRectF(0, 0, 1, 1)).width()
- if pix_widget > 3 or pix_widget < 0.01:
- return
+ if pix_widget > 30 and factor > 1: return
+ if pix_widget < 0.01 and factor < 1: return
self.scale(factor, factor)
if point is not None:
diff --git a/widgets/category_choice_dialog.py b/widgets/category_choice_dialog.py
index 30e7d1b..7b67494 100644
--- a/widgets/category_choice_dialog.py
+++ b/widgets/category_choice_dialog.py
@@ -71,7 +71,7 @@ class CategoryChoiceDialog(QtWidgets.QDialog, Ui_Dialog):
def apply(self):
category = self.lineEdit_category.text()
- group = self.lineEdit_group.text()
+ group = int(self.lineEdit_group.text())
is_crowd = int(self.checkBox_iscrowded.isChecked())
note = self.lineEdit_note.text()
if not category:
diff --git a/widgets/category_edit_dialog.py b/widgets/category_edit_dialog.py
index a6d8ae8..51d6dc1 100644
--- a/widgets/category_edit_dialog.py
+++ b/widgets/category_edit_dialog.py
@@ -89,7 +89,7 @@ class CategoryEditDialog(QtWidgets.QDialog, Ui_Dialog):
def apply(self):
category = self.lineEdit_category.text()
- group = self.lineEdit_group.text()
+ group = int(self.lineEdit_group.text())
is_crowd = int(self.checkBox_iscrowded.isChecked())
note = self.lineEdit_note.text()
if not category:
diff --git a/widgets/mainwindow.py b/widgets/mainwindow.py
index 99bad76..fd9b2e7 100644
--- a/widgets/mainwindow.py
+++ b/widgets/mainwindow.py
@@ -57,7 +57,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
# 标注目标
self.current_label:Annotation = None
self.use_segment_anything = False
-
+ self.gpu_resource_thread = None
self.init_ui()
self.reload_cfg()
@@ -65,6 +65,7 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.reset_action()
def init_segment_anything(self, model_name, reload=False):
+
if model_name == '':
self.use_segment_anything = False
for name, action in self.pths_actions.items():
@@ -85,18 +86,18 @@ class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
self.statusbar.showMessage('Use the checkpoint named {}.'.format(model_name), 3000)
for name, action in self.pths_actions.items():
action.setChecked(model_name==name)
- if not reload:
- if self.use_segment_anything:
- if self.segany.device != 'cpu':
+ if self.use_segment_anything:
+ if self.segany.device != 'cpu':
+ if self.gpu_resource_thread is None:
self.gpu_resource_thread = GPUResource_Thread()
self.gpu_resource_thread.message.connect(self.labelGPUResource.setText)
self.gpu_resource_thread.start()
- else:
- self.labelGPUResource.setText('cpu')
else:
- self.labelGPUResource.setText('segment anything unused.')
+ self.labelGPUResource.setText('cpu')
+ else:
+ self.labelGPUResource.setText('segment anything unused.')
- if reload and self.current_index is not None:
+ if self.current_index is not None:
self.show_image(self.current_index)
def init_ui(self):
diff --git a/widgets/polygon.py b/widgets/polygon.py
index 2699b9a..0b2173d 100644
--- a/widgets/polygon.py
+++ b/widgets/polygon.py
@@ -191,6 +191,8 @@ class Polygon(QtWidgets.QGraphicsPolygonItem):
def set_drawed(self, category, group, iscrowd, note, color:QtGui.QColor, layer=None):
self.is_drawing = False
self.category = category
+ if isinstance(group, str):
+ group = 0 if group == '' else int(group)
self.group = group
self.iscrowd = iscrowd
self.note = note