代码如下:
# -*- coding:utf-8 -*-
"""
@Author :
@Time :
@FileName: json2yolo_txt.py
@Software: PyCharm
@Question: json格式标注文件转化为yolo的txt格式
"""
import os
import json
from pathlib import Path
json_path = 'XXX/Flir/video/thermal_annotations.json' # json文件路径
out_path = 'XXX/Flir/video/labels/' # 输出 txt 文件路径
Path(out_path).mkdir(parents=True, exist_ok=True) # 若路径不存在则创建
# 读取 json 文件数据
with open(json_path, 'r') as load_f:
content = json.load(load_f)
def process_classes():
'''
classes.txt文件处理
'''
# 处理class
categories = content['categories']
classes_txt = out_path + 'classes.txt'
for categorie in categories:
if categorie['id'] == 0:
continue
if os.path.exists(classes_txt):
fp = open(classes_txt, mode="r+", encoding="utf-8")
file_str = str(categorie['id'] - 1) + ':' + str(categorie['name'])
line_data = fp.readlines()
if len(line_data) != 0:
fp.write('\n' + file_str)
else:
fp.write(file_str)
fp.close()
# 不存在则创建文件
else:
fp = open(classes_txt, mode="w+", encoding="utf-8")
file_str = str(categorie['id'] - 1) + ':' + str(categorie['name'])
line_data = fp.readlines()
if len(line_data) != 0:
fp.write('\n' + file_str)
else:
fp.write(file_str)
fp.close()
def process_label():
'''
创建label.txt
'''
# 已知的信息
image_width = 640
image_height = 512
img_file_name = ''
annotation = content['annotations']
images = content['images']
i = 0
for label in annotation:
image_id = label['image_id']
category_id = label['category_id']
image = images[image_id]
if image['id'] == image_id:
file_name = image['file_name']
img_file_name = file_name.split('/')[1].split('.')[0]
image_width = image['width']
image_height = image['height']
label_txt = out_path + img_file_name + '.txt'
if os.path.exists(label_txt):
x = ((label['bbox'][0] + label['bbox'][2]) / 2) / image_width
y = ((label['bbox'][1] + label['bbox'][3]) / 2) / image_height
w = label['bbox'][2] / image_width
h = label['bbox'][3] / image_height
fp = open(label_txt, mode="r+", encoding="utf-8")
file_str = str(category_id) + ' ' + str(round(x, 6)) + ' ' + str(round(y, 6)) + ' ' + str(round(w, 6)) + \
' ' + str(round(h, 6))
line_data = fp.readlines()
if len(line_data) != 0:
fp.write('\n' + file_str)
else:
fp.write(file_str)
fp.close()
else: # 不存在则创建文件
if image_id != i:
diff_vlaue = image_id - i
for _ in range(0, diff_vlaue):
img_name = images[i + _]['file_name'].split('/')[1].split('.')[0]
txt_name = out_path + img_name + '.txt'
fp = open(txt_name, mode="w", encoding="utf-8")
fp.close()
i = image_id
i = i + 1
x = ((label['bbox'][0] + label['bbox'][2]) / 2) / image_width
y = ((label['bbox'][1] + label['bbox'][3]) / 2) / image_height
w = label['bbox'][2] / image_width
h = label['bbox'][3] / image_height
fp = open(label_txt, mode="w+", encoding="utf-8")
file_str = str(category_id) + ' ' + str(round(x, 6)) + ' ' + str(round(y, 6)) + ' ' + str(round(w, 6)) + \
' ' + str(round(h, 6))
line_data = fp.readlines()
if len(line_data) != 0:
fp.write('\n' + file_str)
else:
fp.write(file_str)
fp.close()
process_classes()
process_label()
对应的FLIR数据集的thermal_annotations.json标注文件部分内容:
{
"info": {
"version": 1.0,
"url": "no url specified",
"year": 2019,
"date_created": "today",
"contributor": "no contributor specified",
"description": ""
},
"categories": [
{
"name": "person",
"id": 1,
"supercategory": "unknown"
},
{
"name": "bicycle",
"id": 2,
"supercategory": "unknown"
},
{
"name": "car",
"id": 3,
"supercategory": "unknown"
}
],
"licenses": [],
"annotations": [
{
"image_id": 0,
"extra_info": {
"human_annotated": true
},
"category_id": 1,
"iscrowd": 0,
"id": 1,
"segmentation": [
[
580,
206,
580,
281,
614,
281,
614,
206
]
],
"bbox": [
580,
206,
34,
75
],
"area": 2550
},
{
"image_id": 1,
"extra_info": {
"human_annotated": true
},
"category_id": 1,
"iscrowd": 0,
"id": 2,
"segmentation": [
[
609,
207,
609,
323,
639,
323,
639,
207
]
],
"bbox": [
609,
207,
30,
116
],
"area": 3480
}
],
"images": [
{
"extra_info": {},
"subdirs": ".",
"id": 0,
"width": 640,
"file_name": "thermal_8_bit/FLIR_08863.jpeg",
"height": 512
},
{
"extra_info": {},
"subdirs": ".",
"id": 1,
"width": 640,
"file_name": "thermal_8_bit/FLIR_08864.jpeg",
"height": 512
}
]
}