怎么将labelme标注的json格式转换成yolo格式
时间: 2025-07-12 15:43:24 浏览: 9
<think>好的,用户想将Labelme标注的JSON文件转换成YOLO格式。我需要仔细回忆转换的步骤,确保正确性。首先,Labelme生成的JSON文件包含图像信息和多边形坐标,而YOLO需要的是归一化的中心点坐标、宽度和高度。这中间需要进行坐标转换和归一化处理。
首先,要确认每个JSON文件对应的图像尺寸,因为归一化需要用到图像的宽度和高度。然后,处理每个形状(shape)的标注数据,特别是多边形(polygon)的点坐标。对于YOLO来说,每个对象需要转换成一个边界框(bbox),所以可能需要将多边形点转换为矩形的左上角和右下角坐标,或者直接使用Labelme中的矩形标注。
需要注意的是,YOLO的格式是每行一个对象,包含类别编号、中心点x、中心点y、宽度和高度,这些都需要归一化到0-1之间。因此,计算中心点时,需要将左上和右下的坐标取平均,再除以图像尺寸得到归一化值。宽度和高度也是通过差值计算后归一化。
另外,类别名称需要对应到YOLO的类别索引,可能需要一个类别列表,并在转换时查找对应的索引。用户可能需要提前准备好这个列表,或者在转换过程中动态创建。
还有,处理多个JSON文件时,可能需要批量处理,遍历每个文件,读取其中的数据,进行转换后保存为txt文件,每个图像对应一个txt,放在正确的目录结构中,比如YOLO要求的images和labels文件夹。
用户可能遇到的常见问题包括:坐标归一化错误、类别索引不匹配、多边形转bbox的计算错误。需要提醒用户检查转换后的坐标是否在0-1之间,以及类别是否正确对应。同时,验证转换后的YOLO格式是否正确,可以使用可视化工具检查边界框是否准确覆盖目标。
总结步骤应该是:读取JSON,提取图像尺寸,遍历每个形状,转换坐标,归一化,写入txt。同时提供代码示例会有帮助,但需要确保代码的正确性,比如使用Python处理,导入必要的库如json、os等,处理异常情况,比如非矩形的形状可能需要跳过或处理。
可能还需要考虑不同的标注类型,比如矩形、多边形、圆形等,但YOLO通常使用矩形框,所以如果是多边形,可能需要计算其外接矩形。这部分需要明确告诉用户,假设用户使用的是矩形标注,或者如何处理多边形。
最后,提醒用户注意文件路径的正确性,避免路径错误导致转换失败,以及确保图像文件的存在和正确对应。</think>将Labelme的JSON标注转换为YOLO格式需遵循以下步骤:
---
### 一、理解格式差异
1. **Labelme格式**
- 存储多边形点坐标(x,y)
- 以`JSON`文件保存,包含图像路径、尺寸、标注点
```json
{"shapes": [{"label": "cat", "points": [[x1,y1], [x2,y2], ...]}]}
```
2. **YOLO格式**
- 存储归一化的中心点坐标和宽高
- 每行对应一个对象:`[class_id] [x_center] [y_center] [width] [height]`
- 数值范围:0-1(相对于图像尺寸)
---
### 二、转换步骤
#### 1. 提取图像尺寸
从JSON中获取图像宽高:
```python
width = json_data["imageWidth"]
height = json_data["imageHeight"]
```
#### 2. 处理每个标注对象
遍历`shapes`列表,对每个多边形/矩形:
```python
for shape in json_data["shapes"]:
label = shape["label"]
points = np.array(shape["points"])
```
#### 3. 计算边界框(Bounding Box)
- **左上角**:`(x_min, y_min) = points.min(axis=0)`
- **右下角**:`(x_max, y_max) = points.max(axis=0)`
#### 4. 转换为YOLO格式
```python
x_center = (x_min + x_max) / 2 / width
y_center = (y_min + y_max) / 2 / height
bbox_width = (x_max - x_min) / width
bbox_height = (y_max - y_min) / height
```
#### 5. 保存结果
生成与图片同名的`.txt`文件:
```
0 0.435 0.512 0.120 0.300 # 示例行
```
---
### 三、Python脚本示例
```python
import json
import os
def convert_labelme_to_yolo(json_path, output_dir, class_list):
with open(json_path, 'r') as f:
data = json.load(f)
width = data['imageWidth']
height = data['imageHeight']
txt_lines = []
for shape in data['shapes']:
label = shape['label']
class_id = class_list.index(label)
points = np.array(shape['points'])
# 计算边界框
x_min, y_min = points.min(axis=0)
x_max, y_max = points.max(axis=0)
# 归一化
x_center = (x_min + x_max) / 2 / width
y_center = (y_min + y_max) / 2 / height
bbox_w = (x_max - x_min) / width
bbox_h = (y_max - y_min) / height
txt_lines.append(f"{class_id} {x_center:.6f} {y_center:.6f} {bbox_w:.6f} {bbox_h:.6f}")
# 保存到txt文件
txt_filename = os.path.splitext(os.path.basename(json_path))[0] + '.txt'
with open(os.path.join(output_dir, txt_filename), 'w') as f:
f.write('\n'.join(txt_lines))
```
---
### 四、关键注意事项
1. **类别映射**:需提前定义`class_list`(如`["cat", "dog"]`)
2. **归一化检查**:确保所有值在0-1之间
3. **多对象处理**:同一图片多个对象会生成多行
4. **坐标顺序**:YOLO使用`(中心点x, 中心点y, 宽度, 高度)`
---
### 五、验证结果
使用工具(如`labelImg`)打开生成的YOLO标签,确认边界框位置是否与原始标注匹配。
阅读全文
相关推荐
















