Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
wangsen
paddle_dbnet
Commits
b103b755
Unverified
Commit
b103b755
authored
Dec 31, 2021
by
Evezerest
Committed by
GitHub
Dec 31, 2021
Browse files
Merge pull request #5040 from redearly123/dygraph
add feature lockshapes
parents
ebc6ce21
107f07c2
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
147 additions
and
38 deletions
+147
-38
PPOCRLabel/PPOCRLabel.py
PPOCRLabel/PPOCRLabel.py
+135
-35
PPOCRLabel/libs/canvas.py
PPOCRLabel/libs/canvas.py
+4
-0
PPOCRLabel/libs/shape.py
PPOCRLabel/libs/shape.py
+2
-1
PPOCRLabel/resources/icons/lock.png
PPOCRLabel/resources/icons/lock.png
+0
-0
PPOCRLabel/resources/strings/strings-en.properties
PPOCRLabel/resources/strings/strings-en.properties
+3
-1
PPOCRLabel/resources/strings/strings-zh-CN.properties
PPOCRLabel/resources/strings/strings-zh-CN.properties
+3
-1
No files found.
PPOCRLabel/PPOCRLabel.py
View file @
b103b755
...
...
@@ -61,7 +61,7 @@ from combobox import ComboBox
from
libs.constants
import
*
from
libs.utils
import
*
from
libs.settings
import
Settings
from
libs.shape
import
Shape
,
DEFAULT_LINE_COLOR
,
DEFAULT_FILL_COLOR
from
libs.shape
import
Shape
,
DEFAULT_LINE_COLOR
,
DEFAULT_FILL_COLOR
,
DEFAULT_LOCK_COLOR
from
libs.stringBundle
import
StringBundle
from
libs.canvas
import
Canvas
from
libs.zoomWidget
import
ZoomWidget
...
...
@@ -126,7 +126,7 @@ class MainWindow(QMainWindow, WindowMixin):
self
.
labelHist
=
[]
self
.
lastOpenDir
=
None
self
.
result_dic
=
[]
self
.
result_dic_locked
=
[]
self
.
changeFileFolder
=
False
self
.
haveAutoReced
=
False
self
.
labelFile
=
None
...
...
@@ -395,6 +395,7 @@ class MainWindow(QMainWindow, WindowMixin):
delete
=
action
(
getStr
(
'delBox'
),
self
.
deleteSelectedShape
,
'backspace'
,
'delete'
,
getStr
(
'delBoxDetail'
),
enabled
=
False
)
copy
=
action
(
getStr
(
'dupBox'
),
self
.
copySelectedShape
,
'Ctrl+C'
,
'copy'
,
getStr
(
'dupBoxDetail'
),
enabled
=
False
)
...
...
@@ -406,6 +407,7 @@ class MainWindow(QMainWindow, WindowMixin):
'Ctrl+A'
,
'hide'
,
getStr
(
'showAllBoxDetail'
),
enabled
=
False
)
help
=
action
(
getStr
(
'tutorial'
),
self
.
showTutorialDialog
,
None
,
'help'
,
getStr
(
'tutorialDetail'
))
showInfo
=
action
(
getStr
(
'info'
),
self
.
showInfoDialog
,
None
,
'help'
,
getStr
(
'info'
))
showSteps
=
action
(
getStr
(
'steps'
),
self
.
showStepsDialog
,
None
,
'help'
,
getStr
(
'steps'
))
...
...
@@ -477,6 +479,10 @@ class MainWindow(QMainWindow, WindowMixin):
undo
=
action
(
getStr
(
"undo"
),
self
.
undoShapeEdit
,
'Ctrl+Z'
,
"undo"
,
getStr
(
"undo"
),
enabled
=
False
)
lock
=
action
(
getStr
(
"lockBox"
),
self
.
lockSelectedShape
,
None
,
"lock"
,
getStr
(
"lockBoxDetail"
),
enabled
=
False
)
self
.
editButton
.
setDefaultAction
(
edit
)
self
.
newButton
.
setDefaultAction
(
create
)
self
.
DelButton
.
setDefaultAction
(
deleteImg
)
...
...
@@ -538,13 +544,13 @@ class MainWindow(QMainWindow, WindowMixin):
fitWindow
=
fitWindow
,
fitWidth
=
fitWidth
,
zoomActions
=
zoomActions
,
saveLabel
=
saveLabel
,
undo
=
undo
,
undoLastPoint
=
undoLastPoint
,
open_dataset_dir
=
open_dataset_dir
,
rotateLeft
=
rotateLeft
,
rotateRight
=
rotateRight
,
rotateLeft
=
rotateLeft
,
rotateRight
=
rotateRight
,
lock
=
lock
,
fileMenuActions
=
(
opendir
,
open_dataset_dir
,
saveLabel
,
resetAll
,
quit
),
beginner
=
(),
advanced
=
(),
editMenu
=
(
createpoly
,
edit
,
copy
,
delete
,
singleRere
,
None
,
undo
,
undoLastPoint
,
None
,
rotateLeft
,
rotateRight
,
None
,
color1
,
self
.
drawSquaresOption
),
beginnerContext
=
(
create
,
edit
,
copy
,
delete
,
singleRere
,
rotateLeft
,
rotateRight
,),
None
,
rotateLeft
,
rotateRight
,
None
,
color1
,
self
.
drawSquaresOption
,
lock
),
beginnerContext
=
(
create
,
edit
,
copy
,
delete
,
singleRere
,
rotateLeft
,
rotateRight
,
lock
),
advancedContext
=
(
createMode
,
editMode
,
edit
,
copy
,
delete
,
shapeLineColor
,
shapeFillColor
),
onLoadActive
=
(
...
...
@@ -998,6 +1004,7 @@ class MainWindow(QMainWindow, WindowMixin):
self
.
actions
.
delete
.
setEnabled
(
n_selected
)
self
.
actions
.
copy
.
setEnabled
(
n_selected
)
self
.
actions
.
edit
.
setEnabled
(
n_selected
==
1
)
self
.
actions
.
lock
.
setEnabled
(
n_selected
)
def
addLabel
(
self
,
shape
):
shape
.
paintLabel
=
self
.
displayLabelOption
.
isChecked
()
...
...
@@ -1041,7 +1048,7 @@ class MainWindow(QMainWindow, WindowMixin):
def
loadLabels
(
self
,
shapes
):
s
=
[]
for
label
,
points
,
line_color
,
fill_color
,
difficult
in
shapes
:
shape
=
Shape
(
label
=
label
)
shape
=
Shape
(
label
=
label
,
line_color
=
line_color
)
for
x
,
y
in
points
:
# Ensure the labels are within the bounds of the image. If not, fix them.
...
...
@@ -1051,6 +1058,7 @@ class MainWindow(QMainWindow, WindowMixin):
shape
.
addPoint
(
QPointF
(
x
,
y
))
shape
.
difficult
=
difficult
#shape.locked = False
shape
.
close
()
s
.
append
(
shape
)
...
...
@@ -1065,9 +1073,11 @@ class MainWindow(QMainWindow, WindowMixin):
# shape.fill_color = generateColorByText(label)
self
.
addLabel
(
shape
)
self
.
updateComboBox
()
self
.
canvas
.
loadShapes
(
s
)
def
singleLabel
(
self
,
shape
):
if
shape
is
None
:
# print('rm empty label')
...
...
@@ -1106,10 +1116,9 @@ class MainWindow(QMainWindow, WindowMixin):
difficult
=
s
.
difficult
)
# bool
shapes
=
[]
if
mode
==
'Auto'
else
\
[
format_shape
(
shape
)
for
shape
in
self
.
canvas
.
shapes
]
[
format_shape
(
shape
)
for
shape
in
self
.
canvas
.
shapes
if
shape
.
line_color
!=
DEFAULT_LOCK_COLOR
]
# Can add differrent annotation formats here
for
box
in
self
.
result_dic
:
for
box
in
self
.
result_dic
:
trans_dic
=
{
"label"
:
box
[
1
][
0
],
"points"
:
box
[
0
],
'difficult'
:
False
}
if
trans_dic
[
"label"
]
==
""
and
mode
==
'Auto'
:
continue
...
...
@@ -1120,7 +1129,6 @@ class MainWindow(QMainWindow, WindowMixin):
for
box
in
shapes
:
trans_dic
.
append
({
"transcription"
:
box
[
'label'
],
"points"
:
box
[
'points'
],
'difficult'
:
box
[
'difficult'
]})
self
.
PPlabel
[
annotationFilePath
]
=
trans_dic
if
mode
==
'Auto'
:
self
.
Cachelabel
[
annotationFilePath
]
=
trans_dic
...
...
@@ -1313,6 +1321,7 @@ class MainWindow(QMainWindow, WindowMixin):
# unicodeFilePath = os.path.abspath(unicodeFilePath)
# Tzutalin 20160906 : Add file list and dock to move faster
# Highlight the file item
if
unicodeFilePath
and
self
.
fileListWidget
.
count
()
>
0
:
if
unicodeFilePath
in
self
.
mImgList
:
index
=
self
.
mImgList
.
index
(
unicodeFilePath
)
...
...
@@ -1322,6 +1331,7 @@ class MainWindow(QMainWindow, WindowMixin):
###
self
.
iconlist
.
clear
()
self
.
additems5
(
None
)
for
i
in
range
(
5
):
item_tooltip
=
self
.
iconlist
.
item
(
i
).
toolTip
()
# print(i,"---",item_tooltip)
...
...
@@ -1340,7 +1350,6 @@ class MainWindow(QMainWindow, WindowMixin):
if
unicodeFilePath
and
os
.
path
.
exists
(
unicodeFilePath
):
self
.
canvas
.
verified
=
False
cvimg
=
cv2
.
imdecode
(
np
.
fromfile
(
unicodeFilePath
,
dtype
=
np
.
uint8
),
1
)
height
,
width
,
depth
=
cvimg
.
shape
cvimg
=
cv2
.
cvtColor
(
cvimg
,
cv2
.
COLOR_BGR2RGB
)
...
...
@@ -1361,12 +1370,15 @@ class MainWindow(QMainWindow, WindowMixin):
else
:
self
.
dirty
=
False
self
.
actions
.
save
.
setEnabled
(
True
)
if
len
(
self
.
canvas
.
lockedShapes
)
!=
0
:
self
.
actions
.
save
.
setEnabled
(
True
)
self
.
setDirty
()
self
.
canvas
.
setEnabled
(
True
)
self
.
adjustScale
(
initial
=
True
)
self
.
paintCanvas
()
self
.
addRecentFile
(
self
.
filePath
)
self
.
toggleActions
(
True
)
self
.
showBoundingBoxFromPPlabel
(
filePath
)
self
.
setWindowTitle
(
__appname__
+
' '
+
filePath
)
...
...
@@ -1380,12 +1392,20 @@ class MainWindow(QMainWindow, WindowMixin):
return
True
return
False
def
showBoundingBoxFromPPlabel
(
self
,
filePath
):
width
,
height
=
self
.
image
.
width
(),
self
.
image
.
height
()
imgidx
=
self
.
getImglabelidx
(
filePath
)
if
imgidx
not
in
self
.
PPlabel
.
keys
():
return
shapes
=
[]
shapes
=
[]
#box['ratio'] of the shapes saved in lockedShapes contains the ratio of the
# four corner coordinates of the shapes to the height and width of the image
for
box
in
self
.
canvas
.
lockedShapes
:
if
self
.
canvas
.
isInTheSameImage
:
shapes
.
append
((
box
[
'transcription'
],
[[
s
[
0
]
*
width
,
s
[
1
]
*
height
]
for
s
in
box
[
'ratio'
]],
DEFAULT_LOCK_COLOR
,
None
,
box
[
'difficult'
]))
else
:
shapes
.
append
((
'锁定框:待检测'
,
[[
s
[
0
]
*
width
,
s
[
1
]
*
height
]
for
s
in
box
[
'ratio'
]],
DEFAULT_LOCK_COLOR
,
None
,
box
[
'difficult'
]))
if
imgidx
in
self
.
PPlabel
.
keys
():
for
box
in
self
.
PPlabel
[
imgidx
]:
shapes
.
append
((
box
[
'transcription'
],
box
[
'points'
],
None
,
None
,
box
[
'difficult'
]))
...
...
@@ -1647,8 +1667,36 @@ class MainWindow(QMainWindow, WindowMixin):
return
fullFilePath
return
''
def
saveLockedShapes
(
self
):
self
.
canvas
.
lockedShapes
=
[]
self
.
canvas
.
selectedShapes
=
[]
for
s
in
self
.
canvas
.
shapes
:
if
s
.
line_color
==
DEFAULT_LOCK_COLOR
:
self
.
canvas
.
selectedShapes
.
append
(
s
)
self
.
lockSelectedShape
()
for
s
in
self
.
canvas
.
shapes
:
if
s
.
line_color
==
DEFAULT_LOCK_COLOR
:
self
.
canvas
.
selectedShapes
.
remove
(
s
)
self
.
canvas
.
shapes
.
remove
(
s
)
def
_saveFile
(
self
,
annotationFilePath
,
mode
=
'Manual'
):
if
len
(
self
.
canvas
.
lockedShapes
)
!=
0
:
self
.
saveLockedShapes
()
if
mode
==
'Manual'
:
self
.
result_dic_locked
=
[]
img
=
cv2
.
imread
(
self
.
filePath
)
width
,
height
=
self
.
image
.
width
(),
self
.
image
.
height
()
for
shape
in
self
.
canvas
.
lockedShapes
:
box
=
[[
int
(
p
[
0
]
*
width
),
int
(
p
[
1
]
*
height
)]
for
p
in
shape
[
'ratio'
]]
assert
len
(
box
)
==
4
result
=
[(
shape
[
'transcription'
],
1
)]
result
.
insert
(
0
,
box
)
self
.
result_dic_locked
.
append
(
result
)
self
.
result_dic
+=
self
.
result_dic_locked
self
.
result_dic_locked
=
[]
if
annotationFilePath
and
self
.
saveLabels
(
annotationFilePath
,
mode
=
mode
):
self
.
setClean
()
self
.
statusBar
().
showMessage
(
'Saved to %s'
%
annotationFilePath
)
...
...
@@ -1663,13 +1711,13 @@ class MainWindow(QMainWindow, WindowMixin):
self
.
savePPlabel
(
mode
=
'Auto'
)
self
.
fileListWidget
.
insertItem
(
int
(
currIndex
),
item
)
if
not
self
.
canvas
.
isInTheSameImage
:
self
.
openNextImg
()
self
.
actions
.
saveRec
.
setEnabled
(
True
)
self
.
actions
.
saveLabel
.
setEnabled
(
True
)
elif
mode
==
'Auto'
:
if
annotationFilePath
and
self
.
saveLabels
(
annotationFilePath
,
mode
=
mode
):
self
.
setClean
()
self
.
statusBar
().
showMessage
(
'Saved to %s'
%
annotationFilePath
)
self
.
statusBar
().
show
()
...
...
@@ -1733,7 +1781,9 @@ class MainWindow(QMainWindow, WindowMixin):
if
discardChanges
==
QMessageBox
.
No
:
return
True
elif
discardChanges
==
QMessageBox
.
Yes
:
self
.
canvas
.
isInTheSameImage
=
True
self
.
saveFile
()
self
.
canvas
.
isInTheSameImage
=
False
return
True
else
:
return
False
...
...
@@ -1872,6 +1922,7 @@ class MainWindow(QMainWindow, WindowMixin):
# org_box = [dic['points'] for dic in self.PPlabel[self.getImglabelidx(self.filePath)]]
if
self
.
canvas
.
shapes
:
self
.
result_dic
=
[]
self
.
result_dic_locked
=
[]
# result_dic_locked stores the ocr result of self.canvas.lockedShapes
rec_flag
=
0
for
shape
in
self
.
canvas
.
shapes
:
box
=
[[
int
(
p
.
x
()),
int
(
p
.
y
())]
for
p
in
shape
.
points
]
...
...
@@ -1883,21 +1934,32 @@ class MainWindow(QMainWindow, WindowMixin):
return
result
=
self
.
ocr
.
ocr
(
img_crop
,
cls
=
True
,
det
=
False
)
if
result
[
0
][
0
]
!=
''
:
if
shape
.
line_color
==
DEFAULT_LOCK_COLOR
:
shape
.
label
=
result
[
0
][
0
]
result
.
insert
(
0
,
box
)
self
.
result_dic_locked
.
append
(
result
)
else
:
result
.
insert
(
0
,
box
)
print
(
'result in reRec is '
,
result
)
self
.
result_dic
.
append
(
result
)
else
:
print
(
'Can not recognise the box'
)
if
shape
.
line_color
==
DEFAULT_LOCK_COLOR
:
shape
.
label
=
result
[
0
][
0
]
self
.
result_dic_locked
.
append
([
box
,(
self
.
noLabelText
,
0
)])
else
:
self
.
result_dic
.
append
([
box
,(
self
.
noLabelText
,
0
)])
try
:
if
self
.
noLabelText
==
shape
.
label
or
result
[
1
][
0
]
==
shape
.
label
:
print
(
'label no change'
)
else
:
rec_flag
+=
1
if
len
(
self
.
result_dic
)
>
0
and
rec_flag
>
0
:
except
IndexError
as
e
:
print
(
'Can not recognise the box'
)
if
(
len
(
self
.
result_dic
)
>
0
and
rec_flag
>
0
)
or
self
.
canvas
.
lockedShapes
:
self
.
canvas
.
isInTheSameImage
=
True
self
.
saveFile
(
mode
=
'Auto'
)
self
.
loadFile
(
self
.
filePath
)
self
.
canvas
.
isInTheSameImage
=
False
self
.
setDirty
()
elif
len
(
self
.
result_dic
)
==
len
(
self
.
canvas
.
shapes
)
and
rec_flag
==
0
:
QMessageBox
.
information
(
self
,
"Information"
,
"The recognition result remains unchanged!"
)
...
...
@@ -2107,6 +2169,44 @@ class MainWindow(QMainWindow, WindowMixin):
self
.
labelList
.
clearSelection
()
self
.
_noSelectionSlot
=
False
self
.
canvas
.
loadShapes
(
shapes
,
replace
=
replace
)
print
(
"loadShapes"
)
#1
def
lockSelectedShape
(
self
):
"""lock the selsected shapes.
Add self.selectedShapes to lock self.canvas.lockedShapes,
which holds the ratio of the four coordinates of the locked shapes
to the width and height of the image
"""
width
,
height
=
self
.
image
.
width
(),
self
.
image
.
height
()
def
format_shape
(
s
):
return
dict
(
label
=
s
.
label
,
# str
line_color
=
s
.
line_color
.
getRgb
(),
fill_color
=
s
.
fill_color
.
getRgb
(),
ratio
=
[[
int
(
p
.
x
())
/
width
,
int
(
p
.
y
())
/
height
]
for
p
in
s
.
points
],
# QPonitF
# add chris
difficult
=
s
.
difficult
)
# bool
#lock
if
len
(
self
.
canvas
.
lockedShapes
)
==
0
:
for
s
in
self
.
canvas
.
selectedShapes
:
s
.
line_color
=
DEFAULT_LOCK_COLOR
s
.
locked
=
True
shapes
=
[
format_shape
(
shape
)
for
shape
in
self
.
canvas
.
selectedShapes
]
trans_dic
=
[]
for
box
in
shapes
:
trans_dic
.
append
({
"transcription"
:
box
[
'label'
],
"ratio"
:
box
[
'ratio'
],
'difficult'
:
box
[
'difficult'
]})
self
.
canvas
.
lockedShapes
=
trans_dic
self
.
actions
.
save
.
setEnabled
(
True
)
#unlock
else
:
for
s
in
self
.
canvas
.
shapes
:
s
.
line_color
=
DEFAULT_LINE_COLOR
self
.
canvas
.
lockedShapes
=
[]
self
.
result_dic_locked
=
[]
self
.
setDirty
()
self
.
actions
.
save
.
setEnabled
(
True
)
def
inverted
(
color
):
...
...
PPOCRLabel/libs/canvas.py
View file @
b103b755
...
...
@@ -87,6 +87,10 @@ class Canvas(QWidget):
#initialisation for panning
self
.
pan_initial_pos
=
QPoint
()
#lockedshapes related
self
.
lockedShapes
=
[]
self
.
isInTheSameImage
=
False
def
setDrawingColor
(
self
,
qColor
):
self
.
drawingLineColor
=
qColor
self
.
drawingRectColor
=
qColor
...
...
PPOCRLabel/libs/shape.py
View file @
b103b755
...
...
@@ -30,6 +30,7 @@ DEFAULT_SELECT_LINE_COLOR = QColor(255, 255, 255)
DEFAULT_SELECT_FILL_COLOR
=
QColor
(
0
,
128
,
255
,
155
)
DEFAULT_VERTEX_FILL_COLOR
=
QColor
(
0
,
255
,
0
,
255
)
DEFAULT_HVERTEX_FILL_COLOR
=
QColor
(
255
,
0
,
0
)
DEFAULT_LOCK_COLOR
=
QColor
(
255
,
0
,
255
)
MIN_Y_LABEL
=
10
...
...
@@ -57,7 +58,7 @@ class Shape(object):
self
.
selected
=
False
self
.
difficult
=
difficult
self
.
paintLabel
=
paintLabel
self
.
locked
=
False
self
.
_highlightIndex
=
None
self
.
_highlightMode
=
self
.
NEAR_VERTEX
self
.
_highlightSettings
=
{
...
...
PPOCRLabel/resources/icons/lock.png
0 → 100644
View file @
b103b755
2.86 KB
PPOCRLabel/resources/strings/strings-en.properties
View file @
b103b755
...
...
@@ -105,3 +105,5 @@ labelDialogOption=Pop-up Label Input Dialog
undo
=
Undo
undoLastPoint
=
Undo Last Point
autoSaveMode
=
Auto Export Label Mode
lockBox
=
Lock selected box/Unlock all box
lockBoxDetail
=
Lock selected box/Unlock all box
\ No newline at end of file
PPOCRLabel/resources/strings/strings-zh-CN.properties
View file @
b103b755
...
...
@@ -105,3 +105,5 @@ labelDialogOption=弹出标记输入框
undo
=
撤销
undoLastPoint
=
撤销上个点
autoSaveMode
=
自动导出标记结果
lockBox
=
锁定框/解除锁定框
lockBoxDetail
=
若当前没有框处于锁定状态则锁定选中的框,若存在锁定框则解除所有锁定框的锁定状态
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment