Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
s920243400
PaddleOCR
提交
7ec4c0e4
P
PaddleOCR
项目概览
s920243400
/
PaddleOCR
与 Fork 源项目一致
Fork自
PaddlePaddle / PaddleOCR
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
P
PaddleOCR
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
7ec4c0e4
编写于
12月 14, 2020
作者:
qq_25193841
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Delete xml related codes
上级
f45bdf5b
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
8 addition
and
537 deletion
+8
-537
PPOCRLabel/PPOCRLabel.py
PPOCRLabel/PPOCRLabel.py
+8
-56
PPOCRLabel/libs/labelFile.py
PPOCRLabel/libs/labelFile.py
+0
-152
PPOCRLabel/libs/pascal_voc_io.py
PPOCRLabel/libs/pascal_voc_io.py
+0
-183
PPOCRLabel/libs/yolo_io.py
PPOCRLabel/libs/yolo_io.py
+0
-146
未找到文件。
PPOCRLabel/PPOCRLabel.py
浏览文件 @
7ec4c0e4
...
@@ -61,7 +61,6 @@ from libs.zoomWidget import ZoomWidget
...
@@ -61,7 +61,6 @@ from libs.zoomWidget import ZoomWidget
from
libs.autoDialog
import
AutoDialog
from
libs.autoDialog
import
AutoDialog
from
libs.labelDialog
import
LabelDialog
from
libs.labelDialog
import
LabelDialog
from
libs.colorDialog
import
ColorDialog
from
libs.colorDialog
import
ColorDialog
from
libs.labelFile
import
LabelFile
,
LabelFileError
from
libs.toolBar
import
ToolBar
from
libs.toolBar
import
ToolBar
from
libs.ustr
import
ustr
from
libs.ustr
import
ustr
from
libs.hashableQListWidgetItem
import
HashableQListWidgetItem
from
libs.hashableQListWidgetItem
import
HashableQListWidgetItem
...
@@ -1028,9 +1027,6 @@ class MainWindow(QMainWindow, WindowMixin):
...
@@ -1028,9 +1027,6 @@ class MainWindow(QMainWindow, WindowMixin):
def
saveLabels
(
self
,
annotationFilePath
,
mode
=
'Auto'
):
def
saveLabels
(
self
,
annotationFilePath
,
mode
=
'Auto'
):
# Mode is Auto means that labels will be loaded from self.result_dic totally, which is the output of ocr model
# Mode is Auto means that labels will be loaded from self.result_dic totally, which is the output of ocr model
annotationFilePath
=
ustr
(
annotationFilePath
)
annotationFilePath
=
ustr
(
annotationFilePath
)
if
self
.
labelFile
is
None
:
self
.
labelFile
=
LabelFile
()
self
.
labelFile
.
verified
=
self
.
canvas
.
verified
def
format_shape
(
s
):
def
format_shape
(
s
):
# print('s in saveLabels is ',s)
# print('s in saveLabels is ',s)
...
@@ -1065,8 +1061,8 @@ class MainWindow(QMainWindow, WindowMixin):
...
@@ -1065,8 +1061,8 @@ class MainWindow(QMainWindow, WindowMixin):
# self.lineColor.getRgb(), self.fillColor.getRgb())
# self.lineColor.getRgb(), self.fillColor.getRgb())
# print('Image:{0} -> Annotation:{1}'.format(self.filePath, annotationFilePath))
# print('Image:{0} -> Annotation:{1}'.format(self.filePath, annotationFilePath))
return
True
return
True
except
LabelFileError
as
e
:
except
:
self
.
errorMessage
(
u
'Error saving label data'
,
u
'<b>%s</b>'
%
e
)
self
.
errorMessage
(
u
'Error saving label data'
)
return
False
return
False
def
copySelectedShape
(
self
):
def
copySelectedShape
(
self
):
...
@@ -1258,26 +1254,8 @@ class MainWindow(QMainWindow, WindowMixin):
...
@@ -1258,26 +1254,8 @@ class MainWindow(QMainWindow, WindowMixin):
# if unicodeFilePath in self.mImgList:
# if unicodeFilePath in self.mImgList:
if
unicodeFilePath
and
os
.
path
.
exists
(
unicodeFilePath
):
if
unicodeFilePath
and
os
.
path
.
exists
(
unicodeFilePath
):
if
LabelFile
.
isLabelFile
(
unicodeFilePath
):
self
.
imageData
=
read
(
unicodeFilePath
,
None
)
try
:
self
.
canvas
.
verified
=
False
self
.
labelFile
=
LabelFile
(
unicodeFilePath
)
except
LabelFileError
as
e
:
self
.
errorMessage
(
u
'Error opening file'
,
(
u
"<p><b>%s</b></p>"
u
"<p>Make sure <i>%s</i> is a valid label file."
)
%
(
e
,
unicodeFilePath
))
self
.
status
(
"Error reading %s"
%
unicodeFilePath
)
return
False
self
.
imageData
=
self
.
labelFile
.
imageData
self
.
lineColor
=
QColor
(
*
self
.
labelFile
.
lineColor
)
self
.
fillColor
=
QColor
(
*
self
.
labelFile
.
fillColor
)
self
.
canvas
.
verified
=
self
.
labelFile
.
verified
else
:
# Load image:
# read data first and store for saving into label file.
self
.
imageData
=
read
(
unicodeFilePath
,
None
)
self
.
labelFile
=
None
self
.
canvas
.
verified
=
False
image
=
QImage
.
fromData
(
self
.
imageData
)
image
=
QImage
.
fromData
(
self
.
imageData
)
if
image
.
isNull
():
if
image
.
isNull
():
...
@@ -1289,8 +1267,7 @@ class MainWindow(QMainWindow, WindowMixin):
...
@@ -1289,8 +1267,7 @@ class MainWindow(QMainWindow, WindowMixin):
self
.
image
=
image
self
.
image
=
image
self
.
filePath
=
unicodeFilePath
self
.
filePath
=
unicodeFilePath
self
.
canvas
.
loadPixmap
(
QPixmap
.
fromImage
(
image
))
self
.
canvas
.
loadPixmap
(
QPixmap
.
fromImage
(
image
))
if
self
.
labelFile
:
self
.
loadLabels
(
self
.
labelFile
.
shapes
)
if
self
.
validFilestate
(
filePath
)
is
True
:
if
self
.
validFilestate
(
filePath
)
is
True
:
self
.
setClean
()
self
.
setClean
()
else
:
else
:
...
@@ -1491,23 +1468,6 @@ class MainWindow(QMainWindow, WindowMixin):
...
@@ -1491,23 +1468,6 @@ class MainWindow(QMainWindow, WindowMixin):
self
.
reRecogButton
.
setEnabled
(
True
)
self
.
reRecogButton
.
setEnabled
(
True
)
self
.
actions
.
saveLabel
.
setEnabled
(
True
)
self
.
actions
.
saveLabel
.
setEnabled
(
True
)
def
verifyImg
(
self
,
_value
=
False
):
# Proceding next image without dialog if having any label
if
self
.
filePath
is
not
None
:
try
:
self
.
labelFile
.
toggleVerify
()
except
AttributeError
:
# If the labelling file does not exist yet, create if and
# re-save it with the verified attribute.
self
.
saveFile
()
if
self
.
labelFile
!=
None
:
self
.
labelFile
.
toggleVerify
()
else
:
return
self
.
canvas
.
verified
=
self
.
labelFile
.
verified
self
.
paintCanvas
()
self
.
saveFile
()
def
openPrevImg
(
self
,
_value
=
False
):
def
openPrevImg
(
self
,
_value
=
False
):
if
len
(
self
.
mImgList
)
<=
0
:
if
len
(
self
.
mImgList
)
<=
0
:
...
@@ -1580,18 +1540,10 @@ class MainWindow(QMainWindow, WindowMixin):
...
@@ -1580,18 +1540,10 @@ class MainWindow(QMainWindow, WindowMixin):
def
saveFile
(
self
,
_value
=
False
,
mode
=
'Manual'
):
def
saveFile
(
self
,
_value
=
False
,
mode
=
'Manual'
):
# Manual mode is used for users click "Save" manually,which will change the state of the image
# Manual mode is used for users click "Save" manually,which will change the state of the image
if
self
.
defaultSaveDir
is
not
None
and
len
(
ustr
(
self
.
defaultSaveDir
)):
if
self
.
filePath
:
if
self
.
filePath
:
imgidx
=
self
.
getImglabelidx
(
self
.
filePath
)
imgidx
=
self
.
getImglabelidx
(
self
.
filePath
)
self
.
_saveFile
(
imgidx
,
mode
=
mode
)
self
.
_saveFile
(
imgidx
,
mode
=
mode
)
else
:
imgFileDir
=
os
.
path
.
dirname
(
self
.
filePath
)
imgFileName
=
os
.
path
.
basename
(
self
.
filePath
)
savedFileName
=
os
.
path
.
splitext
(
imgFileName
)[
0
]
savedPath
=
os
.
path
.
join
(
imgFileDir
,
savedFileName
)
self
.
_saveFile
(
savedPath
if
self
.
labelFile
else
self
.
saveFileDialog
(
removeExt
=
False
),
mode
=
mode
)
def
saveFileAs
(
self
,
_value
=
False
):
def
saveFileAs
(
self
,
_value
=
False
):
assert
not
self
.
image
.
isNull
(),
"cannot save empty image"
assert
not
self
.
image
.
isNull
(),
"cannot save empty image"
...
...
PPOCRLabel/libs/labelFile.py
已删除
100644 → 0
浏览文件 @
f45bdf5b
# Copyright (c) 2016 Tzutalin
# Create by TzuTaLin <tzu.ta.lin@gmail.com>
try
:
from
PyQt5.QtGui
import
QImage
except
ImportError
:
from
PyQt4.QtGui
import
QImage
from
base64
import
b64encode
,
b64decode
from
libs.pascal_voc_io
import
PascalVocWriter
from
libs.yolo_io
import
YOLOWriter
from
libs.pascal_voc_io
import
XML_EXT
from
enum
import
Enum
import
os.path
import
sys
class
LabelFileFormat
(
Enum
):
PASCAL_VOC
=
1
YOLO
=
2
class
LabelFileError
(
Exception
):
pass
class
LabelFile
(
object
):
# It might be changed as window creates. By default, using XML ext
# suffix = '.lif'
suffix
=
XML_EXT
def
__init__
(
self
,
filename
=
None
):
self
.
shapes
=
()
self
.
imagePath
=
None
self
.
imageData
=
None
self
.
verified
=
False
def
savePascalVocFormat
(
self
,
filename
,
shapes
,
imagePath
,
imageData
,
lineColor
=
None
,
fillColor
=
None
,
databaseSrc
=
None
):
imgFolderPath
=
os
.
path
.
dirname
(
imagePath
)
imgFolderName
=
os
.
path
.
split
(
imgFolderPath
)[
-
1
]
imgFileName
=
os
.
path
.
basename
(
imagePath
)
#imgFileNameWithoutExt = os.path.splitext(imgFileName)[0]
# Read from file path because self.imageData might be empty if saving to
# Pascal format
image
=
QImage
()
image
.
load
(
imagePath
)
imageShape
=
[
image
.
height
(),
image
.
width
(),
1
if
image
.
isGrayscale
()
else
3
]
writer
=
PascalVocWriter
(
imgFolderName
,
imgFileName
,
imageShape
,
localImgPath
=
imagePath
)
writer
.
verified
=
self
.
verified
for
shape
in
shapes
:
points
=
shape
[
'points'
]
label
=
shape
[
'label'
]
# Add Chris
difficult
=
int
(
shape
[
'difficult'
])
bndbox
=
LabelFile
.
convertPoints2BndBox
(
points
)
writer
.
addBndBox
(
bndbox
[
0
],
bndbox
[
1
],
bndbox
[
2
],
bndbox
[
3
],
label
,
difficult
)
writer
.
save
(
targetFile
=
filename
)
return
def
saveYoloFormat
(
self
,
filename
,
shapes
,
imagePath
,
imageData
,
classList
,
lineColor
=
None
,
fillColor
=
None
,
databaseSrc
=
None
):
imgFolderPath
=
os
.
path
.
dirname
(
imagePath
)
imgFolderName
=
os
.
path
.
split
(
imgFolderPath
)[
-
1
]
imgFileName
=
os
.
path
.
basename
(
imagePath
)
#imgFileNameWithoutExt = os.path.splitext(imgFileName)[0]
# Read from file path because self.imageData might be empty if saving to
# Pascal format
image
=
QImage
()
image
.
load
(
imagePath
)
imageShape
=
[
image
.
height
(),
image
.
width
(),
1
if
image
.
isGrayscale
()
else
3
]
writer
=
YOLOWriter
(
imgFolderName
,
imgFileName
,
imageShape
,
localImgPath
=
imagePath
)
writer
.
verified
=
self
.
verified
for
shape
in
shapes
:
points
=
shape
[
'points'
]
label
=
shape
[
'label'
]
# Add Chris
difficult
=
int
(
shape
[
'difficult'
])
bndbox
=
LabelFile
.
convertPoints2BndBox
(
points
)
writer
.
addBndBox
(
bndbox
[
0
],
bndbox
[
1
],
bndbox
[
2
],
bndbox
[
3
],
label
,
difficult
)
writer
.
save
(
targetFile
=
filename
,
classList
=
classList
)
return
def
toggleVerify
(
self
):
self
.
verified
=
not
self
.
verified
''' ttf is disable
def load(self, filename):
import json
with open(filename, 'rb') as f:
data = json.load(f)
imagePath = data['imagePath']
imageData = b64decode(data['imageData'])
lineColor = data['lineColor']
fillColor = data['fillColor']
shapes = ((s['label'], s['points'], s['line_color'], s['fill_color'])
\
for s in data['shapes'])
# Only replace data after everything is loaded.
self.shapes = shapes
self.imagePath = imagePath
self.imageData = imageData
self.lineColor = lineColor
self.fillColor = fillColor
def save(self, filename, shapes, imagePath, imageData, lineColor=None, fillColor=None):
import json
with open(filename, 'wb') as f:
json.dump(dict(
shapes=shapes,
lineColor=lineColor, fillColor=fillColor,
imagePath=imagePath,
imageData=b64encode(imageData)),
f, ensure_ascii=True, indent=2)
'''
@
staticmethod
def
isLabelFile
(
filename
):
fileSuffix
=
os
.
path
.
splitext
(
filename
)[
1
].
lower
()
return
fileSuffix
==
LabelFile
.
suffix
@
staticmethod
def
convertPoints2BndBox
(
points
):
xmin
=
float
(
'inf'
)
ymin
=
float
(
'inf'
)
xmax
=
float
(
'-inf'
)
ymax
=
float
(
'-inf'
)
for
p
in
points
:
x
=
p
[
0
]
y
=
p
[
1
]
xmin
=
min
(
x
,
xmin
)
ymin
=
min
(
y
,
ymin
)
xmax
=
max
(
x
,
xmax
)
ymax
=
max
(
y
,
ymax
)
# Martin Kersner, 2015/11/12
# 0-valued coordinates of BB caused an error while
# training faster-rcnn object detector.
if
xmin
<
1
:
xmin
=
1
if
ymin
<
1
:
ymin
=
1
return
(
int
(
xmin
),
int
(
ymin
),
int
(
xmax
),
int
(
ymax
))
PPOCRLabel/libs/pascal_voc_io.py
已删除
100644 → 0
浏览文件 @
f45bdf5b
# Copyright (c) <2015-Present> Tzutalin
# Copyright (C) 2013 MIT, Computer Science and Artificial Intelligence Laboratory. Bryan Russell, Antonio Torralba,
# William T. Freeman. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
# associated documentation files (the "Software"), to deal in the Software without restriction, including without
# limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
# Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all copies or substantial portions of
# the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
# CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#!/usr/bin/env python
# -*- coding: utf8 -*-
import
sys
from
xml.etree
import
ElementTree
from
xml.etree.ElementTree
import
Element
,
SubElement
from
lxml
import
etree
import
codecs
from
libs.constants
import
DEFAULT_ENCODING
from
libs.ustr
import
ustr
XML_EXT
=
'.xml'
ENCODE_METHOD
=
DEFAULT_ENCODING
class
PascalVocWriter
:
def
__init__
(
self
,
foldername
,
filename
,
imgSize
,
databaseSrc
=
'Unknown'
,
localImgPath
=
None
):
self
.
foldername
=
foldername
self
.
filename
=
filename
self
.
databaseSrc
=
databaseSrc
self
.
imgSize
=
imgSize
self
.
boxlist
=
[]
self
.
localImgPath
=
localImgPath
self
.
verified
=
False
def
prettify
(
self
,
elem
):
"""
Return a pretty-printed XML string for the Element.
"""
rough_string
=
ElementTree
.
tostring
(
elem
,
'utf8'
)
root
=
etree
.
fromstring
(
rough_string
)
return
etree
.
tostring
(
root
,
pretty_print
=
True
,
encoding
=
ENCODE_METHOD
).
replace
(
" "
.
encode
(),
"
\t
"
.
encode
())
# minidom does not support UTF-8
'''reparsed = minidom.parseString(rough_string)
return reparsed.toprettyxml(indent="
\t
", encoding=ENCODE_METHOD)'''
def
genXML
(
self
):
"""
Return XML root
"""
# Check conditions
if
self
.
filename
is
None
or
\
self
.
foldername
is
None
or
\
self
.
imgSize
is
None
:
return
None
top
=
Element
(
'annotation'
)
if
self
.
verified
:
top
.
set
(
'verified'
,
'yes'
)
folder
=
SubElement
(
top
,
'folder'
)
folder
.
text
=
self
.
foldername
filename
=
SubElement
(
top
,
'filename'
)
filename
.
text
=
self
.
filename
if
self
.
localImgPath
is
not
None
:
localImgPath
=
SubElement
(
top
,
'path'
)
localImgPath
.
text
=
self
.
localImgPath
source
=
SubElement
(
top
,
'source'
)
database
=
SubElement
(
source
,
'database'
)
database
.
text
=
self
.
databaseSrc
size_part
=
SubElement
(
top
,
'size'
)
width
=
SubElement
(
size_part
,
'width'
)
height
=
SubElement
(
size_part
,
'height'
)
depth
=
SubElement
(
size_part
,
'depth'
)
width
.
text
=
str
(
self
.
imgSize
[
1
])
height
.
text
=
str
(
self
.
imgSize
[
0
])
if
len
(
self
.
imgSize
)
==
3
:
depth
.
text
=
str
(
self
.
imgSize
[
2
])
else
:
depth
.
text
=
'1'
segmented
=
SubElement
(
top
,
'segmented'
)
segmented
.
text
=
'0'
return
top
def
addBndBox
(
self
,
xmin
,
ymin
,
xmax
,
ymax
,
name
,
difficult
):
bndbox
=
{
'xmin'
:
xmin
,
'ymin'
:
ymin
,
'xmax'
:
xmax
,
'ymax'
:
ymax
}
bndbox
[
'name'
]
=
name
bndbox
[
'difficult'
]
=
difficult
self
.
boxlist
.
append
(
bndbox
)
def
appendObjects
(
self
,
top
):
for
each_object
in
self
.
boxlist
:
object_item
=
SubElement
(
top
,
'object'
)
name
=
SubElement
(
object_item
,
'name'
)
name
.
text
=
ustr
(
each_object
[
'name'
])
pose
=
SubElement
(
object_item
,
'pose'
)
pose
.
text
=
"Unspecified"
truncated
=
SubElement
(
object_item
,
'truncated'
)
if
int
(
float
(
each_object
[
'ymax'
]))
==
int
(
float
(
self
.
imgSize
[
0
]))
or
(
int
(
float
(
each_object
[
'ymin'
]))
==
1
):
truncated
.
text
=
"1"
# max == height or min
elif
(
int
(
float
(
each_object
[
'xmax'
]))
==
int
(
float
(
self
.
imgSize
[
1
])))
or
(
int
(
float
(
each_object
[
'xmin'
]))
==
1
):
truncated
.
text
=
"1"
# max == width or min
else
:
truncated
.
text
=
"0"
difficult
=
SubElement
(
object_item
,
'difficult'
)
difficult
.
text
=
str
(
bool
(
each_object
[
'difficult'
])
&
1
)
bndbox
=
SubElement
(
object_item
,
'bndbox'
)
xmin
=
SubElement
(
bndbox
,
'xmin'
)
xmin
.
text
=
str
(
each_object
[
'xmin'
])
ymin
=
SubElement
(
bndbox
,
'ymin'
)
ymin
.
text
=
str
(
each_object
[
'ymin'
])
xmax
=
SubElement
(
bndbox
,
'xmax'
)
xmax
.
text
=
str
(
each_object
[
'xmax'
])
ymax
=
SubElement
(
bndbox
,
'ymax'
)
ymax
.
text
=
str
(
each_object
[
'ymax'
])
def
save
(
self
,
targetFile
=
None
):
root
=
self
.
genXML
()
self
.
appendObjects
(
root
)
out_file
=
None
if
targetFile
is
None
:
out_file
=
codecs
.
open
(
self
.
filename
+
XML_EXT
,
'w'
,
encoding
=
ENCODE_METHOD
)
else
:
out_file
=
codecs
.
open
(
targetFile
,
'w'
,
encoding
=
ENCODE_METHOD
)
prettifyResult
=
self
.
prettify
(
root
)
out_file
.
write
(
prettifyResult
.
decode
(
'utf8'
))
out_file
.
close
()
class
PascalVocReader
:
def
__init__
(
self
,
filepath
):
# shapes type:
# [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult]
self
.
shapes
=
[]
self
.
filepath
=
filepath
self
.
verified
=
False
try
:
self
.
parseXML
()
except
:
pass
def
getShapes
(
self
):
return
self
.
shapes
def
addShape
(
self
,
label
,
bndbox
,
difficult
):
xmin
=
int
(
float
(
bndbox
.
find
(
'xmin'
).
text
))
ymin
=
int
(
float
(
bndbox
.
find
(
'ymin'
).
text
))
xmax
=
int
(
float
(
bndbox
.
find
(
'xmax'
).
text
))
ymax
=
int
(
float
(
bndbox
.
find
(
'ymax'
).
text
))
points
=
[(
xmin
,
ymin
),
(
xmax
,
ymin
),
(
xmax
,
ymax
),
(
xmin
,
ymax
)]
self
.
shapes
.
append
((
label
,
points
,
None
,
None
,
difficult
))
def
parseXML
(
self
):
assert
self
.
filepath
.
endswith
(
XML_EXT
),
"Unsupport file format"
parser
=
etree
.
XMLParser
(
encoding
=
ENCODE_METHOD
)
xmltree
=
ElementTree
.
parse
(
self
.
filepath
,
parser
=
parser
).
getroot
()
filename
=
xmltree
.
find
(
'filename'
).
text
try
:
verified
=
xmltree
.
attrib
[
'verified'
]
if
verified
==
'yes'
:
self
.
verified
=
True
except
KeyError
:
self
.
verified
=
False
for
object_iter
in
xmltree
.
findall
(
'object'
):
bndbox
=
object_iter
.
find
(
"bndbox"
)
label
=
object_iter
.
find
(
'name'
).
text
# Add chris
difficult
=
False
if
object_iter
.
find
(
'difficult'
)
is
not
None
:
difficult
=
bool
(
int
(
object_iter
.
find
(
'difficult'
).
text
))
self
.
addShape
(
label
,
bndbox
,
difficult
)
return
True
PPOCRLabel/libs/yolo_io.py
已删除
100644 → 0
浏览文件 @
f45bdf5b
#!/usr/bin/env python
# -*- coding: utf8 -*-
import
sys
import
os
from
xml.etree
import
ElementTree
from
xml.etree.ElementTree
import
Element
,
SubElement
from
lxml
import
etree
import
codecs
from
libs.constants
import
DEFAULT_ENCODING
TXT_EXT
=
'.txt'
ENCODE_METHOD
=
DEFAULT_ENCODING
class
YOLOWriter
:
def
__init__
(
self
,
foldername
,
filename
,
imgSize
,
databaseSrc
=
'Unknown'
,
localImgPath
=
None
):
self
.
foldername
=
foldername
self
.
filename
=
filename
self
.
databaseSrc
=
databaseSrc
self
.
imgSize
=
imgSize
self
.
boxlist
=
[]
self
.
localImgPath
=
localImgPath
self
.
verified
=
False
def
addBndBox
(
self
,
xmin
,
ymin
,
xmax
,
ymax
,
name
,
difficult
):
bndbox
=
{
'xmin'
:
xmin
,
'ymin'
:
ymin
,
'xmax'
:
xmax
,
'ymax'
:
ymax
}
bndbox
[
'name'
]
=
name
bndbox
[
'difficult'
]
=
difficult
self
.
boxlist
.
append
(
bndbox
)
def
BndBox2YoloLine
(
self
,
box
,
classList
=
[]):
xmin
=
box
[
'xmin'
]
xmax
=
box
[
'xmax'
]
ymin
=
box
[
'ymin'
]
ymax
=
box
[
'ymax'
]
xcen
=
float
((
xmin
+
xmax
))
/
2
/
self
.
imgSize
[
1
]
ycen
=
float
((
ymin
+
ymax
))
/
2
/
self
.
imgSize
[
0
]
w
=
float
((
xmax
-
xmin
))
/
self
.
imgSize
[
1
]
h
=
float
((
ymax
-
ymin
))
/
self
.
imgSize
[
0
]
# PR387
boxName
=
box
[
'name'
]
if
boxName
not
in
classList
:
classList
.
append
(
boxName
)
classIndex
=
classList
.
index
(
boxName
)
return
classIndex
,
xcen
,
ycen
,
w
,
h
def
save
(
self
,
classList
=
[],
targetFile
=
None
):
out_file
=
None
#Update yolo .txt
out_class_file
=
None
#Update class list .txt
if
targetFile
is
None
:
out_file
=
open
(
self
.
filename
+
TXT_EXT
,
'w'
,
encoding
=
ENCODE_METHOD
)
classesFile
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
self
.
filename
)),
"classes.txt"
)
out_class_file
=
open
(
classesFile
,
'w'
)
else
:
out_file
=
codecs
.
open
(
targetFile
,
'w'
,
encoding
=
ENCODE_METHOD
)
classesFile
=
os
.
path
.
join
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
targetFile
)),
"classes.txt"
)
out_class_file
=
open
(
classesFile
,
'w'
)
for
box
in
self
.
boxlist
:
classIndex
,
xcen
,
ycen
,
w
,
h
=
self
.
BndBox2YoloLine
(
box
,
classList
)
# print (classIndex, xcen, ycen, w, h)
out_file
.
write
(
"%d %.6f %.6f %.6f %.6f
\n
"
%
(
classIndex
,
xcen
,
ycen
,
w
,
h
))
# print (classList)
# print (out_class_file)
for
c
in
classList
:
out_class_file
.
write
(
c
+
'
\n
'
)
out_class_file
.
close
()
out_file
.
close
()
class
YoloReader
:
def
__init__
(
self
,
filepath
,
image
,
classListPath
=
None
):
# shapes type:
# [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult]
self
.
shapes
=
[]
self
.
filepath
=
filepath
if
classListPath
is
None
:
dir_path
=
os
.
path
.
dirname
(
os
.
path
.
realpath
(
self
.
filepath
))
self
.
classListPath
=
os
.
path
.
join
(
dir_path
,
"classes.txt"
)
else
:
self
.
classListPath
=
classListPath
# print (filepath, self.classListPath)
classesFile
=
open
(
self
.
classListPath
,
'r'
)
self
.
classes
=
classesFile
.
read
().
strip
(
'
\n
'
).
split
(
'
\n
'
)
# print (self.classes)
imgSize
=
[
image
.
height
(),
image
.
width
(),
1
if
image
.
isGrayscale
()
else
3
]
self
.
imgSize
=
imgSize
self
.
verified
=
False
# try:
self
.
parseYoloFormat
()
# except:
# pass
def
getShapes
(
self
):
return
self
.
shapes
def
addShape
(
self
,
label
,
xmin
,
ymin
,
xmax
,
ymax
,
difficult
):
points
=
[(
xmin
,
ymin
),
(
xmax
,
ymin
),
(
xmax
,
ymax
),
(
xmin
,
ymax
)]
self
.
shapes
.
append
((
label
,
points
,
None
,
None
,
difficult
))
def
yoloLine2Shape
(
self
,
classIndex
,
xcen
,
ycen
,
w
,
h
):
label
=
self
.
classes
[
int
(
classIndex
)]
xmin
=
max
(
float
(
xcen
)
-
float
(
w
)
/
2
,
0
)
xmax
=
min
(
float
(
xcen
)
+
float
(
w
)
/
2
,
1
)
ymin
=
max
(
float
(
ycen
)
-
float
(
h
)
/
2
,
0
)
ymax
=
min
(
float
(
ycen
)
+
float
(
h
)
/
2
,
1
)
xmin
=
int
(
self
.
imgSize
[
1
]
*
xmin
)
xmax
=
int
(
self
.
imgSize
[
1
]
*
xmax
)
ymin
=
int
(
self
.
imgSize
[
0
]
*
ymin
)
ymax
=
int
(
self
.
imgSize
[
0
]
*
ymax
)
return
label
,
xmin
,
ymin
,
xmax
,
ymax
def
parseYoloFormat
(
self
):
bndBoxFile
=
open
(
self
.
filepath
,
'r'
)
for
bndBox
in
bndBoxFile
:
classIndex
,
xcen
,
ycen
,
w
,
h
=
bndBox
.
strip
().
split
(
' '
)
label
,
xmin
,
ymin
,
xmax
,
ymax
=
self
.
yoloLine2Shape
(
classIndex
,
xcen
,
ycen
,
w
,
h
)
# Caveat: difficult flag is discarded when saved as yolo format.
self
.
addShape
(
label
,
xmin
,
ymin
,
xmax
,
ymax
,
False
)
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录