coco与voc相互转化

把LabelImg标注的YOLO格式标签转化为VOC格式标签 和 把VOC格式标签转化为YOLO格式标签

点亮~黑夜 2020-07-07 11:08:24  3537  已收藏 90
分类专栏: 19—目标检测 文章标签: voc yolo
版权
把LabelImg标注的YOLO格式标签转化为VOC格式标签 和 把VOC格式标签转化为YOLO格式标签

文章目录:
1 用LabelImgvoc和yolo标注标签格式说明
1.1 LabelImg标注的VOC数据格式
1.2 LabelImg标注的YOLO数据格式
2 voc转换为yolo格式计算
3 yolo转换为voc格式计算
4 yolo格式标签转化为voc格式标签代码
5 VOC格式标签转化为YOLO格式标签代码
1 用LabelImgvoc和yolo标注标签格式说明
关于LabelImg工具的使用,参考

1.1 LabelImg标注的VOC数据格式
VOC数据格式,会直接把每张图片标注的标签信息保存到一个xml文件中

例如:我们上面标注的JPEGImage/000001.jpg图片,标注的标签信息会保存到Annotation/000001.xml文件中,000001.xml中的信息如下:

<annotation>
    <folder>JPEGImage</folder>
    <filename>000000.jpg</filename>
    <path>D:\ZF\2_ZF_data\3_stamp_data\标注公章数据\JPEGImage\000000.jpg</path>
    <source>
        <database>Unknown</database>
    </source>
    <size>
        <width>500</width>
        <height>402</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>circle_red</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>168</xmin>
            <ymin>2</ymin>
            <xmax>355</xmax>
            <ymax>186</ymax>
        </bndbox>
    </object>
    <object>
        <name>circle_red</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>2</xmin>
            <ymin>154</ymin>
            <xmax>208</xmax>
            <ymax>367</ymax>
        </bndbox>
    </object>
    <object>
        <name>circle_red</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>305</xmin>
            <ymin>174</ymin>
            <xmax>493</xmax>
            <ymax>364</ymax>
        </bndbox>
    </object>
</annotation>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
xml中的关键信息说明:

图片的名字
每个目标的标定框坐标:即左上角的坐标和右下角的坐标
xmin
ymin
xmax
ymax
1.2 LabelImg标注的YOLO数据格式
YOLO数据格式,会直接把每张图片标注的标签信息保存到一个txt文件中

例如:我们上面标注的JPEGImage/000001.jpg图片,标注的标签信息会保存到Annotation/000001.txt文件中(同时会生成一个classes.txt文件,也保存到Annotation/classes.txt),000001.txt中的信息如下:

0 0.521000 0.235075 0.362000 0.450249
0 0.213000 0.645522 0.418000 0.519900
0 0.794000 0.665423 0.376000 0.470149
1
2
3
txt中信息说明:

每一行代表标注的一个目标
第一个数代表标注目标的标签,第一目标circle_red,对应数字就是0
后面的四个数代表标注框的中心坐标和标注框的相对宽和高(进行了归一化,如何归一化可以参考我的这篇博客中的介绍)
五个数据从左到右以此为:c l a s s _ i n d e x , x _ c e n t e r , y _ c e n t e r , w , h class\_index, x\_center, y\_center, w, hclass_index,x_center,y_center,w,h。(后面的四个数据都是归一化的)
同时会生成一个Annotation/classes.txt实际类别文件classes.txt,里面的内容如下:

circle_red
circle_gray
rectangle_red
rectangle_gray
fingeprint_red
fingeprint_gray
other
1
2
3
4
5
6
7
2 voc转换为yolo格式计算
标注好的VOC格式的标签xml文件,存储的主要信息为:

图片的名字
图片的高height、宽width、通道depth
标定框的坐标位置:xmin、ymin、xmax、ymax
例如下图代表的是一样图片:

红框代表的是原图大小:height=8,width=8
蓝框代表的是标注物体的框:左上角坐标为 (xmin, ymin)=(2,2),右下角的坐标为 (xmax, ymax)=(6,6)

