赞
踩
yolo转voc:
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time :2021/8/31 下午3:06
- # @Author :
- # @ProjectName :mmdetection-master
- # @File :yolo2voc.py
- # @Description :
- import os
- import codecs
- import cv2
- import random
- import xml.etree.ElementTree as ET
- from xml.dom.minidom import parse
-
- def vocXMLFormat(filePath, imgName, imgW, imgH, objNames, locs, depth=3, truncated=0, difficult=0):
- """
- Generate xml annotation file,eg:
- vocXMLFormat("0000.xml", "0001.png", 608, 608, ["person", "TV"], [[24, 32, 156, 145], [124, 76, 472, 384]])
- Args:
- filePath:The path of the file saved in the generated xml
- imgName:xml file annotates the name of the picture
- imgW:
- imgH:
- objNames:The object contained in the picture, format: ["object label 1", "object label 2"...]
- locs:The picture contains the coordinates of the object, format: [[x,y,w,h],[x,y,w,h]...]
- depth:
- truncated:
- difficult:
- Returns:
- """
- if (objNames == None) or (locs == None):
- print("The objNames or locs is None!!!")
- return
- with codecs.open(filePath, 'w', 'utf-8') as xml:
- xml.write('<?xml version="1.0" encoding="UTF-8"?>\n')
- xml.write('<annotation>\n')
- xml.write('\t<folder>' + 'voc format' + '</folder>\n')
- xml.write('\t<filename>' + imgName + '</filename>\n')
- xml.write('\t<path>' + imgName + '</path>\n')
- xml.write('\t<source>\n')
- xml.write('\t\t<database>weiz</database>\n')
- xml.write('\t</source>\n')
- xml.write('\t<size>\n')
- xml.write('\t\t<width>' + str(imgW) + '</width>\n')
- xml.write('\t\t<height>' + str(imgH) + '</height>\n')
- xml.write('\t\t<depth>' + str(depth) + '</depth>\n')
- xml.write('\t</size>\n')
- xml.write('\t<segmented>0</segmented>\n')
-
- for ind, name in enumerate(objNames):
- xml.write('\t<object>\n')
- xml.write('\t\t<name>' + name + '</name>\n')
- xml.write('\t\t<pose>Unspecified</pose>\n')
- xml.write('\t\t<truncated>' + str(truncated) + '</truncated>\n')
- xml.write('\t\t<difficult>' + str(difficult) + '</difficult>\n')
- xml.write('\t\t<bndbox>\n')
- xml.write('\t\t\t<xmin>' + str(locs[ind][0]) + '</xmin>\n')
- xml.write('\t\t\t<ymin>' + str(locs[ind][1]) + '</ymin>\n')
- xml.write('\t\t\t<xmax>' + str(locs[ind][0] + locs[ind][2]) + '</xmax>\n')
- xml.write('\t\t\t<ymax>' + str(locs[ind][1] + locs[ind][3]) + '</ymax>\n')
- xml.write('\t\t</bndbox>\n')
- xml.write('\t</object>\n')
-
- xml.write('</annotation>')
- xml.close()
- print("The {} accomplish!".format(filePath))
-
-
- def read_line(file_name):
- """
- read file by line
- :param file_name:
- :return:
- """
- lines = []
- file = open(file_name)
- for line in file:
- line = line.strip('\n')
- lines.append(line)
- file.close()
- return lines
-
-
- def showAnnotions(image, locs, labels):
- """
- show annotions
- :param locs:
- :param labels:
- :return:
- """
- for ind, (x, y, w, h) in enumerate(locs):
- cv2.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2)
- cv2.putText(image, labels[ind], (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 1)
-
- cv2.imshow("iamge", image)
- cv2.waitKey(30)
-
-
- def yolo2voc(txt_path, image_path, save_xml_path, label_path):
- """
- Args:
- txt_path:
- image_path:
- save_xml_path:
- label_path:
- Returns:
- """
- txt_list = os.listdir(txt_path)
- label_list = read_line(label_path)
- for txt_name in txt_list:
- image_name, _ = os.path.splitext(txt_name)
- for extension in ["png", "jpg"]: # read image
- image_name_path = image_name + '.' + extension
- image_name_path = os.path.join(image_path, image_name_path)
- if os.path.exists(image_name_path):
- image = cv2.imread(image_name_path)
- image_h, image_w, image_channel = image.shape
- break
- else:
- continue
-
- txt_name_path = os.path.join(txt_path, txt_name)
- lines = read_line(txt_name_path)
- object_locs = []
- object_labels = []
- for line in lines:
- ind, center_x, center_y, w, h = line.split(' ')
- x = (float(center_x) - float(w) / 2) * image_w
- y = (float(center_y) - float(h) / 2) * image_h
- w = float(w) * image_w
- h = float(h) * image_h
- object_locs.append([int(x), int(y), int(w), int(h)])
- object_labels.append(label_list[int(ind)])
-
- # showAnnotions(image, object_locs, object_labels)
- xml_name_path = os.path.join(save_xml_path, image_name + ".xml")
- vocXMLFormat(xml_name_path, os.path.split(image_name_path)[-1], image_w, image_h, object_labels, object_locs,
- image_channel)
-
-
- def fractionalSet(imagePath, txtSavePath):
- """
- Args:
- imagePath:
- txtSavePath:
- Returns:
- """
- testPercent = 0.1
- valPercent = 0.1
- trainPercent = 0.8
-
- imageNames = os.listdir(imagePath)
- testNum = int(len(imageNames) * testPercent)
- print("testNum:", testNum)
- valNum = int(len(imageNames) * valPercent)
- print("valNum:", valNum)
- trainNum = len(imageNames) - testNum - valNum
- print("trainNum", trainNum)
- trainValNum = trainNum + valNum
- print("trainValNum:", trainValNum)
-
- test = random.sample(imageNames, testNum)
- imageNamesTrainVal = list(set(imageNames) - set(test))
- val = random.sample(imageNamesTrainVal, valNum)
- train = list(set(imageNamesTrainVal) - set(val))
-
- ftrainval_path = os.path.join(txtSavePath, "trainval.txt")
- ftest_path = os.path.join(txtSavePath, "test.txt")
- ftrain_path = os.path.join(txtSavePath, "train.txt")
- fval_path = os.path.join(txtSavePath, "val.txt")
-
- ftrainval = open(ftrainval_path, 'w')
- ftest = open(ftest_path, 'w')
- ftrain = open(ftrain_path, 'w')
- fval = open(fval_path, 'w')
-
- for imageName in imageNames:
- if imageName in test:
- imageName = imageName.split('.')[0] + "\n"
- ftest.write(imageName)
- else:
- if imageName in val:
- imageName = imageName.split('.')[0] + "\n"
- fval.write(imageName)
- else:
- imageName = imageName.split('.')[0] + "\n"
- ftrain.write(imageName)
- ftrainval.write(imageName)
-
- ftrainval.close()
- ftrain.close()
- fval.close()
- ftest.close()
-
-
- def convert(size, box):
- """
- ·µ»Ø¹éÒ»»¯ºóµÄÖÐÐĵ㣬¿í¸ßÖµ
- :param size:
- :param box:
- :return:
- """
- dw = 1./(size[0])
- dh = 1./(size[1])
- x = (box[0] + box[1])/2.0 - 1
- y = (box[2] + box[3])/2.0 - 1
- w = box[1] - box[0]
- h = box[3] - box[2]
- x = x*dw
- w = w*dw
- y = y*dh
- h = h*dh
- return (x,y,w,h)
-
-
- def count_label_num(xml_path):
- """
- Args:
- xml_path:
- Returns:
- """
- classes = []
- num = []
-
- xml_list = os.listdir(xml_path)
- for xml_name in xml_list:
- xml_name_path = os.path.join(xml_path, xml_name)
-
- et = ET.parse(xml_name_path)
- root = et.getroot()
- for obj in root.iter('object'):
- cls = obj.find("name").text
-
- try:
- cls_id = classes.index(cls)
- except ValueError:
- classes.append(cls)
- num.append(0)
- print("add new label:{}".format(cls))
- cls_id = classes.index(cls)
-
- num[cls_id] += 1
-
- return classes, num
-
-
- def checkLabel(imagePath, labelPath):
- """
- Ëæ»ú³é²é¼ì²é±ê×¢Êý¾ÝÊÇ·ñÕýÈ·
- :param imagePath:
- :param labelPath:
- :return:
- """
- labelNames = os.listdir(labelPath)
- while True:
- index = random.randint(0, len(labelNames) - 1)
- labelPath_tmp = os.path.join(labelPath, labelNames[index])
-
- tree = ET.parse(labelPath_tmp)
- root = tree.getroot()
- imageName = root.find('filename').text
- labels = [] # ±êÇ©ÐÅÏ¢[[x,y,w,h,label]]
- for obj in root.iter('object'):
- x1 = int(obj.find("bndbox").find("xmin").text)
- y1 = int(obj.find("bndbox").find("ymin").text)
- x2 = int(obj.find("bndbox").find("xmax").text)
- y2 = int(obj.find("bndbox").find("ymax").text)
- name = obj.find("name").text
- labels.append([x1, y1, x2, y2, name])
-
- imagePath_tmp = os.path.join(imagePath, imageName)
- img = cv2.imread(imagePath_tmp)
- for label in labels:
- cv2.rectangle(img, (label[0], label[1]), (label[2], label[3]), (0, 0, 255))
- cv2.putText(img, label[-1], (label[0], label[1]), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (255, 0, 0), 2)
- cv2.imshow(imageName, img)
- k = cv2.waitKey(0)
-
- # °´Esc¼üÍ˳ö
- if k == 27:
- break
- # °´ÓÒ¼ýÍ·ºÍϼýÍ·¼ÌÐø¼ì²â
- if k != 1 and k != 2:
- if k == 27:
- break
- k = cv2.waitKey(0)
- if k == 27:
- break
- cv2.destroyAllWindows()
-
-
-
- txt_path = "/home/zyy/桌面/label"
- image_path = "./defect4/JPEGImages"
- save_xml_path = "./defect4/Annotations"
- image_sets = "./defect4/ImageSets/Main"
- label_path = "./defect4/label.txt"
- setNames = ["test.txt", "val.txt", "train.txt", "trainval.txt"]
- def main():
- # yolo2voc(txt_path, image_path, save_xml_path, label_path)
- # fractionalSet(image_path, image_sets)
-
- # classes, num = count_label_num(save_xml_path)
- # print(classes)
- # print(num)
-
- checkLabel(image_path, save_xml_path)
-
-
- if __name__ == "__main__":
- main()
- import xml.etree.ElementTree as ET
- import os
- import json
-
- coco = dict()
- coco['images'] = []
- coco['type'] = 'instances'
- coco['annotations'] = []
- coco['categories'] = []
-
- category_set = dict()
- image_set = set()
-
- category_item_id = -1
- image_id = 20180000000
- annotation_id = 0
-
-
- def addCatItem(name):
- global category_item_id
- category_item = dict()
- category_item['supercategory'] = 'none'
- category_item_id += 1
- category_item['id'] = category_item_id
- category_item['name'] = name
- coco['categories'].append(category_item)
- category_set[name] = category_item_id
- return category_item_id
-
-
- def addImgItem(file_name, size):
- global image_id
- if file_name is None:
- raise Exception('Could not find filename tag in xml file.')
- if size['width'] is None:
- raise Exception('Could not find width tag in xml file.')
- if size['height'] is None:
- raise Exception('Could not find height tag in xml file.')
- image_id += 1
- image_item = dict()
- image_item['id'] = image_id
- image_item['file_name'] = file_name
- image_item['width'] = size['width']
- image_item['height'] = size['height']
- coco['images'].append(image_item)
- image_set.add(file_name)
- return image_id
-
-
- def addAnnoItem(object_name, image_id, category_id, bbox):
- global annotation_id
- annotation_item = dict()
- annotation_item['segmentation'] = []
- seg = []
- # bbox[] is x,y,w,h
- # left_top
- seg.append(bbox[0])
- seg.append(bbox[1])
- # left_bottom
- seg.append(bbox[0])
- seg.append(bbox[1] + bbox[3])
- # right_bottom
- seg.append(bbox[0] + bbox[2])
- seg.append(bbox[1] + bbox[3])
- # right_top
- seg.append(bbox[0] + bbox[2])
- seg.append(bbox[1])
-
- annotation_item['segmentation'].append(seg)
-
- annotation_item['area'] = bbox[2] * bbox[3]
- annotation_item['iscrowd'] = 0
- annotation_item['ignore'] = 0
- annotation_item['image_id'] = image_id
- annotation_item['bbox'] = bbox
- annotation_item['category_id'] = category_id
- annotation_id += 1
- annotation_item['id'] = annotation_id
- coco['annotations'].append(annotation_item)
-
-
- def _read_image_ids(image_sets_file):
- ids = []
- with open(image_sets_file) as f:
- for line in f:
- ids.append(line.rstrip())
- return ids
-
-
- def parseXmlFiles_by_txt(data_dir, json_save_path, split='train'):
- """
- Args:
- data_dir:
- json_save_path:
- split: 'train' 'trainval' 'test'
- Returns:
- """
- labelfile = split + ".txt"
- image_sets_file = data_dir + "/ImageSets/Main/" + labelfile
- ids = _read_image_ids(image_sets_file)
-
- for _id in ids:
- xml_file = data_dir + f"/Annotations/{_id}.xml"
-
- bndbox = dict()
- size = dict()
- current_image_id = None
- current_category_id = None
- file_name = None
- size['width'] = None
- size['height'] = None
- size['depth'] = None
-
- tree = ET.parse(xml_file)
- root = tree.getroot()
- if root.tag != 'annotation':
- raise Exception('pascal voc xml root element should be annotation, rather than {}'.format(root.tag))
-
- # elem is <folder>, <filename>, <size>, <object>
- for elem in root:
- current_parent = elem.tag
- current_sub = None
- object_name = None
-
- if elem.tag == 'folder':
- continue
-
- if elem.tag == 'filename':
- file_name = elem.text
- if file_name in category_set:
- raise Exception('file_name duplicated')
-
- # add img item only after parse <size> tag
- elif current_image_id is None and file_name is not None and size['width'] is not None:
- if file_name not in image_set:
- current_image_id = addImgItem(file_name, size)
- print('add image with {} and {}'.format(file_name, size))
- else:
- raise Exception('duplicated image: {}'.format(file_name))
- # subelem is <width>, <height>, <depth>, <name>, <bndbox>
- for subelem in elem:
- bndbox['xmin'] = None
- bndbox['xmax'] = None
- bndbox['ymin'] = None
- bndbox['ymax'] = None
-
- current_sub = subelem.tag
- if current_parent == 'object' and subelem.tag == 'name':
- object_name = subelem.text
- if object_name not in category_set:
- current_category_id = addCatItem(object_name)
- else:
- current_category_id = category_set[object_name]
-
- elif current_parent == 'size':
- if size[subelem.tag] is not None:
- raise Exception('xml structure broken at size tag.')
- size[subelem.tag] = int(subelem.text)
-
- # option is <xmin>, <ymin>, <xmax>, <ymax>, when subelem is <bndbox>
- for option in subelem:
- if current_sub == 'bndbox':
- if bndbox[option.tag] is not None:
- raise Exception('xml structure corrupted at bndbox tag.')
- bndbox[option.tag] = int(option.text)
-
- # only after parse the <object> tag
- if bndbox['xmin'] is not None:
- if object_name is None:
- raise Exception('xml structure broken at bndbox tag')
- if current_image_id is None:
- raise Exception('xml structure broken at bndbox tag')
- if current_category_id is None:
- raise Exception('xml structure broken at bndbox tag')
- bbox = []
- # x
- bbox.append(bndbox['xmin'])
- # y
- bbox.append(bndbox['ymin'])
- # w
- bbox.append(bndbox['xmax'] - bndbox['xmin'])
- # h
- bbox.append(bndbox['ymax'] - bndbox['ymin'])
- print('add annotation with {},{},{},{}'.format(object_name, current_image_id, current_category_id,
- bbox))
- addAnnoItem(object_name, current_image_id, current_category_id, bbox)
- json.dump(coco, open(json_save_path, 'w'))
-
-
- """Ö±½Ó´ÓxmlÎļþ¼ÐÖÐÉú³É"""
-
-
- def parseXmlFiles(xml_path, json_save_path):
- for f in os.listdir(xml_path):
- if not f.endswith('.xml'):
- continue
-
- bndbox = dict()
- size = dict()
- current_image_id = None
- current_category_id = None
- file_name = None
- size['width'] = None
- size['height'] = None
- size['depth'] = None
-
- xml_file = os.path.join(xml_path, f)
- print(xml_file)
-
- tree = ET.parse(xml_file)
- root = tree.getroot()
- if root.tag != 'annotation':
- raise Exception('pascal voc xml root element should be annotation, rather than {}'.format(root.tag))
-
- # elem is <folder>, <filename>, <size>, <object>
- for elem in root:
- current_parent = elem.tag
- current_sub = None
- object_name = None
-
- if elem.tag == 'folder':
- continue
-
- if elem.tag == 'filename':
- file_name = elem.text
- if file_name in category_set:
- raise Exception('file_name duplicated')
-
- # add img item only after parse <size> tag
- elif current_image_id is None and file_name is not None and size['width'] is not None:
- if file_name not in image_set:
- current_image_id = addImgItem(file_name, size)
- print('add image with {} and {}'.format(file_name, size))
- else:
- raise Exception('duplicated image: {}'.format(file_name))
- # subelem is <width>, <height>, <depth>, <name>, <bndbox>
- for subelem in elem:
- bndbox['xmin'] = None
- bndbox['xmax'] = None
- bndbox['ymin'] = None
- bndbox['ymax'] = None
-
- current_sub = subelem.tag
- if current_parent == 'object' and subelem.tag == 'name':
- object_name = subelem.text
- if object_name not in category_set:
- current_category_id = addCatItem(object_name)
- else:
- current_category_id = category_set[object_name]
-
- elif current_parent == 'size':
- if size[subelem.tag] is not None:
- raise Exception('xml structure broken at size tag.')
- size[subelem.tag] = int(subelem.text)
-
- # option is <xmin>, <ymin>, <xmax>, <ymax>, when subelem is <bndbox>
- for option in subelem:
- if current_sub == 'bndbox':
- if bndbox[option.tag] is not None:
- raise Exception('xml structure corrupted at bndbox tag.')
- bndbox[option.tag] = int(option.text)
-
- # only after parse the <object> tag
- if bndbox['xmin'] is not None:
- if object_name is None:
- raise Exception('xml structure broken at bndbox tag')
- if current_image_id is None:
- raise Exception('xml structure broken at bndbox tag')
- if current_category_id is None:
- raise Exception('xml structure broken at bndbox tag')
- bbox = []
- # x
- bbox.append(bndbox['xmin'])
- # y
- bbox.append(bndbox['ymin'])
- # w
- bbox.append(bndbox['xmax'] - bndbox['xmin'])
- # h
- bbox.append(bndbox['ymax'] - bndbox['ymin'])
- print('add annotation with {},{},{},{}'.format(object_name, current_image_id, current_category_id,
- bbox))
- addAnnoItem(object_name, current_image_id, current_category_id, bbox)
- json.dump(coco, open(json_save_path, 'w'))
-
-
- if __name__ == '__main__':
- # 下面三个test.json、train.json、val.json只能一个一个运行
- voc_data_dir = "./defect4"
- json_save_path = "./defect4/test.json"
- parseXmlFiles_by_txt(voc_data_dir, json_save_path, "test")
-
- # json_save_path = "./defect4/train.json"
- # parseXmlFiles_by_txt(voc_data_dir, json_save_path, "train")
-
- # json_save_path = "./defect4/val.json"
- # parseXmlFiles_by_txt(voc_data_dir, json_save_path, "val")
-
- # ann_path = "E:/VOCdevkit/VOC2007/Annotations"
- # json_save_path = "E:/VOCdevkit/test.json"
- # parseXmlFiles(ann_path, json_save_path)
voc数据删除指定类别或更改类别名称
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- # @Time :2023/8/8 9:08
- # @Author :weiz
- # @ProjectName :jiangling_new
- # @File :xml_process.py
- # @Description :
- # Copyright (C) 2021-2025 Jiangxi Institute Of Intelligent Industry Technology Innovation
- import os
- import xml.dom.minidom
- import xml.etree.cElementTree as ET
-
-
- def delete_specified_cls(xmlFolderPath, xmlSavePath, delete_cls):
- xml_list = os.listdir(xmlFolderPath)
-
- for xml_name in xml_list:
- xml_tree = ET.parse(os.path.join(xmlFolderPath, xml_name))
- xml_root = xml_tree.getroot()
-
- total_class_num = 0
- class_del_num = 0
-
- for xml_child in xml_root.findall("object"):
-
- total_class_num = total_class_num + 1
-
- old_cls = xml_child.find("name").text
- if old_cls in delete_cls:
- class_del_num = class_del_num + 1
- xml_root.remove(xml_child)
- if total_class_num == class_del_num:
- print("类别全部被删除了,请删除该文件及对应的图片:", xml_name)
- xml_tree.write(os.path.join(xmlSavePath, xml_name))
- else:
- xml_tree.write(os.path.join(xmlSavePath, xml_name))
- print(xml_name, "删除指定类别成功")
-
-
- def change_class_name(xmlFolderPath, xmlSavePath, old_class, new_class):
- """
- voc 数据类别替换
- :param xmlFolderPath:
- :param xmlSavePath:
- :param old_class:
- :param new_class:
- :return:
- """
- xml_list = os.listdir(xmlFolderPath)
-
- for xml_name in xml_list:
- xml_dom = xml.dom.minidom.parse(os.path.join(xmlFolderPath, xml_name))
- root = xml_dom.documentElement
- newfilename = root.getElementsByTagName('name')
- for i, node in enumerate(newfilename):
- for j, cls in enumerate(old_class):
- if node.firstChild.data == cls:
- newfilename[i].firstChild.data = new_class[j]
-
- with open(os.path.join(xmlSavePath, xml_name), 'w') as fh:
- xml_dom.writexml(fh)
- print(xml_name, "文件类别替换成功")
-
-
- g_delete_cls = ["spare_tire"]
- # g_old_class = ["EKS_18_19", "EKS_20寸", "743出口", "743国内", "743BEV", "756"]
- # g_new_class = ["NS1-1532-EA", "NS1-1352-DB", "MS1-1532-BA", "FS1-1532-AC", "KS2-1352-AA", "KS1-1532-AA"]
- # g_old_class = ["fuel_92", "fuel_91", "fuel_87", "gasolina", "fuel_91_ron"]
- # g_new_class = ["FS1-9A095-AB", "LK29-9A095-BA", "NS1-9A095-CA", "MS1-9A095-AA", "NS1-9A095-AA"]
- g_old_class = ["strchromium", "nonchromium"]
- g_new_class = ["KS1-D13210-BFD1", "KS1-D13210-ADD1"]
- g_xmlFolderPath = r"E:\江铃工业相机及手机采集数据\FL09\燃油标签\Annotations"
- g_xmlSavePath = r"E:\江铃工业相机及手机采集数据\FL09\燃油标签\Annotations"
- if __name__ == "__main__":
- change_class_name(g_xmlFolderPath, g_xmlSavePath, g_old_class, g_new_class)
-
- #delete_specified_cls(g_xmlFolderPath, g_xmlSavePath, g_delete_cls)
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。