『自己的工作7』依据多边形的顶点信息生成多边形mask(Python实现)!

it2024-04-19  48

依据多边形的顶点信息生成多边形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): # 用来保存解析出来的xlsx文件目录 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", "") # 把后缀中的.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') # json文件; 转换的结果如下: [{"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) ##### shape(多边形的点, 2) 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 # 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提取每篇文章的标题,副标题,作者,正文。
最新回复(0)