当前位置:   article > 正文

【数据准备001】标注工具Labelimg安装与使用(附txt与xml文件相互转化代码)_标注的txt文件转换为xml

标注的txt文件转换为xml

一、简介

        LabelImg是一个开源的图形图像注释工具,用于创建边界/矩形框(适用于要标注物体的位置和大小)和多边形注释(适用于标注非规则形状的物体)。它是用Python写的,并使用Qt作为其图形界面。LabelImg能够在Windows、Linux和macOS等多个平台上运行,同时支持各种类型的图像文件格式,如JPGPNGBMP等(注:图片格式不是这几种的,可以使用格式工厂转一下即可)。

        在LabelImg中,可以选择PASCAL VOCYOLOCreateML三种格式进行类别标注,生成的文件类型分别为:

        PASCAL VOC——xx.XML文件(常用)

        YOLO——xx.txt文件(常用)

        CreateML——xx.json文件

        CreateML是Apple提供的一种机器学习工具箱,用于构建和训练各种机器学习模型,包括图像分类、目标检测等任务。


二、Labelimg工具的安装

        Labelimg安装十分方便,不需要去git或者github上下载什么开源代码,使用pip就能直接安装

1. conda 安装

        建议在conda中创建一个独立的环境来安装图片标注工具(不会使用conda可以看​【基础01】 Anaconda+Pycharm让Python开发直接起飞​ ),避免忘记安装在哪个环境中,或者与其他环境混淆。

        (1)创建环境

conda create -n labelimg python=3.8

        输入y,继续安装

        出现以上信息,即创建完成

        (2)激活环境,安装工具

        a. 激活环境
 conda activate labelimg

        左边出现你的环境名,即切换成功

        b. 安装工具
pip install labelimg

        这里选择默认版本(最新版)安装,你也可以指定labelimg的版本号进行安装

        在末尾出现successfully就表示安装成功啦~

2. Pip安装

        若没有安装conda,使用python原生IDLE开发的,可以直接打开cmd命令符窗口

        输入pip install labelimg 安装成功后即可


三、Labelimg工具的使用

1. 打开工具

        (1)打开工具

        在刚刚创建的环境中直接输入 labelimg

        (2)基本功能介绍

        (3)快捷键

        在Labelimg中比较常用的快捷键如下:

快捷键

含义

w

绘制矩形框

d

下一张图片

a

上一张图片

Del

删除标注框

Ctrl+鼠标滚轮

放大/缩小图片

Ctrl + +

放大图片

Ctrl + -

缩小图片

Ctrl + s

保存

2. 使用工具

        (1)选择YOLO模式创建标签

        若打完标签未保存,切换图片时,会出现保存提醒

        保存成功后,会在你选择保存标签的文件夹中默认生成两个txt文件

                1.存放标签信息的文件(XXX.txt);

                2.存放标签类别的文件(classes.txt)

        存放标签信息的文件的文件名为与图片名相同,内容由N行5列数据组成。

        每一行代表标注的一个目标,通常包括五个数据,从左到右依次为:类别idx_centery_centerwidthheight

        其中:

                类别id代表标注目标的类别

                x_center和y_center代表标注框的相对中心坐标

                width和height代表标注框的相对宽和高

        请注意,这里的中心点坐标、宽和高都是相对数据!!!

        存放标签类别的文件的文件名为classes.txt (固定不变),用于存放创建的标签类别。

        (2)选择create ML模式创建标签

        同样会生成两个文件:

                1.存放标签信息的文件(XXX.json);

                2.存放标签类别的文件(classes.txt)(若之前存在,则不会再生成)

        在生成JSON文件中,每个目标都表示为一个对象,其中包含以下属性

                image:图像文件的名称。

                annotation:一个包含所有目标的数组,每个目标都表示为一个对象。包括:

                label:目标的类别名称,例如"汽车"、"人"、"自行车"等。

                x和y:目标的左上角坐标,表示其在图像中的位置。

                width和height:目标的宽度和高度,表示其在图像中的大小。

        (3)选择PascalVOC模式创建标签

        同样会生成两个文件:

                1.存放标签信息的文件(XXX.xml);

                2.存放标签类别的文件(classes.txt)(若之前存在,则不会再生成)

        每个XML文件对应一个图像文件,文件中包含了对图像的解释。具体来说,XML文件里标记了物体框的坐标和类别等信息。对于用户自定义数据,可根据实际情况对这些字段进行标注。

        在XML文件中,关键信息包括:

                folder:图像所在文件夹名

                filename:图像文件的名称

                path:图像所在路径

                size:图像的尺寸,包括宽度、高度和通道数

                object:标注框的信息,包括:

                        name:物体框对应的类别名称

                        bndbox:物体框的信息,包括左上角和右下角的坐标

                                xmin:图像左上角x坐标

                                ymin:图像左上角y坐标

                                xmax:图像右下角x坐标

                                ymax:图像右下角y坐标

        此外,XML文件中还可能包含其他相关信息,例如物体框的遮挡情况(pose)、是否被截断(truncated)、是否是难检测(difficult)物体等。这些信息用于辅助标注和评估目标检测任务的性能。

