依据多边形的顶点信息生成多边形mask(Python实现)!
文章目录
一. 安装labelme标定数据集1.1. 安装labelme1.2. 启动labelme标定
二. 报纸版面使用labelme打标2.1. 转换json文件2.2. 多边形mask标定
一. 安装labelme标定数据集
1.1. 安装labelme
首先安装一下Anaconda,然后创建一个python3.6的环境。命令如下:
conda create -n lableme python
=3.6
然后pip安装lableme:
pip
install labelme
1.2. 启动labelme标定
标记好之后,会出现一个json文件,内容大致如下:
{
"version": "4.5.6",
"flags": {},
"shapes": [
{
"label": "1",
"points": [
[
408.7391304347826,
173.91304347826087
],
[
2404.391304347826,
173.91304347826087
],
[
2402.2173913043475,
1258.695652173913
],
[
415.2608695652174,
1256.5217391304348
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "2",
"points": [
[
41.3478260869565,
182.6086956521739
],
[
400.0434782608695,
184.78260869565216
],
[
400.0434782608695,
2176.086956521739
],
[
39.17391304347825,
2167.391304347826
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "3",
"points": [
[
408.7391304347826,
1289.1304347826087
],
[
1887.0,
1293.4782608695652
],
[
1882.6521739130435,
2171.7391304347825
],
[
430.47826086956513,
2165.2173913043475
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "4",
"points": [
[
1913.086956521739,
1306.5217391304348
],
[
2408.7391304347825,
1308.695652173913
],
[
2404.391304347826,
2230.4347826086955
],
[
1904.391304347826,
2228.2608695652175
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "5",
"points": [
[
21.782608695652186,
2204.3478260869565
],
[
421.78260869565213,
2206.5217391304345
],
[
423.9565217391304,
2717.391304347826
],
[
23.956521739130437,
2717.391304347826
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "6",
"points": [
[
443.52173913043475,
2202.173913043478
],
[
1882.6521739130435,
2202.173913043478
],
[
1878.304347826087,
2728.2608695652175
],
[
437.0,
2721.7391304347825
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "7",
"points": [
[
1904.391304347826,
2271.7391304347825
],
[
2410.9130434782605,
2271.7391304347825
],
[
2404.391304347826,
2758.695652173913
],
[
1902.2173913043475,
2756.5217391304345
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "8",
"points": [
[
17.434782608695627,
2758.695652173913
],
[
421.78260869565213,
2756.5217391304345
],
[
421.78260869565213,
3454.3478260869565
],
[
15.260869565217376,
3454.3478260869565
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "9",
"points": [
[
443.52173913043475,
2750.0
],
[
1834.8260869565215,
2747.8260869565215
],
[
1834.8260869565215,
2971.7391304347825
],
[
1037.0,
2969.565217391304
],
[
1030.4782608695652,
3447.8260869565215
],
[
441.3478260869565,
3447.8260869565215
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "10",
"points": [
[
1060.9130434782608,
2991.304347826087
],
[
1880.478260869565,
2993.478260869565
],
[
1876.1304347826085,
3452.173913043478
],
[
1047.8695652173913,
3443.478260869565
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
},
{
"label": "11",
"points": [
[
1900.0434782608695,
2786.9565217391305
],
[
2415.2608695652175,
2791.304347826087
],
[
2408.7391304347825,
3439.1304347826085
],
[
1895.695652173913,
3432.6086956521735
]
],
"group_id": null,
"shape_type": "polygon",
"flags": {}
}
],
"imagePath": "NBRB20110101A01.png",
"imageData": "iVBORwmJ7I/wMfjEpe3nT0pwAAAABJRU5ErkJggg==",
"imageHeight": 1469,
"imageWidth": 1027
}
二. 报纸版面使用labelme打标
2.1. 转换json文件
上面的标记json文件进行内容提取,转换为另一个json文件:
import numpy
as np
import os
import json
import io
import PIL
.Image
"""
这部分代码的功能就是从labelme标记好的JSON文件中,提取有用的坐标位置信息等。然后保存到另一个json文件。
这部分内容参考了博客: https://blog.csdn.net/longzhinuhou/article/details/86634949
"""
def shapes_to_label(json_file_path
, savaFile
):
if not os
.path
.exists
(savaFile
):
os
.mkdir
(savaFile
)
list_path
= os
.listdir
(json_file_path
)
for i
in range(0, len(list_path
)):
path
= os
.path
.join
(json_file_path
, list_path
[i
])
file_name
= list_path
[i
].replace
(".json", "")
file_name_path
= os
.path
.join
(savaFile
, file_name
)
contents
= []
file_handle
= open(file_name_path
+'.json', mode
='w')
if os
.path
.isfile
(path
):
with open(path
, 'r', encoding
='utf-8') as load_f
:
strF
= load_f
.read
()
if len(strF
) > 0:
data
= json
.loads
(strF
)
for shape
in data
['shapes']:
label_name
= shape
['label']
polygons
= shape
['points']
contents
.append
({'name': file_name
, 'label': label_name
, 'points': polygons
})
else:
data
= {}
json
.dump
(contents
, file_handle
)
file_handle
.close
()
if __name__
== '__main__':
shapes_to_label
('./dataset/JSON_Labelme', './dataset/JSON_Processed')
转换的结果如下:
[{"name": "NBRB20110101A02",
"label": "1",
"points": [[408.7391304347826, 173.91304347826087
],
[2404.391304347826, 173.91304347826087
],
[2402.2173913043475, 1258.695652173913
],
[415.2608695652174, 1256.5217391304348
]]},
{"name": "NBRB20110101A02",
"label": "2",
"points": [[41.3478260869565, 182.6086956521739
],
[400.0434782608695, 184.78260869565216
],
[400.0434782608695, 2176.086956521739
],
[39.17391304347825, 2167.391304347826
]]},
{"name": "NBRB20110101A02",
"label": "3",
"points": [[408.7391304347826, 1289.1304347826087
],
[1887.0, 1293.4782608695652
],
[1882.6521739130435, 2171.7391304347825
],
[430.47826086956513, 2165.2173913043475
]]},
{"name": "NBRB20110101A02",
"label": "4",
"points": [[1913.086956521739, 1306.5217391304348
],
[2408.7391304347825, 1308.695652173913
],
[2404.391304347826, 2230.4347826086955
],
[1904.391304347826, 2228.2608695652175
]]},
{"name": "NBRB20110101A02",
"label": "5",
"points": [[21.782608695652186, 2204.3478260869565
],
[421.78260869565213, 2206.5217391304345
],
[423.9565217391304, 2717.391304347826
],
[23.956521739130437, 2717.391304347826
]]},
{"name": "NBRB20110101A02",
"label": "6",
"points": [[443.52173913043475, 2202.173913043478
],
[1882.6521739130435, 2202.173913043478
],
[1878.304347826087, 2728.2608695652175
],
[437.0, 2721.7391304347825
]]},
{"name": "NBRB20110101A02",
"label": "7",
"points": [[1904.391304347826, 2271.7391304347825
],
[2410.9130434782605, 2271.7391304347825
],
[2404.391304347826, 2758.695652173913
],
[1902.2173913043475, 2756.5217391304345
]]},
{"name": "NBRB20110101A02",
"label": "8",
"points": [[17.434782608695627, 2758.695652173913
],
[421.78260869565213, 2756.5217391304345
],
[421.78260869565213, 3454.3478260869565
],
[15.260869565217376, 3454.3478260869565
]]},
{"name": "NBRB20110101A02",
"label": "9",
"points": [[443.52173913043475, 2750.0
],
[1834.8260869565215, 2747.8260869565215
],
[1834.8260869565215, 2971.7391304347825
],
[1037.0, 2969.565217391304
],
[1030.4782608695652, 3447.8260869565215
],
[441.3478260869565, 3447.8260869565215
]]},
{"name": "NBRB20110101A02",
"label": "10",
"points": [[1060.9130434782608, 2991.304347826087
],
[1880.478260869565, 2993.478260869565
],
[1876.1304347826085, 3452.173913043478
],
[1047.8695652173913, 3443.478260869565
]]},
{"name": "NBRB20110101A02",
"label": "11",
"points": [[1900.0434782608695, 2786.9565217391305
],
[2415.2608695652175, 2791.304347826087
],
[2408.7391304347825, 3439.1304347826085
],
[1895.695652173913, 3432.6086956521735
]]}]
2.2. 多边形mask标定
进行多边形mask标定的时候,就是利用到了多边形的定点信息,这里由于一张图我划分了多个版面,我对每个版面分别天长不同的数值。代码如下:
import numpy as np
import json
import cv2
import os
import matplotlib.pyplot as plt
"""
@zhangkaifang 2020-10-22,本函数主要实现打开JSON_Processed文件,读取数据!
"""
def open_json
(filepath_json
):
data
= json.load
(open
(filepath_json
))
polygon_set
= []
for ele
in data:
polygon_set.append
([ele
['points'], ele
['label']])
return polygon_set
"""
@zhangkaifang 2020-10-23,这里是根据标签信息进行多边形mask标定, 这里的[1469,1027]是近似报纸pdf的尺寸大小!
"""
def draw_mask
(polygon_set
):
mask_all, i
= np.zeros
([3480,2433
], dtype
=np.uint8
), 0
for layout
in polygon_set:
data
= np.array
([layout
[0
]], dtype
=np.int32
)
label
= int
(layout
[1
])
im
= np.zeros
([3480,2433
], dtype
=np.uint8
)
cv2.fillPoly
(im, data, label
)
i
= i + 1
mask_all
= mask_all+im
plt.imshow
(mask_all
)
plt.show
()
return mask_all, i
def main
():
path_files
= '../dataset/JSON_Processed'
for file in os.listdir
(path_files
):
polygon_set
= open_json
(os.path.join
(path_files, file
))
mask_all, i
= draw_mask
(polygon_set
)
if __name__
== '__main__':
main
()
以上对每个多边形mask区域内填充了不同的数值。我实现这个的目的就是接下来对报纸进行版面分析!根据每个mask提取每篇文章的标题,副标题,作者,正文。