Skip to content

Commit 2bff95e

Browse files
authored
Add redo in EISeg
1 parent 921dce5 commit 2bff95e

File tree

4 files changed

+48
-13
lines changed

4 files changed

+48
-13
lines changed

contrib/EISeg/README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
# EISeg
55

6-
EISeg(Efficient Interactive Segmentation)是基于飞桨开发的一个高效智能的交互式分割标注软件. 它使用了RITM(Reviving Iterative Training with Mask Guidance for Interactive Segmentation)算法,涵盖了高精度和轻量级等不同方向的高质量交互式分割模型,方便开发者快速实现语义及实例标签的标注,降低标注成本。 另外,将EISeg获取到的标注应用到PaddleSeg提供的其他分割模型进行训练,便可得到定制化场景的高精度模型,打通分割任务从数据标注到模型训练及预测的全流程。
6+
EISeg(Efficient Interactive Segmentation)是基于飞桨开发的一个高效智能的交互式分割标注软件它使用了RITM(Reviving Iterative Training with Mask Guidance for Interactive Segmentation)算法,涵盖了高精度和轻量级等不同方向的高质量交互式分割模型,方便开发者快速实现语义及实例标签的标注,降低标注成本。 另外,将EISeg获取到的标注应用到PaddleSeg提供的其他分割模型进行训练,便可得到定制化场景的高精度模型,打通分割任务从数据标注到模型训练及预测的全流程。
77

88

99

@@ -62,7 +62,7 @@ eiseg
6262

6363
### Windows exe
6464

65-
EISeg使用[QPT](https://github.com/GT-ZhangAcer/QPT)进行打包。可以从[百度云盘](https://pan.baidu.com/s/1XF_Fi6HK28XnPvfuVGj0bA)(提取码:82z9)下载最新EISeg。解压后双击启动程序.exe即可运行程序。程序第一次运行会初始化安装所需要的包,请稍等片刻。
65+
EISeg使用[QPT](https://github.com/GT-ZhangAcer/QPT)进行打包。可以从[百度云盘](https://pan.baidu.com/s/1skX0Zz6mxH8snpm7MOlzaQ)(提取码:82z9)下载最新EISeg。解压后双击启动程序.exe即可运行程序。程序第一次运行会初始化安装所需要的包,请稍等片刻。
6666

6767
### 运行代码
6868

contrib/EISeg/eiseg/app.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,13 @@ def menu(title, actions=None):
161161
"Undo",
162162
self.tr("撤销一次点击"),
163163
)
164+
redo = action(
165+
self.tr("&重做"),
166+
self.redoClick,
167+
shortcuts["redo"],
168+
"Redo",
169+
self.tr("重做一次点击"),
170+
)
164171
save = action(
165172
self.tr("&保存"),
166173
self.saveLabel,
@@ -253,6 +260,7 @@ def menu(title, actions=None):
253260
finish_object,
254261
clear,
255262
undo,
263+
redo,
256264
turn_prev,
257265
turn_next,
258266
),
@@ -774,7 +782,11 @@ def undoAll(self):
774782
self.setClean()
775783

776784
def redoClick(self):
777-
self.toBeImplemented()
785+
if self.image is None:
786+
return
787+
if not self.controller:
788+
return
789+
self.controller.redo_click()
778790

779791
def canvasClick(self, x, y, isLeft):
780792
if self.controller is None:

contrib/EISeg/eiseg/controller.py

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ def __init__(self, net, predictor_params, update_image_callback, prob_thresh=0.5
1717
self.clicker = clicker.Clicker()
1818
self.states = []
1919
self.probs_history = []
20+
self.undo_states = []
21+
self.undo_probs_history = []
2022
self.curr_label_number = 0
2123
self._result_mask = None
2224
self.label_list = None # 存标签编号和颜色的对照
@@ -70,20 +72,30 @@ def add_click(self, x, y, is_positive):
7072
s = self.image.shape
7173
if x < 0 or y < 0 or x >= s[1] or y >= s[0]:
7274
return False
73-
self.states.append(
74-
{
75+
76+
if len(self.states) == 0: # 保存最初状态
77+
self.states.append({
7578
"clicker": self.clicker.get_state(),
7679
"predictor": self.predictor.get_states(),
77-
}
78-
)
80+
})
7981

8082
click = clicker.Click(is_positive=is_positive, coords=(y, x))
8183
self.clicker.add_click(click)
84+
start = time.time()
85+
print(self.predictor)
8286
pred = self.predictor.get_prediction(self.clicker, prev_mask=self._init_mask)
8387
if self._init_mask is not None and len(self.clicker) == 1:
8488
pred = self.predictor.get_prediction(
8589
self.clicker, prev_mask=self._init_mask
8690
)
91+
end = time.time()
92+
print("cost time", end - start)
93+
94+
# 保存最新状态
95+
self.states.append({
96+
"clicker": self.clicker.get_state(),
97+
"predictor": self.predictor.get_states(),
98+
})
8799

88100
if self.probs_history:
89101
self.probs_history.append((self.probs_history[-1][0], pred))
@@ -97,17 +109,28 @@ def set_label(self, label):
97109

98110
def undo_click(self):
99111
"""undo一步点击"""
100-
if not self.states: # 如果还没点
112+
if len(self.states) == 1: # 如果还没点
101113
return
102-
103-
prev_state = self.states.pop()
104-
self.clicker.set_state(prev_state["clicker"])
105-
self.predictor.set_states(prev_state["predictor"])
106-
self.probs_history.pop()
114+
self.undo_states.append(self.states.pop())
115+
self.clicker.set_state(self.states[-1]["clicker"])
116+
self.predictor.set_states(self.states[-1]["predictor"])
117+
self.undo_probs_history.append(self.probs_history.pop())
107118
if not self.probs_history:
108119
self.reset_init_mask()
109120
self.update_image_callback()
110121

122+
def redo_click(self):
123+
"""redo一步点击"""
124+
if not self.undo_states: # 如果还没撤销过
125+
return
126+
if len(self.undo_probs_history) >= 1:
127+
next_state = self.undo_states.pop()
128+
self.states.append(next_state)
129+
self.clicker.set_state(next_state["clicker"])
130+
self.predictor.set_states(next_state["predictor"])
131+
self.probs_history.append(self.undo_probs_history.pop())
132+
self.update_image_callback()
133+
111134
def partially_finish_object(self):
112135
"""部分完成
113136
保存一个mask的状态,这个状态里不存点,看起来比较

contrib/EISeg/eiseg/resource/Redo.png

4.6 KB
Loading

0 commit comments

Comments
 (0)