而voc_label.py目的就是把标注为VOC格式数据转化为标注为yolo格式数据:
VOC格式标签:图片的实际宽和高,标注框的左上角和右下角坐标
YOLO格式标签:标注框的中心坐标(归一化的),标注框的宽和高(归一化的)
VOC格式标签转换为YOLO格式标签计算公式:

框中心的实际坐标(x, y):(一般可能还会在后面减去1)
x _ c e n t e r = x m a x + x m i n 2 = 6 + 2 2 = 4 x\_center=\frac{xmax+xmin}{2}=\frac{6+2}{2}=4
x_center= 
2
xmax+xmin
​    
 = 
2
6+2
​    
 =4

y _ c e n t e r = y m a x + y m i n 2 = 6 + 2 2 = 4 y\_center=\frac{ymax+ymin}{2}=\frac{6+2}{2}=4
y_center= 
2
ymax+ymin
​    
 = 
2
6+2
​    
 =4

框归一化后的中心坐标(x, y):
x = x _ c e n t e r w i d t h = 4 8 = 0.5 x=\frac{x\_center}{width}=\frac{4}{8}=0.5
x= 
width
x_center
​    
 = 
8
4
​    
 =0.5

y = y _ c e n t e r h e i g h t = 4 8 = 0.5 y=\frac{y\_center}{height}=\frac{4}{8}=0.5
y= 
height
y_center
​    
 = 
8
4
​    
 =0.5

框的高和框(归一化的):
w = x m a x − x m i n w i d t h = 6 − 2 8 = 0.5 w=\frac{xmax-xmin}{width}=\frac{6-2}{8}=0.5
w= 
width
xmax−xmin
​    
 = 
8
6−2
​    
 =0.5

h = y m a x − y m i n h e i g h t = 6 − 2 8 = 0.5 h=\frac{ymax-ymin}{height}=\frac{6-2}{8}=0.5
h= 
height
ymax−ymin
​    
 = 
8
6−2
​    
 =0.5

3 yolo转换为voc格式计算
voc中保存的坐标信息为:xmin, ymin, xmax, ymax,所以只要根据上面的公式,推导出这四个值即可,推导如下:

