第一章 导包
import os
import json
import argparse
第二章 类别
class_mapping = {"自己的类别": 0}
第三章 多边形点集转换为边界框的函数
def convert_polygon_to_bbox(points):
"""将多边形点集转换为边界框"""
x_coords = [point[0] for point in points]
y_coords = [point[1] for point in points]
xmin = min(x_coords)
ymin = min(y_coords)
xmax = max(x_coords)
ymax = max(y_coords)
return xmin, ymin, xmax, ymax
第四章 转换函数
def convert_json_to_yolo(json_path, txt_path, image_width, image_height):
"""将单个JSON文件转换为YOLO格式的TXT文件"""
with open(json_path, 'r') as f:
data = json.load(f)
with open(txt_path, 'w') as f:
for shape in data.get("shapes", []):
label = shape["label"]
if label not in class_mapping:
print(f"警告: 未定义的类别 '{label}',跳过此对象")
continue
class_id = class_mapping[label]
points = shape["points"]
xmin, ymin, xmax, ymax = convert_polygon_to_bbox(points)
# 计算归一化的边界框坐标
x_center = (xmin + xmax) / (2 * image_width)
y_center = (ymin + ymax) / (2 * image_height)
width = (xmax - xmin) / image_width
height = (ymax - ymin) / image_height
# 写入YOLO格式的行
f.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")
第五章 批量转换函数
def batch_convert(json_dir, txt_dir, image_width, image_height):
"""批量转换JSON文件夹中的所有文件"""
# 确保输出目录存在
os.makedirs(txt_dir, exist_ok=True)
# 获取所有JSON文件
json_files = [f for f in os.listdir(json_dir) if f.lower().endswith('.json')]
if not json_files:
print(f"错误: 在 {json_dir} 中未找到JSON文件")
return
total = len(json_files)
success = 0
print(f"开始批量转换: {total} 个JSON文件")
for i, json_file in enumerate(json_files, 1):
json_path = os.path.join(json_dir, json_file)
txt_file = os.path.splitext(json_file)[0] + '.txt'
txt_path = os.path.join(txt_dir, txt_file)
try:
convert_json_to_yolo(json_path, txt_path, image_width, image_height)
success += 1
print(f"[{i}/{total}] 成功转换: {json_file} -> {txt_file}")
except Exception as e:
print(f"[{i}/{total}] 转换失败: {json_file} - 错误: {str(e)}")
print(f"转换完成: 成功 {success}/{total}")
第六章 主函数
def main():
parser = argparse.ArgumentParser(description='批量将JSON标注文件转换为YOLO格式的TXT文件')
parser.add_argument('--json_dir', required=True, help='JSON文件所在目录')
parser.add_argument('--txt_dir', required=True, help='TXT文件输出目录')
parser.add_argument('--img_width', type=int, required=True, help='图像宽度')
parser.add_argument('--img_height', type=int, required=True, help='图像高度')
args = parser.parse_args()
batch_convert(args.json_dir, args.txt_dir, args.img_width, args.img_height)
第七章 主函数调用
if __name__ == "__main__":
main()
全部代码如下:
import os
import json
import argparse
# 类别映射 - 根据实际情况修改
class_mapping = {"自己的类别": 0}
def convert_polygon_to_bbox(points):
"""将多边形点集转换为边界框"""
x_coords = [point[0] for point in points]
y_coords = [point[1] for point in points]
xmin = min(x_coords)
ymin = min(y_coords)
xmax = max(x_coords)
ymax = max(y_coords)
return xmin, ymin, xmax, ymax
def convert_json_to_yolo(json_path, txt_path, image_width, image_height):
"""将单个JSON文件转换为YOLO格式的TXT文件"""
with open(json_path, 'r') as f:
data = json.load(f)
with open(txt_path, 'w') as f:
for shape in data.get("shapes", []):
label = shape["label"]
if label not in class_mapping:
print(f"警告: 未定义的类别 '{label}',跳过此对象")
continue
class_id = class_mapping[label]
points = shape["points"]
xmin, ymin, xmax, ymax = convert_polygon_to_bbox(points)
# 计算归一化的边界框坐标
x_center = (xmin + xmax) / (2 * image_width)
y_center = (ymin + ymax) / (2 * image_height)
width = (xmax - xmin) / image_width
height = (ymax - ymin) / image_height
# 写入YOLO格式的行
f.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")
def batch_convert(json_dir, txt_dir, image_width, image_height):
"""批量转换JSON文件夹中的所有文件"""
# 确保输出目录存在
os.makedirs(txt_dir, exist_ok=True)
# 获取所有JSON文件
json_files = [f for f in os.listdir(json_dir) if f.lower().endswith('.json')]
if not json_files:
print(f"错误: 在 {json_dir} 中未找到JSON文件")
return
total = len(json_files)
success = 0
print(f"开始批量转换: {total} 个JSON文件")
for i, json_file in enumerate(json_files, 1):
json_path = os.path.join(json_dir, json_file)
txt_file = os.path.splitext(json_file)[0] + '.txt'
txt_path = os.path.join(txt_dir, txt_file)
try:
convert_json_to_yolo(json_path, txt_path, image_width, image_height)
success += 1
print(f"[{i}/{total}] 成功转换: {json_file} -> {txt_file}")
except Exception as e:
print(f"[{i}/{total}] 转换失败: {json_file} - 错误: {str(e)}")
print(f"转换完成: 成功 {success}/{total}")
def main():
parser = argparse.ArgumentParser(description='批量将JSON标注文件转换为YOLO格式的TXT文件')
parser.add_argument('--json_dir', required=True, help='JSON文件所在目录')
parser.add_argument('--txt_dir', required=True, help='TXT文件输出目录')
parser.add_argument('--img_width', type=int, required=True, help='图像宽度')
parser.add_argument('--img_height', type=int, required=True, help='图像高度')
args = parser.parse_args()
batch_convert(args.json_dir, args.txt_dir, args.img_width, args.img_height)
if __name__ == "__main__":
main()
# ""是文件路径
# 执行命令 python xx.py --json_dir "" --txt_dir "" --img_width 800 --img_height 600
# 传入四个参数
# --json_dir:json的文件夹路径
# --txt_dir:输出的txt的文件夹路径
# --img_width 图像宽
# --img_height 图像高