使用python,将文件夹中所有的labelme标注生成的json文件转换为可以用于labelimg标注的yolo格式的xml文件,且文件名与原文件名一致,且json文件中存在shape_type为circle的情况,则以第一个点为圆心,第一个点到第二个点的距离为半径,生成的yaml中的标签需为circle的外切矩形,最后将生成的xml文件放在新文件夹里
时间: 2024-02-15 13:05:24 浏览: 102
将labelme标注的json文件(coco格式)转化为voc需要的xml格式
5星 · 资源好评率100%
好的,这是一个比较复杂的任务,需要用到多个Python模块和库。我将为您提供一个基本的代码框架,但是您需要根据自己的具体需求进行适当的修改和调整。
首先,您需要安装以下Python库:
- xml.etree.ElementTree
- os
- json
- numpy
然后,您可以使用以下代码将JSON文件转换为Yolo格式的XML文件:
```python
import xml.etree.ElementTree as ET
import os
import json
import numpy as np
def convert_json_to_xml(json_file, xml_dir):
with open(json_file, 'r') as f:
data = json.load(f)
# 获取文件名和标签
filename = os.path.splitext(os.path.basename(json_file))[0]
labels = data['shapes']
# 创建XML根元素
annotation = ET.Element('annotation')
ET.SubElement(annotation, 'folder').text = 'yolo'
ET.SubElement(annotation, 'filename').text = filename + '.jpg'
ET.SubElement(annotation, 'path').text = os.path.join(xml_dir, filename + '.jpg')
size = ET.SubElement(annotation, 'size')
ET.SubElement(size, 'width').text = str(data['imageWidth'])
ET.SubElement(size, 'height').text = str(data['imageHeight'])
ET.SubElement(size, 'depth').text = '3'
# 遍历标签
for label in labels:
shape_type = label['shape_type']
if shape_type == 'circle':
# 获取圆心和半径
points = label['points']
center = np.array(points[0])
radius = np.linalg.norm(np.array(points[0]) - np.array(points[1]))
# 计算外切矩形坐标
x_min = int(center[0] - radius)
y_min = int(center[1] - radius)
x_max = int(center[0] + radius)
y_max = int(center[1] + radius)
# 创建标注元素
object = ET.SubElement(annotation, 'object')
ET.SubElement(object, 'name').text = 'circle'
ET.SubElement(object, 'pose').text = 'Unspecified'
ET.SubElement(object, 'truncated').text = '0'
ET.SubElement(object, 'difficult').text = '0'
bbox = ET.SubElement(object, 'bndbox')
ET.SubElement(bbox, 'xmin').text = str(x_min)
ET.SubElement(bbox, 'ymin').text = str(y_min)
ET.SubElement(bbox, 'xmax').text = str(x_max)
ET.SubElement(bbox, 'ymax').text = str(y_max)
else:
# 如果不是圆,则获取矩形坐标
points = label['points']
x_min = min([int(point[0]) for point in points])
y_min = min([int(point[1]) for point in points])
x_max = max([int(point[0]) for point in points])
y_max = max([int(point[1]) for point in points])
# 创建标注元素
object = ET.SubElement(annotation, 'object')
ET.SubElement(object, 'name').text = shape_type
ET.SubElement(object, 'pose').text = 'Unspecified'
ET.SubElement(object, 'truncated').text = '0'
ET.SubElement(object, 'difficult').text = '0'
bbox = ET.SubElement(object, 'bndbox')
ET.SubElement(bbox, 'xmin').text = str(x_min)
ET.SubElement(bbox, 'ymin').text = str(y_min)
ET.SubElement(bbox, 'xmax').text = str(x_max)
ET.SubElement(bbox, 'ymax').text = str(y_max)
# 创建XML文件
xml_file = os.path.join(xml_dir, filename + '.xml')
tree = ET.ElementTree(annotation)
tree.write(xml_file)
```
接下来,您可以使用以下代码将文件夹中的所有JSON文件转换为XML文件,并将它们放在新文件夹中:
```python
def convert_folder_to_xml(json_dir, xml_dir):
if not os.path.exists(xml_dir):
os.makedirs(xml_dir)
json_files = [os.path.join(json_dir, file) for file in os.listdir(json_dir) if file.endswith('.json')]
for json_file in json_files:
convert_json_to_xml(json_file, xml_dir)
```
最后,您可以像这样调用上面的函数:
```python
json_dir = '/path/to/json/folder'
xml_dir = '/path/to/xml/folder'
convert_folder_to_xml(json_dir, xml_dir)
```
请注意,这只是一个基本的代码框架,您需要根据自己的具体需求进行适当的修改和调整。
阅读全文