四、YOLO格式文件与VOC格式文件相互转换

        1. txt2xml

  1. def Txt2XML(input_txt_dir, output_xml_dir, image_dir, class_txt):
  2. # 获取txt文件的目录列表
  3. txt_files = os.listdir(input_txt_dir)
  4. # 获取图像的目录列表
  5. image_files = os.listdir(image_dir)
  6. image_infos = []
  7. for txt_file in txt_files:
  8. file_name, file_ext = os.path.splitext(txt_file)
  9. for image_file in image_files:
  10. images = []
  11. image_name, image_ext = os.path.splitext(image_file)
  12. if image_ext == '.jpg':
  13. # 判断图像名是否与txt文件名相同
  14. if image_name == file_name:
  15. images.append(image_file)
  16. # 读取txt文件中的标注信息
  17. with open(os.path.join(input_txt_dir, txt_file), 'r') as f:
  18. bboxes = []
  19. for line in f.readlines():
  20. bbox_id, x_center, y_center, width, height = line.strip().split()
  21. x_center = float(x_center) # 相对坐标
  22. y_center = float(y_center) # 相对坐标
  23. width = float(width) # 相对坐标
  24. height = float(height) # 相对坐标
  25. bbox = (bbox_id, x_center, y_center, width, height)
  26. bboxes.append(bbox)
  27. images.append(bboxes)
  28. image_infos.append(images)
  29. # 获取标注框的类别列表
  30. class_names = []
  31. with open(class_txt, 'r') as classes:
  32. for class_name in classes.readlines():
  33. class_names.append(class_name.strip())
  34. # 遍历每个图像文件,获取图像的高度和宽度,并将标注信息写入XML文件
  35. for image_info in image_infos:
  36. image_file = image_info[0]
  37. image_name, image_ext = os.path.splitext(image_file)
  38. image_path = os.path.join(image_dir, image_file)
  39. img = cv2.imread(image_path)
  40. image_height, image_width, num_channels = img.shape[:3] # 获取图片的高度、宽度和通道数
  41. # 创建XML文件并写入标注信息
  42. with open(os.path.join(output_xml_dir, image_name+'.xml'), 'a') as f:
  43. f.write('<annotation>\n')
  44. # 图像位置信息
  45. f.write('\t<filename>{}</filename>\n'.format(image_file))
  46. f.write('\t<path>{}</path>\n'.format(image_path))
  47. # 图像尺寸信息
  48. f.write('\t<size>\n')
  49. f.write('\t\t<width>{}</width>\n\t\t<height>{}</height>\n\t\t<depth>{}</depth>\n'.format(image_width, image_height, num_channels))
  50. f.write('\t</size>\n')
  51. # 图像类别、坐标信息
  52. bboxes = image_info[1]
  53. for bbox in bboxes:
  54. bbox_id, x_center, y_center, width, height = bbox
  55. xmin = (x_center * image_width) - (width * image_width)/2 # 计算标注框左上角x坐标值
  56. ymin = (y_center * image_height) - (height * image_height)/2 # 计算标注框左上角y坐标值
  57. xmax = (x_center * image_width) + (width * image_width)/2 # 计算标注框右下角x坐标值
  58. ymax = (y_center * image_height) + (height * image_height)/2 # 计算标注框右下角y坐标值
  59. f.write('\t<object>\n')
  60. f.write('\t\t<name>{}</name>\n'.format(class_names[int(bbox_id)].strip()))
  61. f.write('\t\t<pose>Unspecified</pose>\n')
  62. f.write('\t\t<truncated>0</truncated>\n')
  63. f.write('\t\t<difficult>0</difficult>\n')
  64. f.write('\t\t<bndbox>\n')
  65. f.write('\t\t\t<xmin>{}</xmin>\n\t\t\t<ymin>{}</ymin>\n\t\t\t<xmax>{}</xmax>\n\t\t\t<ymax>{}</ymax>\n'.format(int(xmin), int(ymin), int(xmax), int(ymax)))
  66. f.write('\t\t</bndbox>\n')
  67. f.write('\t</object>\n')
  68. f.write('</annotation>')

        2. xml2txt

  1. def XML2txt(input_dir, output_dir, class_txt):
  2. # 获取所有XML文件列表
  3. xml_files = os.listdir(input_dir)
  4. # 获取标注框的类别列表
  5. class_names = []
  6. with open(class_txt, 'r') as classes:
  7. for class_name in classes.readlines():
  8. class_names.append(class_name.split())
  9. # 遍历每个XML文件
  10. for xml_file in xml_files:
  11. # 获取文件名和扩展名
  12. file_name, file_ext = os.path.splitext(xml_file)
  13. # 确保是XML文件
  14. if file_ext == '.xml':
  15. # 解析XML文件并获取标注信息
  16. tree = ET.parse(os.path.join(input_dir, xml_file))
  17. root = tree.getroot()
  18. # 获取图像的最大宽度和高度
  19. max_width = float(root.find('size').find('width').text)
  20. max_height = float(root.find('size').find('height').text)
  21. # 获取标注框的坐标信息
  22. bndbox_coords = []
  23. for obj in root.findall('object'):
  24. bbox_type = obj.find('name').text
  25. type_id = class_name.index(bbox_type)
  26. bndbox = obj.find('bndbox')
  27. xmin = float(bndbox.find('xmin').text)
  28. ymin = float(bndbox.find('ymin').text)
  29. xmax = float(bndbox.find('xmax').text)
  30. ymax = float(bndbox.find('ymax').text)
  31. bndbox_coords.append((type_id, xmin, ymin, xmax, ymax))
  32. # 计算YOLO所需的格式并写入输出文件
  33. with open(os.path.join(output_dir, file_name + '.txt'), 'w') as f:
  34. for coords in bndbox_coords:
  35. type_id, xmin, ymin, xmax, ymax = coords
  36. x_center = (xmin + xmax) / 2 / max_width # x_center字段计算,相对坐标
  37. y_center = (ymin + ymax) / 2 / max_height # y_center字段计算,相对坐标
  38. width = (xmax - xmin) / max_width # width字段(相对宽)计算
  39. height = (ymax - ymin) / max_height # height字段(相对高)计算
  40. f.write('{} {:.6f} {:.6f} {:.6f} {:.6f}\n'.format(type_id, x_center, y_center, width, height))

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/93145
推荐阅读
相关标签
  

闽ICP备14008679号