在前几天我使用yolov8时,找网上转格式的代码,发现没有自己想要的,于是进行改编捣鼓了一下。
一、打开labelme
二、创建图形将所要的物体框起来(这里我用的是矩形)
三、打上关键点(即控制点)
对于可见点,正常打点,写名称;对于不可见点,打点写名称后,在discription中写下hidden
四、转换格式代码,由于我的description是hidden,所以代码中我写的是识别到hidden更改可见数据,可按需更改。
import json
import os
#更改为你的标注框的信息
#更改为你关键点的信息(名称)
bbox_class = {
'pen': 0
}
keypoint_class = [
'spot_1', 'spot_2', 'spot_3'
]
# 设定文件夹路径
folder_path = r"D:\Download\ultralytics-main\111111labels\camera4\labels"
files = os.listdir(folder_path)
for file in files:
if file.endswith('.json'):
# 完整的文件路径
labelme_path = os.path.join(folder_path, file)
with open(labelme_path, 'r', encoding='utf-8') as f:
labelme = json.load(f)
img_width = labelme['imageWidth']
img_height = labelme['imageHeight']
# 生成 YOLO 格式的 txt 文件
suffix = labelme_path.rsplit('.', 1)[0]
yolo_txt_path = suffix + '.txt'
with open(yolo_txt_path, 'w', encoding='utf-8') as f:
for each_ann in labelme['shapes']:
if each_ann['shape_type'] == 'rectangle':
yolo_str = ''
bbox_class_id = bbox_class[each_ann['label']]
yolo_str += '{} '.format(bbox_class_id)
bbox = [min(each_ann['points'][0][0], each_ann['points'][1][0]),
max(each_ann['points'][0][0], each_ann['points'][1][0]),
min(each_ann['points'][0][1], each_ann['points'][1][1]),
max(each_ann['points'][0][1], each_ann['points'][1][1])]
bbox_center_x = (bbox[0] + bbox[1]) / 2
bbox_center_y = (bbox[2] + bbox[3]) / 2
bbox_width = bbox[1] - bbox[0]
bbox_height = bbox[3] - bbox[2]
bbox_center_x_norm = bbox_center_x / img_width
bbox_center_y_norm = bbox_center_y / img_height
bbox_width_norm = bbox_width / img_width
bbox_height_norm = bbox_height / img_height
yolo_str += '{:.5f} {:.5f} {:.5f} {:.5f} '.format(
bbox_center_x_norm, bbox_center_y_norm, bbox_width_norm, bbox_height_norm)
bbox_keypoints_dict = {}
for point_ann in labelme['shapes']:
if point_ann['shape_type'] == 'point':
x = point_ann['points'][0][0]
y = point_ann['points'][0][1]
label = point_ann['label']
if bbox[0] < x < bbox[1] and bbox[2] < y < bbox[3]:
bbox_keypoints_dict[label] = [x, y]
# 创建一个字典来存储每个spot的可视化值
spot_visualization_values = {
'spot_1': None,
'spot_2': None,
'spot_3': None
}
# 遍历所有形状以收集spot的可视化值
for shape in labelme['shapes']:
if shape['shape_type'] == 'point':
label = shape['label']
if label in spot_visualization_values:
# 检查description是否包含"hidden"
is_hidden = 'hidden' in (shape.get('description', '').lower())
# 设置可视化值
spot_visualization_values[label] = 1 if is_hidden else 2
# 遍历所有关键点类
for each_class in keypoint_class:
if each_class in spot_visualization_values:
visualization_value=spot_visualization_values[each_class]
# 检查当前spot是否在bbox_keypoints_dict的当前类中定义
# 获取关键点坐标并归一化
keypoint_x_norm = bbox_keypoints_dict[each_class][0] / img_width
keypoint_y_norm = bbox_keypoints_dict[each_class][1] / img_height
yolo_str += '{:.6f} {:.6f} {} '.format(keypoint_x_norm, keypoint_y_norm,
visualization_value)
else:
yolo_str += '0 0 0 '
f.write(yolo_str + '\n')
print('{} --> {} 转换完成'.format(labelme_path, yolo_txt_path))
print(f"Processing class: {each_class}")
print(f"Available keys in bbox_keypoints_dict: {bbox_keypoints_dict.keys()}")
五、改完数据如下:
前五个是框的数据,后面每三个是关键点的数据,关键点数据中,1表示隐藏点,2可见点。
注意:可见点数据必须要是六位小数(至少我用的版本需要),我就踩坑了,检查了好久才发现是这里出错了。