### 一、LabelMe JSON文件转换为VOC数据集格式
LabelMe工具生成的JSON文件格式与VOC数据集的格式存在差异,因此需要进行转换。以下是具体的转换步骤:
1. **下载官方工具**
在GitHub上可以找到LabelMe的官方工具包,如`labelme5.0.1`或`labelme3.16.7`。这些工具通常包含将JSON文件转换为VOC数据集所需的脚本。
2. **使用官方脚本转换数据集**
官方提供的`labelme2voc.py`脚本可以将JSON文件转换为VOC数据集格式。该脚本会将标注信息转换为PASCAL VOC所需的`xml`文件,并生成对应的图像文件(如`.png`)。
```python
# 示例代码:labelme2voc.py的部分代码
import json
import os
from labelme import utils
import numpy as np
import glob
import PIL.Image as Image
def json_to_voc(json_file):
with open(json_file, 'r') as f:
data = json.load(f)
img = utils.img_b64_to_array(data['imageData'])
lbl, _ = utils.shapes_to_label(img.shape, data['shapes'], [0, 1])
label_img = Image.fromarray(lbl.astype(np.uint8))
label_img.save(json_file.replace('.json', '_label.png'))
```
3. **划分训练集和验证集**
转换完成后,通常需要将数据集划分为训练集和验证集。可以使用`train_test_split`函数或手动划分的方式,将数据按比例分配。
```python
from sklearn.model_selection import train_test_split
files = glob.glob('data/*.json')
train_files, val_files = train_test_split(files, test_size=0.2)
```
### 二、LabelMe JSON文件转换为语义分割数据集
在语义分割任务中,LabelMe的JSON文件需要转换为适合训练的格式,通常是单通道的PNG图像,每个像素值代表一个类别。
1. **解析JSON文件**
使用`labelme.utils.shapes_to_label`函数可以将JSON文件中的标注信息转换为标签图像。
```python
import labelme.utils
import numpy as np
def convert_json_to_segmentation(json_file):
with open(json_file, 'r') as f:
data = json.load(f)
img = utils.img_b64_to_array(data['imageData'])
lbl, _ = utils.shapes_to_label(img.shape, data['shapes'], [0, 1])
return lbl
```
2. **生成语义分割标签图像**
将解析后的标签信息保存为PNG文件,供后续训练使用。
```python
label_img = Image.fromarray(lbl.astype(np.uint8))
label_img.save(json_file.replace('.json', '_seg.png'))
```
### 三、LabelMe JSON文件转换为COCO数据集格式
COCO数据集的标注格式与LabelMe不同,因此需要将JSON文件转换为COCO的`annotations.json`文件,并生成对应的图像文件。
1. **生成COCO格式的标注文件**
使用`labelme2coco.py`脚本可以将JSON文件转换为COCO格式的`annotations.json`文件。
```python
import json
import os
from labelme import utils
import numpy as np
import glob
def json_to_coco(json_files, output_file):
images = []
annotations = []
categories = [{'id': 1, 'name': 'object'}]
for i, json_file in enumerate(json_files):
with open(json_file, 'r') as f:
data = json.load(f)
img = utils.img_b64_to_array(data['imageData'])
image_id = i + 1
images.append({
'id': image_id,
'file_name': os.path.basename(json_file).replace('.json', '.jpg'),
'width': img.shape[1],
'height': img.shape[0]
})
for shape in data['shapes']:
segmentation = [np.array(shape['points']).flatten().tolist()]
x_min = min(p[0] for p in shape['points'])
y_min = min(p[1] for p in shape['points'])
width = max(p[0] for p in shape['points']) - x_min
height = max(p[1] for p in shape['points']) - y_min
annotations.append({
'id': len(annotations) + 1,
'image_id': image_id,
'category_id': 1,
'bbox': [x_min, y_min, width, height],
'segmentation': [segmentation],
'area': width * height,
'iscrowd': 0
})
coco_data = {
'images': images,
'annotations': annotations,
'categories': categories
}
with open(output_file, 'w') as f:
json.dump(coco_data, f)
```
2. **生成图像文件**
将JSON文件中的图像数据保存为`JPEGImages`文件夹中的`.jpg`文件。
```python
for json_file in json_files:
with open(json_file, 'r') as f:
data = json.load(f)
img = utils.img_b64_to_array(data['imageData'])
img = Image.fromarray(img)
img.save(json_file.replace('.json', '.jpg'))
```
### 四、LabelMe JSON文件转换为YOLOv5所需的.txt文件
YOLOv5要求的标注文件格式为`.txt`,每行包含类别ID和归一化的边界框坐标。
1. **生成.txt文件**
使用`segment/predict_seg.py`脚本可以生成`.txt`文件,保存预测结果。
```bash
python segment/predict_seg.py --weights runs/train-seg/exp2/weights/best.pt --source data/images/ --device 0 --save-txt
```
2. **手动转换JSON文件**
如果需要手动转换,可以使用以下代码:
```python
def json_to_yolo(json_file, output_file):
with open(json_file, 'r') as f:
data = json.load(f)
img_width = data['imageWidth']
img_height = data['imageHeight']
with open(output_file, 'w') as f:
for shape in data['shapes']:
points = np.array(shape['points'])
x_min = min(points[:, 0]) / img_width
y_min = min(points[:, 1]) / img_height
x_max = max(points[:, 0]) / img_width
y_max = max(points[:, 1]) / img_height
f.write(f"0 {x_min} {y_min} {x_max} {y_max}\n")
```