推导:xmin, xmax
{ x m a x + x m i n = 2 x _ c e n t e r x m a x − x m i n = w ∗ w i d t h
{xmax+xmin=2x_centerxmax−xmin=w∗width
{xmax+xmin=2x_centerxmax−xmin=w∗width

xmax+xmin=2x_center
xmax−xmin=w∗width
​    
 

{ 2 x m a x = 2 x _ c e n t e r + w ∗ w i d t h = > x m a x = x _ c e n t e r + 1 2 ∗ w ∗ w i d t h 2 x m i n = 2 x _ c e n t e r − w ∗ w i d t h = > x m i n = x _ c e n t e r − 1 2 ∗ w ∗ w i d t h
{2xmax=2x_center+w∗width=>xmax=x_center+12∗w∗width2xmin=2x_center−w∗width=>xmin=x_center−12∗w∗width
{2xmax=2x_center+w∗width=>xmax=x_center+12∗w∗width2xmin=2x_center−w∗width=>xmin=x_center−12∗w∗width

2xmax=2x_center+w∗width=>xmax=x_center+ 
2
1
​    
 ∗w∗width
2xmin=2x_center−w∗width=>xmin=x_center− 
2
1
​    
 ∗w∗width
​    
 

推导:ymin, ymax
{ y m a x + y m i n = 2 y _ c e n t e r y m a x − y m i n = y ∗ h e i g h t
{ymax+ymin=2y_centerymax−ymin=y∗height
{ymax+ymin=2y_centerymax−ymin=y∗height

ymax+ymin=2y_center
ymax−ymin=y∗height
​    
 

{ 2 y m a x = 2 y _ c e n t e r + h ∗ h e i g h t = > y m a x = y _ c e n t e r + 1 2 ∗ h ∗ h e i g h t 2 y m i n = 2 y _ c e n t e r − h ∗ h e i g h t = > y m i n = y _ c e n t e r − 1 2 ∗ h ∗ h e i g h t
{2ymax=2y_center+h∗height=>ymax=y_center+12∗h∗height2ymin=2y_center−h∗height=>ymin=y_center−12∗h∗height
{2ymax=2y_center+h∗height=>ymax=y_center+12∗h∗height2ymin=2y_center−h∗height=>ymin=y_center−12∗h∗height

2ymax=2y_center+h∗height=>ymax=y_center+ 
2
1
​    
 ∗h∗height
2ymin=2y_center−h∗height=>ymin=y_center− 
2
1
​    
 ∗h∗height
​    
 

4 yolo格式标签转化为voc格式标签代码
代码是把txt标签转化为voc标签
代码支持一个标签文件中有多个目标
__Author__ = "Shliang"
__Email__ = "shliang0603@gmail.com"

import os
import xml.etree.ElementTree as ET
from xml.dom.minidom import Document
import cv2


'''
import xml
xml.dom.minidom.Document().writexml()
def writexml(self,
             writer: Any,
             indent: str = "",
             addindent: str = "",
             newl: str = "",
             encoding: Any = None) -> None
'''

class YOLO2VOCConvert:
    def __init__(self, txts_path, xmls_path, imgs_path):
        self.txts_path = txts_path   # 标注的yolo格式标签文件路径
        self.xmls_path = xmls_path   # 转化为voc格式标签之后保存路径
        self.imgs_path = imgs_path   # 读取读片的路径个图片名字,存储到xml标签文件中
        self.classes = ["shirt", "non_shirt", "western_style_clothes", "coat", "down_filled_coat",
                        "cotton", "sweater", "silk_scarf", "tie", "bow_tie"]

    # 从所有的txt文件中提取出所有的类别, yolo格式的标签格式类别为数字 0,1,...
    # writer为True时,把提取的类别保存到'./Annotations/classes.txt'文件中
    def search_all_classes(self, writer=False):
        # 读取每一个txt标签文件,取出每个目标的标注信息
        all_names = set()
        txts = os.listdir(self.txts_path)
        # 使用列表生成式过滤出只有后缀名为txt的标签文件
        txts = [txt for txt in txts if txt.split('.')[-1] == 'txt']
        print(len(txts), txts)
        # 11 ['0002030.txt', '0002031.txt', ... '0002039.txt', '0002040.txt']
        for txt in txts:
            txt_file = os.path.join(self.txts_path, txt)
            with open(txt_file, 'r') as f:
                objects = f.readlines()
                for object in objects:
                    object = object.strip().split(' ')
                    print(object)  # ['2', '0.506667', '0.553333', '0.490667', '0.658667']
                    all_names.add(int(object[0]))
            # print(objects)  # ['2 0.506667 0.553333 0.490667 0.658667\n', '0 0.496000 0.285333 0.133333 0.096000\n', '8 0.501333 0.412000 0.074667 0.237333\n']

        print("所有的类别标签:", all_names, "共标注数据集:%d张" % len(txts))

        # 把从xmls标签文件中提取的类别写入到'./Annotations/classes.txt'文件中
        # if writer:
        #     with open('./Annotations/classes.txt', 'w') as f:
        #         for label in all_names:
        #             f.write(label + '\n')

        return list(all_names)

    def yolo2voc(self):
        # 创建一个保存xml标签文件的文件夹
        if not os.path.exists(self.xmls_path):
            os.mkdir(self.xmls_path)

        # # 读取每张图片,获取图片的尺寸信息(shape)
        # imgs = os.listdir(self.imgs_path)
        # for img_name in imgs:
        #     img = cv2.imread(os.path.join(self.imgs_path, img_name))
        #     height, width, depth = img.shape
        #     # print(height, width, depth)   # h 就是多少行(对应图片的高度), w就是多少列(对应图片的宽度)
        #
        # # 读取每一个txt标签文件,取出每个目标的标注信息
        # all_names = set()
        # txts = os.listdir(self.txts_path)
        # # 使用列表生成式过滤出只有后缀名为txt的标签文件
        # txts = [txt for txt in txts if txt.split('.')[-1] == 'txt']
        # print(len(txts), txts)
        # # 11 ['0002030.txt', '0002031.txt', ... '0002039.txt', '0002040.txt']
        # for txt_name in txts:
        #     txt_file = os.path.join(self.txts_path, txt_name)
        #     with open(txt_file, 'r') as f:
        #         objects = f.readlines()
        #         for object in objects:
        #             object = object.strip().split(' ')
        #             print(object)  # ['2', '0.506667', '0.553333', '0.490667', '0.658667']

        # 把上面的两个循环改写成为一个循环:
        imgs = os.listdir(self.imgs_path)
        txts = os.listdir(self.txts_path)
        txts = [txt for txt in txts if not txt.split('.')[0] == "classes"]  # 过滤掉classes.txt文件
        print(txts)
        # 注意,这里保持图片的数量和标签txt文件数量相等,且要保证名字是一一对应的   (后面改进,通过判断txt文件名是否在imgs中即可)
        if len(imgs) == len(txts):   # 注意:./Annotation_txt 不要把classes.txt文件放进去
            map_imgs_txts = [(img, txt) for img, txt in zip(imgs, txts)]
            txts = [txt for txt in txts if txt.split('.')[-1] == 'txt']
            print(len(txts), txts)
            for img_name, txt_name in map_imgs_txts:
                # 读取图片的尺度信息
                print("读取图片:", img_name)
                img = cv2.imread(os.path.join(self.imgs_path, img_name))
                height_img, width_img, depth_img = img.shape
                print(height_img, width_img, depth_img)   # h 就是多少行(对应图片的高度), w就是多少列(对应图片的宽度)

                # 获取标注文件txt中的标注信息
                all_objects = []
                txt_file = os.path.join(self.txts_path, txt_name)
                with open(txt_file, 'r') as f:
                    objects = f.readlines()
                    for object in objects:
                        object = object.strip().split(' ')
                        all_objects.append(object)
                        print(object)  # ['2', '0.506667', '0.553333', '0.490667', '0.658667']

                # 创建xml标签文件中的标签
                xmlBuilder = Document()
                # 创建annotation标签,也是根标签
                annotation = xmlBuilder.createElement("annotation")

                # 给标签annotation添加一个子标签
                xmlBuilder.appendChild(annotation)

                # 创建子标签folder
                folder = xmlBuilder.createElement("folder")
                # 给子标签folder中存入内容,folder标签中的内容是存放图片的文件夹,例如:JPEGImages
                folderContent = xmlBuilder.createTextNode(self.imgs_path.split('/')[-1])  # 标签内存
                folder.appendChild(folderContent)  # 把内容存入标签
                annotation.appendChild(folder)   # 把存好内容的folder标签放到 annotation根标签下

                # 创建子标签filename
                filename = xmlBuilder.createElement("filename")
                # 给子标签filename中存入内容,filename标签中的内容是图片的名字,例如:000250.jpg
                filenameContent = xmlBuilder.createTextNode(txt_name.split('.')[0] + '.jpg')  # 标签内容
                filename.appendChild(filenameContent)
                annotation.appendChild(filename)

                # 把图片的shape存入xml标签中
                size = xmlBuilder.createElement("size")
                # 给size标签创建子标签width
                width = xmlBuilder.createElement("width")  # size子标签width
                widthContent = xmlBuilder.createTextNode(str(width_img))
                width.appendChild(widthContent)
                size.appendChild(width)   # 把width添加为size的子标签
                # 给size标签创建子标签height
                height = xmlBuilder.createElement("height")  # size子标签height
                heightContent = xmlBuilder.createTextNode(str(height_img))  # xml标签中存入的内容都是字符串
                height.appendChild(heightContent)
                size.appendChild(height)  # 把width添加为size的子标签
                # 给size标签创建子标签depth
                depth = xmlBuilder.createElement("depth")  # size子标签width
                depthContent = xmlBuilder.createTextNode(str(depth_img))
                depth.appendChild(depthContent)
                size.appendChild(depth)  # 把width添加为size的子标签
                annotation.appendChild(size)   # 把size添加为annotation的子标签

                # 每一个object中存储的都是['2', '0.506667', '0.553333', '0.490667', '0.658667']一个标注目标
                for object_info in all_objects:
                    # 开始创建标注目标的label信息的标签
                    object = xmlBuilder.createElement("object")  # 创建object标签
                    # 创建label类别标签
                    # 创建name标签
                    imgName = xmlBuilder.createElement("name")  # 创建name标签
                    imgNameContent = xmlBuilder.createTextNode(self.classes[int(object_info[0])])
                    imgName.appendChild(imgNameContent)
                    object.appendChild(imgName)  # 把name添加为object的子标签

                    # 创建pose标签
                    pose = xmlBuilder.createElement("pose")
                    poseContent = xmlBuilder.createTextNode("Unspecified")
                    pose.appendChild(poseContent)
                    object.appendChild(pose)  # 把pose添加为object的标签

                    # 创建truncated标签
                    truncated = xmlBuilder.createElement("truncated")
                    truncatedContent = xmlBuilder.createTextNode("0")
                    truncated.appendChild(truncatedContent)
                    object.appendChild(truncated)

                    # 创建difficult标签
                    difficult = xmlBuilder.createElement("difficult")
                    difficultContent = xmlBuilder.createTextNode("0")
                    difficult.appendChild(difficultContent)
                    object.appendChild(difficult)

                    # 先转换一下坐标
                    # (objx_center, objy_center, obj_width, obj_height)->(xmin,ymin, xmax,ymax)
                    x_center = float(object_info[1])*width_img + 1
                    y_center = float(object_info[2])*height_img + 1
                    xminVal = int(x_center - 0.5*float(object_info[3])*width_img)   # object_info列表中的元素都是字符串类型
                    yminVal = int(y_center - 0.5*float(object_info[4])*height_img)
                    xmaxVal = int(x_center + 0.5*float(object_info[3])*width_img)
                    ymaxVal = int(y_center + 0.5*float(object_info[4])*height_img)

                    # 创建bndbox标签(三级标签)
                    bndbox = xmlBuilder.createElement("bndbox")
                    # 在bndbox标签下再创建四个子标签(xmin,ymin, xmax,ymax) 即标注物体的坐标和宽高信息
                    # 在voc格式中,标注信息:左上角坐标(xmin, ymin) (xmax, ymax)右下角坐标
                    # 1、创建xmin标签
                    xmin = xmlBuilder.createElement("xmin")  # 创建xmin标签(四级标签)
                    xminContent = xmlBuilder.createTextNode(str(xminVal))
                    xmin.appendChild(xminContent)
                    bndbox.appendChild(xmin)
                    # 2、创建ymin标签
                    ymin = xmlBuilder.createElement("ymin")  # 创建ymin标签(四级标签)
                    yminContent = xmlBuilder.createTextNode(str(yminVal))
                    ymin.appendChild(yminContent)
                    bndbox.appendChild(ymin)
                    # 3、创建xmax标签
                    xmax = xmlBuilder.createElement("xmax")  # 创建xmax标签(四级标签)
                    xmaxContent = xmlBuilder.createTextNode(str(xmaxVal))
                    xmax.appendChild(xmaxContent)
                    bndbox.appendChild(xmax)
                    # 4、创建ymax标签
                    ymax = xmlBuilder.createElement("ymax")  # 创建ymax标签(四级标签)
                    ymaxContent = xmlBuilder.createTextNode(str(ymaxVal))
                    ymax.appendChild(ymaxContent)
                    bndbox.appendChild(ymax)

                    object.appendChild(bndbox)
                    annotation.appendChild(object)  # 把object添加为annotation的子标签
                f = open(os.path.join(self.xmls_path, txt_name.split('.')[0]+'.xml'), 'w')
                xmlBuilder.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
                f.close()


if __name__ == '__main__':
    txts_path1 = './Annotations_txt'
    xmls_path1 = './Annotations_xml'
    imgs_path1 = './JPEGImages'

    yolo2voc_obj1 = YOLO2VOCConvert(txts_path1, xmls_path1, imgs_path1)
    labels = yolo2voc.search_all_classes()
    print('labels: ', labels)
    yolo2voc_obj1.yolo2voc()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
5 VOC格式标签转化为YOLO格式标签代码
代码参考

Github yolov3:https://github.com/AlexeyAB/darknet/blob/master/scripts/voc_label.py
YOLO官网:https://pjreddie.com/media/files/voc_label.py
把标注的VOC格式的.xml标签文件,转化为YOLO格式的txt标签文件

import xml.etree.ElementTree as ET
import pickle
import os
from os import listdir, getcwd
from os.path import join

# classes = ['hard_hat', 'other', 'regular', 'long_hair', 'braid', 'bald', 'beard']

def convert(size, box):
    # size=(width, height)  b=(xmin, xmax, ymin, ymax)
    # x_center = (xmax+xmin)/2        y_center = (ymax+ymin)/2
    # x = x_center / width            y = y_center / height
    # w = (xmax-xmin) / width         h = (ymax-ymin) / height
    
    x_center = (box[0]+box[1])/2.0
    y_center = (box[2]+box[3])/2.0
    x = x_center / size[0]
    y = y_center / size[1]

    w = (box[1] - box[0]) / size[0]
    h = (box[3] - box[2]) / size[1]
    
    # print(x, y, w, h)
    return (x,y,w,h)


def convert_annotation(xml_files_path, save_txt_files_path, classes):  
    xml_files = os.listdir(xml_files_path)
    print(xml_files)
    for xml_name in xml_files:
        print(xml_name)
        xml_file = os.path.join(xml_files_path, xml_name)
        out_txt_path = os.path.join(save_txt_files_path, xml_name.split('.')[0] + '.txt')
        out_txt_f = open(out_txt_path, 'w')
        tree=ET.parse(xml_file)
        root = tree.getroot()
        size = root.find('size')
        w = int(size.find('width').text)
        h = int(size.find('height').text)

        for obj in root.iter('object'):
            difficult = obj.find('difficult').text
            cls = obj.find('name').text
            if cls not in classes or int(difficult) == 1:
                continue
            cls_id = classes.index(cls)
            xmlbox = obj.find('bndbox')
            b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text))
            # b=(xmin, xmax, ymin, ymax)
            print(w, h, b)
            bb = convert((w,h), b)
            out_txt_f.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')


if __name__ == "__main__":
    # 测试程序
    # classes = ['hard_hat', 'other', 'regular', 'long_hair', 'braid', 'bald', 'beard']
    # xml_files = r'D:\ZF\1_ZF_proj\3_脚本程序\2_voc格式转yolo格式\voc_labels'
    # save_txt_files = r'D:\ZF\1_ZF_proj\3_脚本程序\2_voc格式转yolo格式\yolo_labels'
    # convert_annotation(xml_files, save_txt_files, classes)

    #====================================================================================================
    # 把帽子头发胡子的voc的xml标签文件转化为yolo的txt标签文件
    # 1、帽子头发胡子的类别
    classes1 = ['hard_hat', 'other', 'regular', 'long_hair', 'braid', 'bald', 'beard']
    # 2、voc格式的xml标签文件路径
    xml_files1 = r'D:\ZF\2_ZF_data\19_Yolov5_dataset\VOCdevkit_hat_hair_beard_补过标签_合并类别\VOC2007\Annotations_合并类别之后的标签'
    # 3、转化为yolo格式的txt标签文件存储路径
    save_txt_files1 = r'D:\ZF\2_ZF_data\19_Yolov5_dataset\VOCdevkit_hat_hair_beard_yolo\labels'

    convert_annotation(xml_files1, save_txt_files1, classes1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠ ⊕ ♠
————————————————
版权声明:本文为CSDN博主「点亮~黑夜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_41010198/article/details/107175968

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/251943.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

angular中封装fancyBox(图片预览)

首先在官网下载最新版的fancyBox(一定要去最新网站&#xff0c;以前依赖的jquery版本偏低)&#xff0c;附上链接&#xff1a;http://fancyapps.com/fancybox/3/ 然后在项目中引用jquery&#xff0c;然后在引用jquery.fancybox.min.css和jquery.fancybox.min.js。 如果需要动画和…

十二省联考题解 - JLOI2019 题解

十二省联考题解 - JLOI2019 题解 两个T3的难度较大 平均代码量远大于去年省选 套路题考查居多 A 难度等级 1 $n^2$暴力可以拿到$60$分的优秀成绩 然后可以想到把区间异或转化为前缀两点异或 可以想到使用二分答案的方法可持久化Trie解决&#xff0c;但是时间复杂度为$n\log^2 (…

前端vue的get和post请求

vue的get和post需要两个文件vue.js和vue-resource.js 以下是实现的代码&#xff0c;可以参考一下&#xff0c;需要注意的接口的请求需要考虑跨域的问题&#xff0c;其次就是访问页面需要在tomcat下访问&#xff0c;否则也会报跨域的问题 <!DOCTYPE html> <html lang&q…

[Vijos 1143]三取方格数

Description 设有N*N的方格图&#xff0c;我们将其中的某些方格填入正整数&#xff0c; 而其他的方格中放入0。 某人从图得左上角出发&#xff0c;可以向下走&#xff0c;也可以向右走&#xff0c;直到到达右下角。 在走过的路上&#xff0c;他取走了方格中的数。&#xff08;取…

线扫相机相关规格说明

工业线阵相机与面阵相机特点分析 点滴成海~ 2018-06-29 13:50:38 12184 收藏 29 分类专栏&#xff1a; intership 文章标签&#xff1a; 视觉元件分析 版权 最近在公司实习&#xff0c;实习中的项目是使用的是微视的一款线阵相机&#xff08;Microview MVC1024DLM-GE35&…

postgresql 不同数据库不同模式下的数据迁移

编写不容易,转载请注明出处谢谢, 数据迁移 因为之前爬虫的时候&#xff0c;一部分数据并没有上传到服务器&#xff0c;在本地。本来用的就是postgresql&#xff0c;也没用多久&#xff0c;数据迁移的时候&#xff0c;也遇到了很多问题&#xff0c;第一次使pg_dump xx > file…

Oracle中主键自增长

最近在学习Oracle和MySql&#xff0c;MySql有自动配置主键自增长auto_increment&#xff0c;这样在输入数据的时候可以不考虑主键的添加&#xff0c;方便对数据库的操作。 在Oracle中设置自增长首先用到sequence序列&#xff1b; 以创建学生表为例&#xff1a; create table St…

3.单例模式

public class Singleton {//定义私有的静态变量 private static Singleton singleton;//私有化构造函数private Singleton(){}//获取实例public static Singleton getInstance(){//同步前判断避免同步的性能损耗if(nullsingleton){//预防多线程问题synchronized(Singleton.clas…

docker与mmdetection

这里不再介绍 mmdetection 的安装和配置&#xff0c;使用 mmdetection 较简单的方法是使用已安装 mmdetection 的 docker 容器。这样直接省去了安装 mmdetection 的过程&#xff0c;让重心放在模型训练上&#xff01; 如果你对 docker 和 mmdetection 还不是很熟悉&#xff0c…

互联网平台掘金三四五线城市,你需要知道的9.9个真相

互联网上半场结束&#xff0c;一二线城市流量红利消失&#xff0c;许多互联网平台、投资机构一度经历至黑之夜。融资失败、公司倒闭、大裁员迭出。对比鲜明的是&#xff0c;深耕三四五线城市的互联网平台正在迅猛崛起。春节期间&#xff0c;小部分敏锐的业者注意到互联网产品在…

平滑重启更新(GR机制)

平滑重启更新&#xff08;GR机制&#xff09; 什么是平滑启动机制 是一种在协议重启时保证转发业务不中断的机制。什么时候用到平滑重启 平滑重启一般应用于业务更新或者版本发布过程中&#xff0c;能够避免因为代码发布重启服务导致的暂时性服务不可用的影响。ngnix 平滑重启和…

正斜杠( / )和反斜杠( \ )的区别

反斜杠“\”是电脑出现了之后为了表示程序设计里的特殊含义才发明的专用标点。所以除了程序设计领域外&#xff0c;任何地方都不应该使用反斜杠。 如何区分正反斜杠 英语&#xff1a;"/" 英文是forward slash, “\" 是backward slash形象些比喻的话&#xff0c;…

MMDetectionV2 + Colab

MMDetectionV2 Colab 超详细教程及踩坑实录 文章目录 前言一、环境配置二、准备自己的数据集 Aug.14更新三&#xff1a;修改config文件 3.1 文件结构3.2 &#xff08;本地&#xff09;修改config文件 3.2.1 &#xff08;本地&#xff09;构造自己模型的权重文件3.2.2 &#x…

刚刚,OpenStack 第 19 个版本来了,附28项特性详细解读!

刚刚&#xff0c;OpenStack 第 19 个版本来了&#xff0c;附28项特性详细解读&#xff01; OpenStack Stein版本引入了新的多云编排功能&#xff0c;以及帮助实现边缘计算用例的增强功能。 OpenStack由一系列相互关联的项目组成&#xff0c;这些项目可以以不同的组合方式组合在…

SQL作业:综合练习(二)的返评

一&#xff1a;作业题目&#xff1a;综合练习&#xff08;二&#xff09; 二&#xff1a;题目要求&#xff1a; 1、创建数据库CPXS&#xff0c;保存于E盘根目录下以自己学号姓第一个字母&#xff08;阿拉伯数字大写字母&#xff09;方式创建的文件夹中&#xff0c;初始大小5MB&…

caffe cifar10试跑问题总结

caffe cifar10试跑问题总结 [daniel] 写了一个脚本可以直接用来添加环境变量&#xff1a;/Users/songdanzju/daniel_script/export_for_ananconda.sh#! /bin/bash export PATH~/ananconda/bin:$PATH export DYLD_FALLBACK_LIBRARY_PATH~/anaconda:~/anaconda/lib:/usr/local/l…

paddlepaddle-VisualDL2.0对项目进行可视化调参

如果需要更好的阅读体验&#xff0c;可以在ai studio上fork该项目&#xff1a;使用VisualDL2.0对项目进行可视化调参 调参是深度学习必须要做的事情。数据和模型处理好后&#xff0c;需要进行模型训练&#xff0c;这个时候就需要进行调参了。一种好的参数配置&#xff0c;可以…

第一、二次实训作业

1.编写程序&#xff1a; 声明一个整型变量a&#xff0c;并赋初值5&#xff0c;在程序中判断a是奇数还是偶数&#xff0c;然后输出判断的结果。 package 判断奇偶; public class liux { public static void main(String[] args){ int x5; if(x%20){ System.out.println("这…

推荐一款作图工具

以前看到别人的时序图觉得好好看&#xff0c;然后就想这都是用的什么工具画出来的呢&#xff1f;然后看到了一个师兄用的这个工具&#xff0c;真的挺好用的。这是是试用版的界面。类图我觉着看起来效果都挺不错的。转载于:https://www.cnblogs.com/tuhooo/p/8874410.html

【codeforces】【比赛题解】#849 CF Round #431 (Div.2)

cf的比赛越来越有难度了……至少我做起来是这样。 先看看题目吧&#xff1a;点我。 这次比赛是北京时间21:35开始的&#xff0c;算是比较良心。 【A】奇数与结束 "奇数从哪里开始&#xff0c;又在哪里结束&#xff1f;梦想从何处起航&#xff0c;它们又是否会破灭呢&#…