【python基础】eval的使用
前言
开发的时候,遇到一个标注的json文件中多边形的框的表示,一时忘记不知道如何解析,此处主要使用eval函数,故记录之。
json文件多边形框的描述
"result": [ { "tagtype": "circle_green", "obstructed": false, "labelId": 1, "data": "[[\"M\",475.7550000000001,362.453],[\"L\",476.69799999999987,383.6790000000001],[\"L\",485.18899999999985,383.2080000000001],[\"L\",484.7170000000001,361.981],[\"Z\"]]" }, { "tagtype": "circle_green", "obstructed": false, "labelId": 2, "data": "[[\"M\",561.1320000000001,361.509],[\"L\",562.547,383.2080000000001],[\"L\",570.5659999999998,382.7360000000001],[\"L\",569.623,361.038],[\"Z\"]]" } ]
其中,
bbox是xywh格式的;
带mlz的是由点组成的线;
是否有z代表是否是闭合图形;
有的是末尾有两个z,和一个z表示的意思一样
解析
def parse_data(data): if isinstance(data, str): data = eval(data) assert isinstance(data, list) if isinstance(data[0], list): pts = [] for i, d in enumerate(data): if d[0] != 'Z': pts.append(d[1:]) # remove 'M' if len(pts) == 1: return pts[0], 'point' if data[-1][0] == 'Z': return pts, 'area' return pts, 'line' else: if len(data) == 4: return data, 'bbox' #xywh else: warnings.warn('3d bbox not supported yet')
具体地

>>> a=eval("[[\"M\",560.9090000000001,361.818],[\"L\",569.6970000000001,361.818],[\"L\",569.6970000000001,383.3330000000001],[\"L\",561.5149999999999,383.9390000000001],[\"Z\"]]") >>> a[0] ['M', 560.9090000000001, 361.818] >>> len(a) 5 >>> a[4] ['Z'] >>> b=[] >>> b.append(a[0][1:]) >>> b.append(a[1][1:]) >>> b [[560.9090000000001, 361.818], [569.6970000000001, 361.818]] >>> b.append(a[3][1:]) >>> b.append(a[2][1:]) >>> b [[560.9090000000001, 361.818], [569.6970000000001, 361.818], [561.5149999999999, 383.9390000000001], [569.6970000000001, 383.3330000000001]]
code: json2label.py

import argparse import json import os import os.path as osp json_dir = "./" imgw = 1280 imgh = 720 imgsz = imgw, imgh tfl_label = {'circle_green':0, 'circle_red':1, 'circle_yellow':2, 'left_green':3, 'left_red':4, 'left_yellow':5, 'nomotor_green':6, 'nomotor_red':7, 'nomotor_yellow':8, 'off':9} def get_bbox(size, box): # Convert xyxy box to YOLOv5 xywh box dw = 1. / size[0] dh = 1. / size[1] xc = (box[0] + box[2])*0.5*dw yc = (box[1] + box[3])*0.5*dh w = (box[2]-box[0])*dw h = (box[3]-box[1])*dh return xc, yc, w, h def get_minrect(points, size): len_pts = len(points) x_min = size[0] # image width y_min = size[1] # image height x_max = 0 y_max = 0 for i in range(len_pts): # print("points: ", points) if points[i][0] < x_min: x_min = points[i][0] if points[i][1] < y_min: y_min = points[i][1] if points[i][0] > x_max: x_max = points[i][0] if points[i][1] > y_max: y_max = points[i][1] return x_min, y_min, x_max, y_max def parse_data(data): if isinstance(data, str): data = eval(data) assert isinstance(data, list) if isinstance(data[0], list): pts = [] for i, d in enumerate(data): if d[0] != 'Z': pts.append(d[1:]) # remove 'M' if len(pts) == 1: return pts[0], 'point' if data[-1][0] == 'Z': return pts, 'area' return pts, 'line' else: if len(data) == 4: return data, 'bbox' else: warnings.warn('3d bbox not supported yet') def parse_json(filename, dataset): labeldir = filename.split("_")[0] # print("labeldir: ", labeldir) if not osp.exists(osp.join(json_dir, labeldir)): os.mkdir(labeldir) k=0 for data in dataset: # k+=1 # if k==2: # break # data = dataset[i] count = data['label_count'] imagename = data['file_obj'] name = osp.split(imagename)[-1].replace('png', 'txt') labelname = osp.join(labeldir, name) # print('labelname: ', labelname) labelfile = open(labelname, 'w+') for res in data['result']: tagtype = res['tagtype'] points = parse_data(res['data'])[0] # print('points: ', points) if len(points)<4: print('labelname: ', labelname) continue classid = tfl_label[tagtype] rect = get_minrect(points, imgsz) bbox = get_bbox(imgsz, rect) if bbox[2]*imgsz[0] < 5: print('this image tfl width less than 5:{}\t{}\t{}\n'.format(name, bbox[2]*imgsz[0], bbox[3]*imgsz[1])) if bbox[3]*imgsz[1] < 12: print('this image tfl height less than 10:{}\t{}\t{}\n'.format(name, bbox[2]*imgsz[0], bbox[3]*imgsz[1])) info = f"{classid} {' '.join(f'{x:.6f}' for x in bbox)}\n" labelfile.write(info) labelfile.close() def main(): jsonfiles = os.listdir(json_dir) for i in range(0, len(jsonfiles)): path = os.path.join(json_dir, jsonfiles[i]) # print("path: ", jsonfiles[i]) if os.path.isfile(path) and path.endswith('json'): dataset = json.load(open(path)) num = len(dataset) # print("dataset number: ", num) parse_json(jsonfiles[i], dataset) if __name__ == '__main__': main()
参考
1. Python:eval函数 - 概念、用法、注意事项;
完
各美其美,美美与共,不和他人作比较,不对他人有期待,不批判他人,不钻牛角尖。
心正意诚,做自己该做的事情,做自己喜欢做的事情,安静做一枚有思想的技术媛。
版权声明,转载请注明出处:https://www.cnblogs.com/happyamyhope/
心正意诚,做自己该做的事情,做自己喜欢做的事情,安静做一枚有思想的技术媛。
版权声明,转载请注明出处:https://www.cnblogs.com/happyamyhope/
分类:
python
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
2019-03-27 win10安装ubuntu16.04双系统