Yolov5多邊形標簽和JSON數(shù)據(jù)格式轉換
Labelme簡要介紹
通過labelme對圖進行標注后,得到的是json文件,而Yolov5對數(shù)據(jù)進行模型構建的時候,讀取需要的是txt格式的文件。所以需要先通過Python進行文件格式的轉換
注:labelme是麻省理工(MIT)的計算機科學和人工智能實驗室(CSAIL)研發(fā)的圖像標注工具,人們可以使用該工具創(chuàng)建定制化標注任務或執(zhí)行圖像標注,項目源代碼已經開源。
Labelme程序運行,通過標注后如圖所示:
圖1 Labelme標注
此圖片可以得到以下格式的json文件:
文件中的字段如下:
‘version’——版本號
‘shapes’——里面裝的是Yolov5需要的數(shù)據(jù)
‘label’——你在labelme里面設置的類
‘points’——點的坐標
我這里的label如圖1所示共有5類,等下進行json轉化為txt的時候用
對應這些類創(chuàng)一個字典以便json進行轉換
例:name2id={'bike':0,'arrow':1,'crossline':2,'building':3,'car':4,'person':5}
可能某一張圖片中可能不存在上述的某個類,所以這里請以某個json中最多的類創(chuàng)建這個字典。
多邊形標簽的處理方法
由于yolov5 僅支持矩形圖形的識別,所以需要通過數(shù)據(jù)處理,將多邊形變換為矩形。
處理原理:遍歷該標簽所有的坐標,獲取最大x_max,y_max,最小x_min,y_min的x和y的坐標。
然后再進行數(shù)據(jù)的規(guī)范化。
轉換后的txt格式如下:
第一個是類,比如第一行中的第一個數(shù)字是4,我的name2id中car也為4,即這里指代的就是'car'這個標簽。
第一行 第二個 和 第三個數(shù)字 為數(shù)字為圖片中心點(x,y)的坐標
第四個數(shù)字和第五個數(shù)字對應的是 這個標簽的 寬和高。
代碼實現(xiàn)
多邊形標簽代碼實現(xiàn)方法
x_max=0 y_max=0 x_min=100000 y_min=100000 for lk in range(len(i['points'])): x1=float(i['points'][lk][0]) y1=float(i['points'][lk][1]) # print(x1) if x_max<x1: x_max=x1 if y_max<y1: y_max=y1 if y_min>y1: y_min=y1 if x_min>x1: x_min=x1 bb = (x_min, y_max, x_max, y_min)
json轉化為txt的部分代碼如下:
def decode_json(json_floder_path,txt_outer_path, json_name): # json_floder_path='E:\\Python_package\\itesjson\\' # json_name='V1125.json' txt_name = txt_outer_path + json_name[:-5] + '.txt' with open(txt_name,'w') as f: json_path = os.path.join(json_floder_path, json_name)#os路徑融合 data = json.load(open(json_path, 'r', encoding='gb2312',errors='ignore')) img_w = data['imageWidth']#圖片的高 img_h = data['imageHeight']#圖片的寬 isshape_type=data['shapes'][0]['shape_type'] print(isshape_type) #print(isshape_type) #print('下方判斷根據(jù)這里的值可以設置為你自己的類型,我這里是polygon'多邊形) #len(data['shapes']) for i in data['shapes']: label_name = i['label']#得到json中你標記的類名 if (i['shape_type'] == 'polygon'):#數(shù)據(jù)類型為多邊形 需要轉化為矩形 x_max=0 y_max=0 x_min=100000 y_min=100000 for lk in range(len(i['points'])): x1=float(i['points'][lk][0]) y1=float(i['points'][lk][1]) # print(x1) if x_max<x1: x_max=x1 if y_max<y1: y_max=y1 if y_min>y1: y_min=y1 if x_min>x1: x_min=x1 bb = (x_min, y_max, x_max, y_min) if (i['shape_type'] == 'rectangle'):#為矩形不需要轉換 x1 = float(i['points'][0][0]) y1 = float(i['points'][0][1]) x2 = float(i['points'][1][0]) y2 = float(i['points'][1][1]) bb = (x1, y1, x2, y2) bbox = convert((img_w, img_h), bb) try: f.write(str(name2id[label_name]) + " " + " ".join([str(a) for a in bbox]) + '\n') except: pass
json_floder——讀取json的文件夾的絕對路徑
txt_outer_path——保存txt文本的文件夾的絕對路徑
json_name——json_name是json文本的名字
讀取該類的坐標然后進行數(shù)字規(guī)范化
數(shù)字規(guī)范化的代碼如下:
def convert(img_size, box): dw = 1. / (img_size[0]) dh = 1. / (img_size[1]) x = (box[0] + box[2]) / 2.0 y = (box[1] + box[3]) / 2.0 w = abs(box[2] - box[0]) h = abs(box[3] - box[1])#加入絕對值的原因是只需要它的寬和高,以免出現(xiàn)負數(shù) x = x * dw w = w * dw y = y * dh h = h * dh return (x, y, w, h)
最后附上我的完整代碼:
#處理labelme多邊形矩陣的標注 json轉化txt import json import os name2id={'bike':0,'arrow':1,'crossline':2,'building':3,'car':4,'person':5} def convert(img_size, box): dw = 1. / (img_size[0]) dh = 1. / (img_size[1]) x = (box[0] + box[2]) / 2.0 y = (box[1] + box[3]) / 2.0 w = abs(box[2] - box[0]) h = abs(box[3] - box[1]) x = x * dw w = w * dw y = y * dh h = h * dh return (x, y, w, h) def decode_json(json_floder_path,txt_outer_path, json_name): # json_floder_path='E:\\Python_package\\itesjson\\' # json_name='V1125.json' txt_name = txt_outer_path + json_name[:-5] + '.txt' with open(txt_name,'w') as f: json_path = os.path.join(json_floder_path, json_name)#os路徑融合 data = json.load(open(json_path, 'r', encoding='gb2312',errors='ignore')) img_w = data['imageWidth']#圖片的高 img_h = data['imageHeight']#圖片的寬 isshape_type=data['shapes'][0]['shape_type'] print(isshape_type) #print(isshape_type) #print('下方判斷根據(jù)這里的值可以設置為你自己的類型,我這里是polygon'多邊形) #len(data['shapes']) for i in data['shapes']: label_name = i['label']#得到json中你標記的類名 if (i['shape_type'] == 'polygon'):#數(shù)據(jù)類型為多邊形 需要轉化為矩形 x_max=0 y_max=0 x_min=100000 y_min=100000 for lk in range(len(i['points'])): x1=float(i['points'][lk][0]) y1=float(i['points'][lk][1]) # print(x1) if x_max<x1: x_max=x1 if y_max<y1: y_max=y1 if y_min>y1: y_min=y1 if x_min>x1: x_min=x1 bb = (x_min, y_max, x_max, y_min) if (i['shape_type'] == 'rectangle'):#為矩形不需要轉換 x1 = float(i['points'][0][0]) y1 = float(i['points'][0][1]) x2 = float(i['points'][1][0]) y2 = float(i['points'][1][1]) bb = (x1, y1, x2, y2) bbox = convert((img_w, img_h), bb) try: f.write(str(name2id[label_name]) + " " + " ".join([str(a) for a in bbox]) + '\n') except: pass if __name__ == "__main__": json_floder_path = 'E:\Python_package\\itesjson\\'#存放json的文件夾的絕對路徑 txt_outer_path='E:\Python_package\\e1\\'#存放txt的文件夾絕對路徑 json_names = os.listdir(json_floder_path) print("共有:{}個文件待轉化".format(len(json_names))) flagcount=0 for json_name in json_names: decode_json(json_floder_path,txt_outer_path,json_name) flagcount+=1 print("還剩下{}個文件未轉化".format(len(json_names)-flagcount)) break # break print('轉化全部完畢')
os.listdir——讀取文件下的所有文件。請先創(chuàng)建一個只有json文件的文件夾
記得先修改?。?!if __name__==“__main__”后的參數(shù)
json_floder_path——改成你自己的json文件夾路徑
txt_outer_path——改成你自己的輸出文件夾路徑
到此這篇關于Yolov5多邊形標簽和JSON數(shù)據(jù)格式轉換的文章就介紹到這了,更多相關Yolov5的JSON數(shù)據(jù)格式轉換內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python實現(xiàn)監(jiān)控遠程主機實時數(shù)據(jù)的示例詳解
這篇文章主要為大家詳細介紹了Python如何使用Socket庫和相應的第三方庫來監(jiān)控遠程主機的實時數(shù)據(jù),比如CPU使用率、內存使用率、網絡帶寬等,感興趣的可以了解一下2023-04-04Python開發(fā)SQLite3數(shù)據(jù)庫相關操作詳解【連接,查詢,插入,更新,刪除,關閉等】
這篇文章主要介紹了Python開發(fā)SQLite3數(shù)據(jù)庫相關操作,結合實例形式較為詳細的分析了Python操作SQLite3數(shù)據(jù)庫的連接,查詢,插入,更新,刪除,關閉等相關操作技巧,需要的朋友可以參考下2017-07-07利用Python腳本實現(xiàn)ping百度和google的方法
最近在做SEO的時候,為了讓發(fā)的外鏈能夠快速的收錄,想到了利用ping的功能,google和百度都有相關的ping介紹,有興趣的朋友可以去看看相關的知識。下面這篇文章主要介紹了利用Python腳本實現(xiàn)ping百度和google的方法,需要的朋友可以參考借鑒,一起來看看吧。2017-01-01