涉及到的格式转换包括:
1.yolo to voc#示例
#[输入格式] [输出格式] [JPEGImages路径] [labels路径] [Annotations路径] [voc.names路径]
python geshi.py yolo voc C:/Users/Desktop/testdata/JPEGImages/ C:/Users/Desktop/testdata/labels/ C:/Users/Desktop/testdata/Annotations/ C:/Users/Desktop/testdata/voc.names
2.voc to yolo#
#[输入格式] [输出格式] [voc的路径(包含Annotations,JPEGImages)] [输出路径] [标签1] [标签n]
python geshi.py voc yolo C:/Users/Desktop/testdata/ C:/Users/Desktop/testdata/labels/ ship car person
3.dota to voc#示例
#[输入格式] [输出格式] [dota的label路径] [dota的影像路径] [输出的标注文件]
python geshi.py dota voc C:/Users/Desktop/testdata/dota/labels/ C:/Users/Desktop/testdata/dota/JPEGImages/ C:/Users/Desktop/testdata/dota/Annotations/
4.voc to data#示例
#[输入格式] [输出格式] [voc的label路径] [输出的label路径]
python geshi.py voc dota C:/Users/Desktop/testdata/dota/Annotations/ C:/Users/Desktop/testdata/dota/Annotations/txtlabel/
5.voc to coco#示例
#[输入格式] [输出格式] [voc label路径] [输出coco的json]
python geshi.py voc coco C:/Users/Desktop/testdata/voc_tmp/ C:/Users/Desktop/testdata/train_test.json
6.coco to voc#示例
#[输入格式] [输出格式] [coco的json] [输出voc label路径]
python geshi.py coco voc C:/Users/Desktop/testdata/data/train.json C:/Users/Desktop/testdata/data/Annotations/
7.yolo to coco#示例
#[输入格式] [输出格式] [标注文件txt存储路径] [json文件输出的文件夹] [图片路径] [voc.names路径] [json文件名字]
python geshi.py yolo coco C:/Users/Desktop/testdata/data/labels/ C:/Users/Desktop/testdata/data/coco/ C:/Users/Desktop/testdata/data/JPEGImages/ C:/Users/Desktop/testdata/data/labels/voc.names trainyolo.json
8.coco to yolo#示例
#[输入格式] [输出格式] [json路径] [输出yolo label的路径]
python geshi.py coco yolo C:/Users/Desktop/testdata/train.json C:/Users/Desktop/testdata/yolo_new/
9.coco to dota#示例
#[输入格式] [输出格式] [json路径] [输出dota label的路径]
python geshi.py coco yolo C:/Users/qiaomengyu/Desktop/testdata/train.json C:/Users/qiaomengyu/Desktop/testdata/dota_new/
10.dota to coco#示例
#[输入格式] [输出格式] [dota label的路径] [图片路径] [存储的json路径]
python geshi.py dota coco C:/Users/qiaomengyu/Desktop/testdata/dota_new/ C:/Users/qiaomengyu/Desktop/testdata/data/JPEGimages/ C:/Users/qiaomengyu/Desktop/testdata/tarin_new.json
11.dota to yolo#示例
#[输入格式] [输出格式] [dota label的路径] [图片路径] [存储的yolo label路径]
python geshi.py dota yolo C:/Users/qiaomengyu/Desktop/testdata/dota_new/ C:/Users/qiaomengyu/Desktop/testdata/data/JPEGimages/ C:/Users/qiaomengyu/Desktop/testdata/yolo_test11/
12.yolo to dota示例
#[输入格式] [输出格式] [yolo label路径] [存储的标签路径] [生成的voc.anmes路径]
python geshi.py yolo dota C:/Users/qiaomengyu/Desktop/testdata/data/JPEGimages/ C:/Users/qiaomengyu/Desktop/testdata/yolo_new/ C:/Users/qiaomengyu/Desktop/testdata/voc_tmp/ C:/Users/qiaomengyu/Desktop/testdata/voc.names
import sys
from importlib.resources import read_text
import os
import xml.etree.ElementTree as ET
from PIL import Image
import numpy as np
from os import listdir, getcwd
from pathlib import Path
from xml.dom.minidom import Document
from xml.dom.minidom import parse
import xml.dom.minidom
import numpy as np
import csv
import cv2
import string
import math
from pycocotools.coco import COCO
import json
from datetime import datetime
import argparse
from lxml import etree, objectify
import shutil
from pathlib import Path
######################################################yolo to voc#########################################################
def read_txt(labels_path,voc_path):
labels = os.listdir(labels_path)
f = open(voc_path, "r")
line = f.read().splitlines()
classes_str = line
print(' [Info]_Load class name: '+str(line),flush=True)
f.close()
# Classes
classes = classes_str
# Image height width deepth
sh = sw = sd = 0
files_label = os.listdir(labels_path)
file_num = len(files_label)
i = 1
if len(labels) is 0:
print(' [Info]_labels file is not found',flush=True)
else:
jindu_int = 0
jindu_flag = 0
for label in labels:
try:
with open(labels_path + label, 'r') as f:
img_id = os.path.splitext(label)[0]
contents = f.readlines()
labeldicts = []
#str_jindu = str((i/file_num)*100)+'%'
jindu_tmp = (i/file_num)*100
jindu_int = int(float(jindu_tmp)/2)
#print(jindu_int)
if jindu_int > jindu_flag:
print(' [Percentage]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
if i == file_num:
print(' [Info]_Dataset format conversion completed',flush=True)
i = i+1
for content in contents:
# input image format
flag_panduan = False
if os.path.exists(img_path + label.strip('.txt') + '.jpg') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.jpg'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.JPG') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.JPG'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.jpeg') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.jpeg'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.JPEG') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.JPEG'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.png') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.png'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.PNG') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.PNG'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.bmp') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.bmp'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.BMP') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.BMP'))
flag_panduan = True
# image height width
if flag_panduan == False:
print("[Info]_The '" + label+"' corresponding image file was not found!")
break
sh, sw, sd = img.shape[0], img.shape[1], img.shape[2]
content = content.strip('\n').split()
x = float(content[1])*sw
y = float(content[2])*sh
w = float(content[3])*sw
h = float(content[4])*sh
# coordinate transition, x_center y_center width height -> xmin ymin xmax ymax
try:
new_dict = {'name': classes[int(content[0])],
'difficult': '0',
'xmin': x+1-w/2,
'ymin': y+1-h/2,
'xmax': x+1+w/2,
'ymax': y+1+h/2
}
labeldicts.append(new_dict)
except IndexError:
print(" [Error]_voc.names classes no match txt file, xml file generate error, Please Check")
#names里的类别数少,txt里标注的类别数多,txt里读出来的类别在names找不到
sys.exit(0)
write_xml_yolo2dota(img_id, sw, sh, sd, annotations_path + label.strip('.txt') + '.xml', labeldicts)
except PermissionError:
print("[Info]_The label folders contain non-labeled data '"+labels_path + label+"'")
def write_xml(imgname, sw, sh, sd, filepath, labeldicts):
# 创建Annotation根节点
root = ET.Element('Annotation')
# 创建filename子节点,无扩展名
ET.SubElement(root, 'filename').text = str(imgname)
# 创建size子节点
sizes = ET.SubElement(root,'size')
ET.SubElement(sizes, 'width').text = str(sw)
ET.SubElement(sizes, 'height').text = str(sh)
ET.SubElement(sizes, 'depth').text = str(sd)
for labeldict in labeldicts:
objects = ET.SubElement(root, 'object')
ET.SubElement(objects, 'name').text = labeldict['name']
ET.SubElement(objects, 'pose').text = 'Unspecified'
ET.SubElement(objects, 'truncated').text = '0'
ET.SubElement(objects, 'difficult').text = '0'
bndbox = ET.SubElement(objects,'bndbox')
ET.SubElement(bndbox, 'xmin').text = str(int(labeldict['xmin']))
ET.SubElement(bndbox, 'ymin').text = str(int(labeldict['ymin']))
ET.SubElement(bndbox, 'xmax').text = str(int(labeldict['xmax']))
ET.SubElement(bndbox, 'ymax').text = str(int(labeldict['ymax']))
tree = ET.ElementTree(root)
tree.write(filepath, encoding='utf-8')
#########################################################voc to yolo######################################################
def listdir(path, list_name):
for file in os.listdir(path):
file_path = os.path.join(path, file)
if os.path.isdir(file_path):
listdir(file_path, list_name)
else:
list_name.append(file_path)
def voc_label(voc_data_path,label_save_path,class_str,class_list):
sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
#classes = ["plane", "ship", "harbor", "tennis-court", "soccer-ball-field", "ground-track-field", "storage-tank", "bridge"]
#classes = ["sar_ship"]
classes = class_str
print(' [Info]_Load class name:' +classes)
wd = getcwd()
xml_data_path = voc_data_path +'Annotations/'
jpg_data_path = voc_data_path +'JPEGImages/'
if os.path.exists(xml_data_path) == False:
print(' [info]_The Annotations path is not exist, please check and try again',flush=True)
exit()
if os.path.exists(jpg_data_path) == False:
print(' [info]_The JPEGImages path is not exist, please check and try again',flush=True)
exit()
xml_list_name = []
jpg_list_name = []
listdir(xml_data_path,xml_list_name)
listdir(jpg_data_path,jpg_list_name)
if not os.path.exists(label_save_path):
os.makedirs(label_save_path)
jishu = 0
jindu_int = 0
jindu_flag = 0
for ii in xml_list_name:
image_id = Path(ii).stem
convert_annotation(voc_data_path, image_id,classes,class_list,label_save_path)
jindu_tmp = ((jishu/len(xml_list_name)))*100
jindu_int = int(jindu_tmp)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
print('[Percent]_100'+'%',flush=True)
def convert(size, box):
dw = 1./size[0]
dh = 1./size[1]
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
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 convert_annotation(data_path, image_id,classes,class_list,label_save_path):
in_file = open(data_path + '/Annotations/%s.xml'%(image_id))
#out_file = open(data_path + 'labels/%s.txt'%(image_id), 'w')
out_file = open(label_save_path+ '%s.txt'%(image_id), 'w')
tree=ET.parse(in_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 class_list or int(difficult) == 1:
continue
cls_id = class_list.index(cls)
#print(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))
bb = convert((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
#######################################################dota to voc########################################################
def dota_load(txt_path,img_path,xml_path):
jishu = 0
jindu_int = 0
jindu_flag = 0
txts = os.listdir(txt_path)
for count, t in enumerate(txts):
try:
boxes, labels = load_annoataion(os.path.join(txt_path, t))
xml_name = t.replace('.txt', '.xml')
img_name = t.replace('.txt', '.png')
if os.path.exists(os.path.join(img_path, img_name)) == False:
img_name = t.replace('.txt', '.jpg')
if os.path.exists(os.path.join(img_path, img_name)) == False:
img_name = t.replace('.txt', '.jpeg')
if os.path.exists(os.path.join(img_path, img_name)) == False:
img_name = t.replace('.txt', '.tif')
if os.path.exists(os.path.join(img_path, img_name)) == False:
img_name = t.replace('.txt', '.tiff')
if os.path.exists(os.path.join(img_path, img_name)) == False:
print("[Info]_The '"+ xml_name +"' no corresponding image file was found")
break
#print(img_name)
img = cv2.imread(os.path.join(img_path, img_name))
h, w, d = img.shape
#print(xml_name, xml_path, boxes, labels, w, h, d)
WriterXMLFiles(xml_name, xml_path, boxes, labels, w, h, d)
jindu_tmp = ((jishu/len(txts)))*100
jindu_int = int(jindu_tmp)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
except TypeError:
print("[Info]_The dataset folder contains non-data files '" +os.path.join(txt_path, t)+"'")
print(' [Percent]_100%')
def WriterXMLFiles(filename, path, box_list, label_list, w, h, d):
# dict_box[filename]=json_dict[filename]
doc = xml.dom.minidom.Document()
root = doc.createElement('annotation')
doc.appendChild(root)
foldername = doc.createElement("folder")
foldername.appendChild(doc.createTextNode("JPEGImages"))
root.appendChild(foldername)
nodeFilename = doc.createElement('filename')
nodeFilename.appendChild(doc.createTextNode(filename))
root.appendChild(nodeFilename)
pathname = doc.createElement("path")
pathname.appendChild(doc.createTextNode("xxxx"))
root.appendChild(pathname)
sourcename=doc.createElement("source")
databasename = doc.createElement("database")
databasename.appendChild(doc.createTextNode("Unknown"))
sourcename.appendChild(databasename)
annotationname = doc.createElement("annotation")
annotationname.appendChild(doc.createTextNode("xxx"))
sourcename.appendChild(annotationname)
imagename = doc.createElement("image")
imagename.appendChild(doc.createTextNode("xxx"))
sourcename.appendChild(imagename)
flickridname = doc.createElement("flickrid")
flickridname.appendChild(doc.createTextNode("0"))
sourcename.appendChild(flickridname)
root.appendChild(sourcename)
nodesize = doc.createElement('size')
nodewidth = doc.createElement('width')
nodewidth.appendChild(doc.createTextNode(str(w)))
nodesize.appendChild(nodewidth)
nodeheight = doc.createElement('height')
nodeheight.appendChild(doc.createTextNode(str(h)))
nodesize.appendChild(nodeheight)
nodedepth = doc.createElement('depth')
nodedepth.appendChild(doc.createTextNode(str(d)))
nodesize.appendChild(nodedepth)
root.appendChild(nodesize)
segname = doc.createElement("segmented")
segname.appendChild(doc.createTextNode("0"))
root.appendChild(segname)
for (box, label) in zip(box_list, label_list):
nodeobject = doc.createElement('object')
nodename = doc.createElement('name')
nodename.appendChild(doc.createTextNode(str(label)))
nodeobject.appendChild(nodename)
nodename = doc.createElement('pose')
nodename.appendChild(doc.createTextNode("Unspecified"))
nodeobject.appendChild(nodename)
nodename = doc.createElement('truncated')
nodename.appendChild(doc.createTextNode("0"))
nodeobject.appendChild(nodename)
nodename = doc.createElement('difficult')
nodename.appendChild(doc.createTextNode("0"))
nodeobject.appendChild(nodename)
x_list = []
y_list = []
x_list.append(box[0])
x_list.append(box[2])
x_list.append(box[4])
x_list.append(box[6])
y_list.append(box[1])
y_list.append(box[3])
y_list.append(box[5])
y_list.append(box[7])
max_x = max(x_list)
min_x = min(x_list)
max_y = max(y_list)
min_y = min(y_list)
nodebndbox = doc.createElement('bndbox')
nodex1 = doc.createElement('xmin')
nodex1.appendChild(doc.createTextNode(str(min_x)))
nodebndbox.appendChild(nodex1)
nodex2 = doc.createElement('ymin')
nodex2.appendChild(doc.createTextNode(str(min_y)))
nodebndbox.appendChild(nodex2)
nodey3 = doc.createElement('xmax')
nodey3.appendChild(doc.createTextNode(str(max_x)))
nodebndbox.appendChild(nodey3)
nodex4 = doc.createElement('ymax')
nodex4.appendChild(doc.createTextNode(str(max_y)))
nodebndbox.appendChild(nodex4)
nodeobject.appendChild(nodebndbox)
root.appendChild(nodeobject)
fp = open(path + filename, 'w')
doc.writexml(fp, indent='\n')
fp.close()
def load_annoataion(p):
'''
load annotation from the text file
:param p:
:return:
'''
text_polys = []
text_tags = []
if not os.path.exists(p):
return np.array(text_polys, dtype=np.float32)
try:
with open(p, 'r') as f:
#for line in f.readlines()[2:]:
for line in f.readlines():
label = 'text'
# strip BOM. \ufeff for python3, \xef\xbb\bf for python2
#line = [i.strip('\ufeff').strip('\xef\xbb\xbf') for i in line]
#print(line)
x1, y1, x2, y2, x3, y3, x4, y4 ,label= line.split(' ')[0:9]
#print(label)
text_polys.append([float(x1), float(y1), float(x2), float(y2), float(x3), float(y3), float(x4), float(y4)])
text_tags.append(label)
return np.array(text_polys, dtype=np.int32), np.array(text_tags, dtype=np.str)
except PermissionError:
pass
#########################################################voc to data######################################################
def voc_to_dota(xml_path, xml_name,save_path):
txt_name = xml_name[:-4] + '.txt'
txt_path = save_path
if not os.path.exists(txt_path):
os.makedirs(txt_path)
txt_file = os.path.join(txt_path, txt_name)
file_path = os.path.join(xml_path, file_list[i])
tree = ET.parse(os.path.join(file_path))
root = tree.getroot()
# print(root[6][0].text)
with open(txt_file, "w+", encoding='UTF-8') as out_file:
# out_file.write('imagesource:null' + '\n' + 'gsd:null' + '\n')
for obj in root.findall('object'):
name = obj.find('name').text
#difficult = obj.find('difficult').text
# print(name, difficult)
robndbox = obj.find('bndbox')
xmin = int(robndbox.find('xmin').text)
ymin = int(robndbox.find('ymin').text)
xmax = int(robndbox.find('xmax').text)
ymax = int(robndbox.find('ymax').text)
p0x = xmin
p0y = ymin
p1x = xmax
p1y = ymin
p2x = xmax
p2y = ymax
p3x = xmin
p3y = ymax
'''
cx = float(robndbox.find('cx').text)
cy = float(robndbox.find('cy').text)
w = float(robndbox.find('w').text)
h = float(robndbox.find('h').text)
angle = float(robndbox.find('angle').text)
# print(cx, cy, w, h, angle)
p0x, p0y = rotatePoint(cx, cy, cx - w / 2, cy - h / 2, -angle)
p1x, p1y = rotatePoint(cx, cy, cx + w / 2, cy - h / 2, -angle)
p2x, p2y = rotatePoint(cx, cy, cx + w / 2, cy + h / 2, -angle)
p3x, p3y = rotatePoint(cx, cy, cx - w / 2, cy + h / 2, -angle)
'''
data = str(p0x) + " " + str(p0y) + " " + str(p1x) + " " + str(p1y) + " " + \
str(p2x) + " " + str(p2y) + " " + str(p3x) + " " + str(p3y) + " "
#data = data + name + " " + difficult + "\n"
data = data + name + " "+ '0' + "\n"
out_file.write(data)
# 转换成四点坐标
def rotatePoint(xc, yc, xp, yp, theta):
xoff = xp - xc
yoff = yp - yc
cosTheta = math.cos(theta)
sinTheta = math.sin(theta)
pResx = cosTheta * xoff + sinTheta * yoff
pResy = - sinTheta * xoff + cosTheta * yoff
# pRes = (xc + pResx, yc + pResy)
# 保留一位小数点
# return xc + pResx, yc + pResy
return float(format(xc + pResx, '.1f')), float(format(yc + pResy, '.1f'))
#######################################################voc to coco########################################################
def addCatItem_c(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_c(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']
image_item['license'] = None
image_item['flickr_url'] = None
image_item['coco_url'] = None
image_item['date_captured'] = str(datetime.today())
coco['images'].append(image_item)
image_set.add(file_name)
return image_id
def addAnnoItem_c(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_c(image_sets_file):
ids = []
with open(image_sets_file, 'r') as f:
for line in f.readlines():
ids.append(line.strip())
return ids
def parseXmlFilse_c(data_dir, json_save_path):
assert os.path.exists(data_dir), "data path:{} does not exist".format(data_dir)
xml_files_list = []
if os.path.isdir(data_dir):
# 修改此处xml的路径即可
# xml_dir = os.path.join(data_dir,"labels/voc")
xml_dir = data_dir
xml_list = os.listdir(xml_dir)
xml_files_list = [os.path.join(xml_dir, i) for i in xml_list]
else:
print(' [Error]_The voc path is no exist, please check and try again')
exit()
jishu = 0
jindu_int = 0
jindu_flag = 0
for xml_file in xml_files_list:
jindu_tmp = ((jishu/len(xml_files_list)))*100
jindu_int = int(jindu_tmp)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
if not xml_file.endswith('.xml'):
continue
tree = ET.parse(xml_file)
root = tree.getroot()
# 初始化
size = dict()
size['width'] = None
size['height'] = None
if root.tag != 'annotation' and root.tag != 'Annotation':
raise Exception('pascal voc xml root element should be Annotation, rather than {}'.format(root.tag))
# 提取图片名字
file_name = root.findtext('filename')
file_name = os.path.splitext(file_name)[0]
assert file_name is not None, "filename is not in the file"
# 提取图片 size {width,height,depth}
size_info = root.findall('size')
assert size_info is not None, "size is not in the file"
for subelem in size_info[0]:
size[subelem.tag] = int(subelem.text)
if file_name is not None and size['width'] is not None and file_name not in image_set:
# 添加coco['image'],返回当前图片ID
current_image_id = addImgItem_c(file_name, size)
#print('add image with name: {}\tand\tsize: {}'.format(file_name, size))
#################################
# 打印目标信息
#################################
elif file_name in image_set:
raise Exception('file_name duplicated')
else:
raise Exception("file name:{}\t size:{}".format(file_name, size))
# 提取一张图片内所有目标object标注信息
object_info = root.findall('object')
if len(object_info) == 0:
continue
# 遍历每个目标的标注信息
for object in object_info:
# 提取目标名字
object_name = object.findtext('name')
if object_name not in category_set:
# 创建类别索引
current_category_id = addCatItem_c(object_name)
else:
current_category_id = category_set[object_name]
# 初始化标签列表
bndbox = dict()
bndbox['xmin'] = None
bndbox['xmax'] = None
bndbox['ymin'] = None
bndbox['ymax'] = None
# 提取box:[xmin,ymin,xmax,ymax]
bndbox_info = object.findall('bndbox')
for box in bndbox_info[0]:
bndbox[box.tag] = int(box.text)
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 object_name:{}\timage_id:{}\tcat_id:{}\tbbox:{}'.format(object_name, current_image_id,current_category_id,bbox))
addAnnoItem_c(object_name, current_image_id, current_category_id, bbox)
json_parent_dir = os.path.dirname(json_save_path)
if not os.path.exists(json_parent_dir):
os.makedirs(json_parent_dir)
json.dump(coco, open(json_save_path, 'w'))
print('[Percent]_100'+'%',flush=True)
#print("class nums:{}".format(len(coco['categories'])))
#print("image nums:{}".format(len(coco['images'])))
#print("bbox nums:{}".format(len(coco['annotations'])))
#######################################################coco to voc########################################################
# 将类别名字和id建立索引
def catid2name(coco):
classes = dict()
for cat in coco.dataset['categories']:
classes[cat['id']] = cat['name']
return classes
# 将标签信息写入xml
def save_anno_to_xml(filename, size, objs, save_path):
E = objectify.ElementMaker(annotate=False)
anno_tree = E.annotation(
E.folder("DATA"),
E.filename(filename),
E.source(
E.database("The VOC Database"),
E.annotation("PASCAL VOC"),
E.image("flickr")
),
E.size(
E.width(size['width']),
E.height(size['height']),
E.depth(size['depth'])
),
E.segmented(0)
)
for obj in objs:
E2 = objectify.ElementMaker(annotate=False)
anno_tree2 = E2.object(
E.name(obj[0]),
E.pose("Unspecified"),
E.truncated(0),
E.difficult(0),
E.bndbox(
E.xmin(obj[1]),
E.ymin(obj[2]),
E.xmax(obj[3]),
E.ymax(obj[4])
)
)
anno_tree.append(anno_tree2)
filename = Path(filename).stem
anno_path = os.path.join(save_path, filename+ ".xml")
etree.ElementTree(anno_tree).write(anno_path, pretty_print=True)
# 利用cocoAPI从json中加载信息
def load_coco(anno_file, xml_save_path):
if os.path.exists(xml_save_path):
#shutil.rmtree(xml_save_path)
print(" [Error]_The annotions file is exist!")
else:
os.makedirs(xml_save_path)
coco = COCO(anno_file)
classes = catid2name(coco)
imgIds = coco.getImgIds()
classesIds = coco.getCatIds()
#for imgId in tqdm(imgIds):
jishu = 0
jindu_int = 0
jindu_flag = 0
for imgId in imgIds:
size = {}
img = coco.loadImgs(imgId)[0]
filename = img['file_name']
width = img['width']
height = img['height']
size['width'] = width
size['height'] = height
size['depth'] = 3
annIds = coco.getAnnIds(imgIds=img['id'], iscrowd=None)
anns = coco.loadAnns(annIds)
objs = []
for ann in anns:
object_name = classes[ann['category_id']]
# bbox:[x,y,w,h]
bbox = list(map(int, ann['bbox']))
xmin = bbox[0]
ymin = bbox[1]
xmax = bbox[0] + bbox[2]
ymax = bbox[1] + bbox[3]
obj = [object_name, xmin, ymin, xmax, ymax]
objs.append(obj)
save_anno_to_xml(filename, size, objs, xml_save_path)
jindu_tmp = ((jishu/len(imgIds)))*100
jindu_int = int(jindu_tmp)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
print('[Percent]_100'+'%',flush=True)
def parseJsonFile(data_dir, xmls_save_path):
assert os.path.exists(data_dir), "data dir:{} does not exits".format(data_dir)
'''
if os.path.isdir(data_dir):
data_types = ['train2017', 'val2017']
for data_type in data_types:
ann_file = 'instances_{}.json'.format(data_type)
xmls_save_path = os.path.join(xmls_save_path, data_type)
load_coco(ann_file, xmls_save_path)
elif os.path.isfile(data_dir):
'''
if os.path.isfile(data_dir):
anno_file = data_dir
load_coco(anno_file, xmls_save_path)
else:
print(" [Error]_json file is no exist, Please Check and try again")
#########################################################yolo to coco######################################################
def addCatItem_y(category_dict):
for k, v in category_dict.items():
category_item = dict()
category_item['supercategory'] = 'none'
category_item['id'] = int(k)
category_item['name'] = v
coco['categories'].append(category_item)
def addImgItem_y(file_name, size):
global image_id
image_id += 1
image_item = dict()
image_item['id'] = image_id
image_item['file_name'] = os.path.basename(file_name)
image_item['width'] = size[1]
image_item['height'] = size[0]
image_item['license'] = None
image_item['flickr_url'] = None
image_item['coco_url'] = None
image_item['date_captured'] = str(datetime.today())
coco['images'].append(image_item)
image_set.add(file_name)
return image_id
def addAnnoItem_y(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 xywhn2xywh_y(bbox, size):
bbox = list(map(float, bbox))
size = list(map(float, size))
xmin = (bbox[0] - bbox[2] / 2.) * size[1]
ymin = (bbox[1] - bbox[3] / 2.) * size[0]
w = bbox[2] * size[1]
h = bbox[3] * size[0]
box = (xmin, ymin, w, h)
return list(map(int, box))
def parseXmlFilse_y(image_path, anno_path, name_path,save_path, json_name='train.json'):
assert os.path.exists(image_path), "ERROR {} dose not exists".format(image_path)
assert os.path.exists(anno_path), "ERROR {} dose not exists".format(anno_path)
if os.path.exists(save_path):
#shutil.rmtree(save_path)
pass
else:
os.makedirs(save_path)
json_path = os.path.join(save_path, json_name)
try:
category_set = []
with open(name_path) as f:
for i in f.readlines():
category_set.append(i.strip())
category_id = dict((k, v) for k, v in enumerate(category_set))
if len(category_id) == 0:
print('[Error]_The yolo classes name read error, file is empty',flush=True)
exit()
addCatItem_y(category_id)
except FileNotFoundError:
print('[Error]_The yolo classes name path read error, file not exist',flush=True)
exit()
images = [os.path.join(image_path, i) for i in os.listdir(image_path)]
files = [os.path.join(anno_path, i) for i in os.listdir(anno_path)]
images_index = dict((v.split(os.sep)[-1][:-4], k) for k, v in enumerate(images))
jishu = 0
jindu_int = 0
jindu_flag = 0
for file in files:
if os.path.splitext(file)[-1] != '.txt' or 'classes' in file.split(os.sep)[-1]:
continue
strtest = Path(file).stem
new_test = image_path +strtest
# if file.split(os.sep)[-1][:-4] in images_index:
if new_test in images_index:
index = images_index[new_test]
# index = images_index[file.split(os.sep)[-1][:-4]]
img = cv2.imread(images[index])
shape = img.shape
filename = images[index].split(os.sep)[-1]
current_image_id = addImgItem_y(filename, shape)
else:
continue
with open(file, 'r') as fid:
for i in fid.readlines():
i = i.strip().split()
category = int(i[0])
category_name = category_id[category]
bbox = xywhn2xywh_y((i[1], i[2], i[3], i[4]), shape)
addAnnoItem_y(category_name, current_image_id, category, bbox)
jindu_tmp = ((jishu/len(files)))*100
jindu_int = int(jindu_tmp)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
print('[Percent]_100'+'%',flush=True)
json.dump(coco, open(json_path, 'w'))
#########################################################coco to yolo######################################################
# 将类别名字和id建立索引
def catid2name_c_y(coco):
classes = dict()
for cat in coco.dataset['categories']:
classes[cat['id']] = cat['name']
return classes
# 将[xmin,ymin,xmax,ymax]转换为yolo格式[x_center, y_center, w, h](做归一化)
def xyxy2xywhn_c_y(object, width, height):
cat_id = object[0]
xn = object[1] / width
yn = object[2] / height
wn = object[3] / width
hn = object[4] / height
out = "{} {:.5f} {:.5f} {:.5f} {:.5f}".format(cat_id, xn, yn, wn, hn)
return out
def save_anno_to_txt_c_y(images_info, save_path):
filename = images_info['filename']
txt_name = filename + ".txt"
with open(os.path.join(save_path, txt_name), "w") as f:
for obj in images_info['objects']:
line = xyxy2xywhn_c_y(obj, images_info['width'], images_info['height'])
f.write("{}\n".format(line))
# 利用cocoAPI从json中加载信息
def load_coco_c_y(anno_file, xml_save_path):
if os.path.exists(xml_save_path):
#shutil.rmtree(xml_save_path)
pass
else:
os.makedirs(xml_save_path)
coco = COCO(anno_file)
classes = catid2name_c_y(coco)
imgIds = coco.getImgIds()
classesIds = coco.getCatIds()
with open(os.path.join(xml_save_path, "classes.txt"), 'w') as f:
for id in classesIds:
f.write("{}\n".format(classes[id]))
jishu = 0
jindu_int = 0
jindu_flag = 0
for imgId in imgIds:
#for imgId in tqdm(imgIds):
info = {}
img = coco.loadImgs(imgId)[0]
filename = img['file_name']
width = img['width']
height = img['height']
info['filename'] = filename
info['width'] = width
info['height'] = height
annIds = coco.getAnnIds(imgIds=img['id'], iscrowd=None)
anns = coco.loadAnns(annIds)
objs = []
for ann in anns:
object_name = classes[ann['category_id']]
# bbox:[x,y,w,h]
bbox = list(map(float, ann['bbox']))
xc = bbox[0] + bbox[2] / 2.
yc = bbox[1] + bbox[3] / 2.
w = bbox[2]
h = bbox[3]
obj = [ann['category_id'], xc, yc, w, h]
objs.append(obj)
info['objects'] = objs
save_anno_to_txt_c_y(info, xml_save_path)
jindu_tmp = ((jishu/len(imgIds)))*100
jindu_int = int(jindu_tmp)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
print('[Percent]_100'+'%',flush=True)
def parseJsonFile_c_y(json_path, txt_save_path):
#assert os.path.exists(json_path), "json path:{} does not exists".format(json_path)
if os.path.exists(txt_save_path):
#shutil.rmtree(txt_save_path)
pass
else:
os.makedirs(txt_save_path)
#assert json_path.endswith('json'), "json file:{} It is not json file!".format(json_path)
load_coco_c_y(json_path, txt_save_path)
#########################################################coco to dota######################################################
def coco_to_dota(our_category,json_path,save_path,class_list,class_str):
with open(json_path, 'r', encoding="utf-8") as file:
json_data = json.load(file)
jishu = 0
jindu_int = 0
jindu_flag = 0
try:
for ann in json_data["annotations"]:
category_id = ann["category_id"]
category = our_category[category_id]
image_id = ann["image_id"]
ann_id = ann["id"]
for img_file in json_data["images"]:
if img_file["id"] == image_id:
img_file_name = img_file["file_name"]
seg_info = ann["segmentation"][0]
length = len(seg_info)
contours = []
for i in range(length):
if i % 2 == 0:
contours.append([seg_info[i], seg_info[i+1]])
contours = np.array(contours, dtype=np.float32)
# 对每个轮廓点求最小外接矩形
rect = cv2.minAreaRect(contours)
# cv2.boxPoints可以将轮廓点转换为四个角点坐标
box = cv2.boxPoints(rect)
# 令四个角点坐标为顺时针
startidx = box.sum(axis=1).argmin()
box = np.roll(box, 4 - startidx, 0)
# 在原图上画出预测的外接矩形
# img_dir_path = 'data/train/'
# image = cv2.imread(os.path.join(img_dir_path, img_file_name))
# box = box.reshape((-1, 1, 2)).astype(np.int32)
# img = cv2.polylines(image, [box], True, (0, 255, 0), 10)
# cv2.imwrite('data/visual/' + str(image_id) + '_' + str(ann_id) + '.png', img)
file = open(save_path + img_file_name.split(".")[0] + '.txt', 'a')
for dot in box:
d0 = int(dot[0])
d1 = int(dot[1])
file.write(str(d0))
file.write(' ')
file.write(str(d1))
file.write(' ')
file.write(category)
file.write(' ')
file.write('0\n')
jindu_tmp = ((jishu/len(json_data["annotations"])))*100
jindu_int = int(jindu_tmp)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
except IndexError:
print(" [Info]_The selected categories "+class_str +" have been converted, but note that the dataset also contains the categories that were not selected!", flush=True)
print('[Percent]_100'+'%',flush=True)
#########################################################dota to coco######################################################
def dota_load_dota2coco(txt_path,img_path,xml_path):
jishu = 0
jindu_int = 0
jindu_flag = 0
txts = os.listdir(txt_path)
for count, t in enumerate(txts):
try:
boxes, labels = load_annoataion_dota2coco(os.path.join(txt_path, t))
xml_name = t.replace('.txt', '.xml')
img_name = t.replace('.txt', '.png')
if os.path.exists(os.path.join(img_path, img_name)) == False:
img_name = t.replace('.txt', '.jpg')
if os.path.exists(os.path.join(img_path, img_name)) == False:
img_name = t.replace('.txt', '.jpeg')
if os.path.exists(os.path.join(img_path, img_name)) == False:
img_name = t.replace('.txt', '.tif')
if os.path.exists(os.path.join(img_path, img_name)) == False:
img_name = t.replace('.txt', '.tiff')
if os.path.exists(os.path.join(img_path, img_name)) == False:
print("[Info]_The '"+ xml_name +"' no corresponding image file was found")
break
#print(img_name)
img = cv2.imread(os.path.join(img_path, img_name))
h, w, d = img.shape
#print(xml_name, xml_path, boxes, labels, w, h, d)
WriterXMLFiles_dota2coco(xml_name, xml_path, boxes, labels, w, h, d)
jindu_tmp = ((jishu/len(txts)))*100
jindu_int = int(jindu_tmp/2)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
except TypeError:
print("[Info]_The dataset folder contains non-data files '" +os.path.join(txt_path, t)+"'")
print(' [Percent]_50%')
def WriterXMLFiles_dota2coco(filename, path, box_list, label_list, w, h, d):
# dict_box[filename]=json_dict[filename]
doc = xml.dom.minidom.Document()
root = doc.createElement('annotation')
doc.appendChild(root)
foldername = doc.createElement("folder")
foldername.appendChild(doc.createTextNode("JPEGImages"))
root.appendChild(foldername)
nodeFilename = doc.createElement('filename')
nodeFilename.appendChild(doc.createTextNode(filename))
root.appendChild(nodeFilename)
pathname = doc.createElement("path")
pathname.appendChild(doc.createTextNode("xxxx"))
root.appendChild(pathname)
sourcename=doc.createElement("source")
databasename = doc.createElement("database")
databasename.appendChild(doc.createTextNode("Unknown"))
sourcename.appendChild(databasename)
annotationname = doc.createElement("annotation")
annotationname.appendChild(doc.createTextNode("xxx"))
sourcename.appendChild(annotationname)
imagename = doc.createElement("image")
imagename.appendChild(doc.createTextNode("xxx"))
sourcename.appendChild(imagename)
flickridname = doc.createElement("flickrid")
flickridname.appendChild(doc.createTextNode("0"))
sourcename.appendChild(flickridname)
root.appendChild(sourcename)
nodesize = doc.createElement('size')
nodewidth = doc.createElement('width')
nodewidth.appendChild(doc.createTextNode(str(w)))
nodesize.appendChild(nodewidth)
nodeheight = doc.createElement('height')
nodeheight.appendChild(doc.createTextNode(str(h)))
nodesize.appendChild(nodeheight)
nodedepth = doc.createElement('depth')
nodedepth.appendChild(doc.createTextNode(str(d)))
nodesize.appendChild(nodedepth)
root.appendChild(nodesize)
segname = doc.createElement("segmented")
segname.appendChild(doc.createTextNode("0"))
root.appendChild(segname)
for (box, label) in zip(box_list, label_list):
nodeobject = doc.createElement('object')
nodename = doc.createElement('name')
nodename.appendChild(doc.createTextNode(str(label)))
nodeobject.appendChild(nodename)
nodename = doc.createElement('pose')
nodename.appendChild(doc.createTextNode("Unspecified"))
nodeobject.appendChild(nodename)
nodename = doc.createElement('truncated')
nodename.appendChild(doc.createTextNode("0"))
nodeobject.appendChild(nodename)
nodename = doc.createElement('difficult')
nodename.appendChild(doc.createTextNode("0"))
nodeobject.appendChild(nodename)
x_list = []
y_list = []
x_list.append(box[0])
x_list.append(box[2])
x_list.append(box[4])
x_list.append(box[6])
y_list.append(box[1])
y_list.append(box[3])
y_list.append(box[5])
y_list.append(box[7])
max_x = max(x_list)
min_x = min(x_list)
max_y = max(y_list)
min_y = min(y_list)
nodebndbox = doc.createElement('bndbox')
nodex1 = doc.createElement('xmin')
nodex1.appendChild(doc.createTextNode(str(min_x)))
nodebndbox.appendChild(nodex1)
nodex2 = doc.createElement('ymin')
nodex2.appendChild(doc.createTextNode(str(min_y)))
nodebndbox.appendChild(nodex2)
nodey3 = doc.createElement('xmax')
nodey3.appendChild(doc.createTextNode(str(max_x)))
nodebndbox.appendChild(nodey3)
nodex4 = doc.createElement('ymax')
nodex4.appendChild(doc.createTextNode(str(max_y)))
nodebndbox.appendChild(nodex4)
nodeobject.appendChild(nodebndbox)
root.appendChild(nodeobject)
fp = open(path + filename, 'w')
doc.writexml(fp, indent='\n')
fp.close()
def load_annoataion_dota2coco(p):
'''
load annotation from the text file
:param p:
:return:
'''
text_polys = []
text_tags = []
if not os.path.exists(p):
return np.array(text_polys, dtype=np.float32)
try:
with open(p, 'r') as f:
#for line in f.readlines()[2:]:
for line in f.readlines():
label = 'text'
# strip BOM. \ufeff for python3, \xef\xbb\bf for python2
#line = [i.strip('\ufeff').strip('\xef\xbb\xbf') for i in line]
x1, y1, x2, y2, x3, y3, x4, y4 ,label= line.split(' ')[0:9]
#print(label)
text_polys.append([float(x1), float(y1), float(x2), float(y2), float(x3), float(y3), float(x4), float(y4)])
text_tags.append(label)
return np.array(text_polys, dtype=np.int32), np.array(text_tags, dtype=np.str)
except PermissionError:
pass
def addCatItem_voctococo(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_voctococo(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']
image_item['license'] = None
image_item['flickr_url'] = None
image_item['coco_url'] = None
image_item['date_captured'] = str(datetime.today())
coco['images'].append(image_item)
image_set.add(file_name)
return image_id
def addAnnoItem_voctococo(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_voctococo(image_sets_file):
ids = []
with open(image_sets_file, 'r') as f:
for line in f.readlines():
ids.append(line.strip())
return ids
def parseXmlFilse_voctococo(data_dir, json_save_path):
assert os.path.exists(data_dir), "data path:{} does not exist".format(data_dir)
xml_files_list = []
if os.path.isdir(data_dir):
# 修改此处xml的路径即可
# xml_dir = os.path.join(data_dir,"labels/voc")
xml_dir = data_dir
xml_list = os.listdir(xml_dir)
xml_files_list = [os.path.join(xml_dir, i) for i in xml_list]
else:
print(' [Error]_The voc path is no exist, please check and try again')
exit()
jishu = 0
jindu_int = 0
jindu_flag = 0
for xml_file in xml_files_list:
jindu_tmp = ((jishu/len(xml_files_list)))*100
jindu_int = int(jindu_tmp/2 + 50)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
if not xml_file.endswith('.xml'):
continue
tree = ET.parse(xml_file)
root = tree.getroot()
# 初始化
size = dict()
size['width'] = None
size['height'] = None
if root.tag != 'annotation' and root.tag != 'Annotation':
raise Exception('pascal voc xml root element should be Annotation, rather than {}'.format(root.tag))
# 提取图片名字
file_name = root.findtext('filename')
file_name = os.path.splitext(file_name)[0]
assert file_name is not None, "filename is not in the file"
# 提取图片 size {width,height,depth}
size_info = root.findall('size')
assert size_info is not None, "size is not in the file"
for subelem in size_info[0]:
size[subelem.tag] = int(subelem.text)
if file_name is not None and size['width'] is not None and file_name not in image_set:
# 添加coco['image'],返回当前图片ID
current_image_id = addImgItem_voctococo(file_name, size)
#print('add image with name: {}\tand\tsize: {}'.format(file_name, size))
#################################
# 打印目标信息
#################################
elif file_name in image_set:
raise Exception('file_name duplicated')
else:
raise Exception("file name:{}\t size:{}".format(file_name, size))
# 提取一张图片内所有目标object标注信息
object_info = root.findall('object')
if len(object_info) == 0:
continue
# 遍历每个目标的标注信息
for object in object_info:
# 提取目标名字
object_name = object.findtext('name')
if object_name not in category_set:
# 创建类别索引
current_category_id = addCatItem_voctococo(object_name)
else:
current_category_id = category_set[object_name]
# 初始化标签列表
bndbox = dict()
bndbox['xmin'] = None
bndbox['xmax'] = None
bndbox['ymin'] = None
bndbox['ymax'] = None
# 提取box:[xmin,ymin,xmax,ymax]
bndbox_info = object.findall('bndbox')
for box in bndbox_info[0]:
bndbox[box.tag] = int(box.text)
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 object_name:{}\timage_id:{}\tcat_id:{}\tbbox:{}'.format(object_name, current_image_id,current_category_id,bbox))
addAnnoItem_voctococo(object_name, current_image_id, current_category_id, bbox)
json_parent_dir = os.path.dirname(json_save_path)
if not os.path.exists(json_parent_dir):
os.makedirs(json_parent_dir)
json.dump(coco, open(json_save_path, 'w'))
print('[Percent]_100'+'%',flush=True)
#########################################################dota to yolo######################################################
def listdir_dota2yolo(path, list_name):
for file in os.listdir(path):
file_path = os.path.join(path, file)
if os.path.isdir(file_path):
listdir(file_path, list_name)
else:
list_name.append(file_path)
def voc_label_dota2yolo(voc_label_path,voc_img_path,label_save_path,class_str,class_list):
sets=[('2007', 'train'), ('2007', 'val'), ('2007', 'test')]
#classes = ["plane", "ship", "harbor", "tennis-court", "soccer-ball-field", "ground-track-field", "storage-tank", "bridge"]
classes = class_str
#print(' [Info]_Load class name:' +str(classes))
wd = getcwd()
xml_data_path = voc_label_path
jpg_data_path = voc_img_path
if os.path.exists(xml_data_path) == False:
print(' [info]_The Annotations path is not exist, please check and try again',flush=True)
exit()
if os.path.exists(jpg_data_path) == False:
print(' [info]_The JPEGImages path is not exist, please check and try again',flush=True)
exit()
xml_list_name = []
jpg_list_name = []
listdir(xml_data_path,xml_list_name)
listdir(jpg_data_path,jpg_list_name)
if not os.path.exists(label_save_path):
os.makedirs(label_save_path)
jishu = 0
jindu_int = 0
jindu_flag = 0
for ii in xml_list_name:
image_id = Path(ii).stem
convert_annotation_dota2yolo(voc_label_path, image_id,classes,class_list,label_save_path)
jindu_tmp = ((jishu/len(xml_list_name)))*100
jindu_int = int(jindu_tmp/2 + 50)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
print('[Percent]_100'+'%',flush=True)
def convert_dota2yolo(size, box):
dw = 1./size[0]
dh = 1./size[1]
x = (box[0] + box[1])/2.0
y = (box[2] + box[3])/2.0
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 convert_annotation_dota2yolo(data_path, image_id,classes,class_list,label_save_path):
in_file = open(data_path + '%s.xml'%(image_id))
#out_file = open(data_path + 'labels/%s.txt'%(image_id), 'w')
out_file = open(label_save_path+ '%s.txt'%(image_id), 'w')
tree=ET.parse(in_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 class_list or int(difficult) == 1:
continue
cls_id = class_list.index(cls)
#print(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))
bb = convert_dota2yolo((w,h), b)
out_file.write(str(cls_id) + " " + " ".join([str(a) for a in bb]) + '\n')
#########################################################yolo to dota######################################################
def read_txt_yolo2dota(labels_path,voc_path,annotations_path):
labels = os.listdir(labels_path)
f = open(voc_path, "r")
line = f.read().splitlines()
classes_str = line
print(' [Info]_Load class name: '+str(line),flush=True)
f.close()
# Classes
classes = classes_str
# Image height width deepth
sh = sw = sd = 0
files_label = os.listdir(labels_path)
file_num = len(files_label)
i = 1
if len(labels) is 0:
print(' [Info]_labels file is not found',flush=True)
else:
jindu_int = 0
jindu_flag = 0
for label in labels:
try:
with open(labels_path + label, 'r') as f:
img_id = os.path.splitext(label)[0]
contents = f.readlines()
labeldicts = []
#str_jindu = str((i/file_num)*100)+'%'
jindu_tmp = (i/file_num)*100
jindu_int = int(float(jindu_tmp)/2)
#print(jindu_int)
if jindu_int > jindu_flag:
print(' [Percentage]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
if i == file_num:
print(' [Info]_Dataset format conversion completed',flush=True)
i = i+1
for content in contents:
# input image format
flag_panduan = False
if os.path.exists(img_path + label.strip('.txt') + '.jpg') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.jpg'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.JPG') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.JPG'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.jpeg') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.jpeg'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.JPEG') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.JPEG'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.png') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.png'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.PNG') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.PNG'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.bmp') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.bmp'))
flag_panduan = True
elif os.path.exists(img_path + label.strip('.txt') + '.BMP') == True :
img = np.array(Image.open(img_path + label.strip('.txt') + '.BMP'))
flag_panduan = True
# image height width
if flag_panduan == False:
print("[Info]_The '" + label+"' corresponding image file was not found!")
break
sh, sw, sd = img.shape[0], img.shape[1], img.shape[2]
content = content.strip('\n').split()
x = float(content[1])*sw
y = float(content[2])*sh
w = float(content[3])*sw
h = float(content[4])*sh
# coordinate transition, x_center y_center width height -> xmin ymin xmax ymax
try:
new_dict = {'name': classes[int(content[0])],
'difficult': '0',
'xmin': x+1-w/2,
'ymin': y+1-h/2,
'xmax': x+1+w/2,
'ymax': y+1+h/2
}
labeldicts.append(new_dict)
except IndexError:
print(" [Error]_voc.names classes no match txt file, xml file generate error, Please Check")
#names里的类别数少,txt里标注的类别数多,txt里读出来的类别在names找不到
sys.exit(0)
write_xml_yolo2dota(img_id, sw, sh, sd, annotations_path + label.strip('.txt') + '.xml', labeldicts)
except PermissionError:
print("[Info]_The label folders contain non-labeled data '"+labels_path + label+"'")
def write_xml_yolo2dota(imgname, sw, sh, sd, filepath, labeldicts):
# 创建Annotation根节点
root = ET.Element('Annotation')
# 创建filename子节点,无扩展名
ET.SubElement(root, 'filename').text = str(imgname)
# 创建size子节点
sizes = ET.SubElement(root,'size')
ET.SubElement(sizes, 'width').text = str(sw)
ET.SubElement(sizes, 'height').text = str(sh)
ET.SubElement(sizes, 'depth').text = str(sd)
for labeldict in labeldicts:
objects = ET.SubElement(root, 'object')
ET.SubElement(objects, 'name').text = labeldict['name']
ET.SubElement(objects, 'pose').text = 'Unspecified'
ET.SubElement(objects, 'truncated').text = '0'
ET.SubElement(objects, 'difficult').text = '0'
bndbox = ET.SubElement(objects,'bndbox')
ET.SubElement(bndbox, 'xmin').text = str(int(labeldict['xmin']))
ET.SubElement(bndbox, 'ymin').text = str(int(labeldict['ymin']))
ET.SubElement(bndbox, 'xmax').text = str(int(labeldict['xmax']))
ET.SubElement(bndbox, 'ymax').text = str(int(labeldict['ymax']))
tree = ET.ElementTree(root)
tree.write(filepath, encoding='utf-8')
def voc_to_dota_yolo2dota(xml_path, xml_name,save_path):
txt_name = xml_name[:-4] + '.txt'
txt_path = save_path
if not os.path.exists(txt_path):
os.makedirs(txt_path)
txt_file = os.path.join(txt_path, txt_name)
file_path = os.path.join(xml_path, file_list[i])
tree = ET.parse(os.path.join(file_path))
root = tree.getroot()
# print(root[6][0].text)
with open(txt_file, "w+", encoding='UTF-8') as out_file:
# out_file.write('imagesource:null' + '\n' + 'gsd:null' + '\n')
for obj in root.findall('object'):
name = obj.find('name').text
difficult = obj.find('difficult').text
robndbox = obj.find('bndbox')
xmin = int(robndbox.find('xmin').text)
ymin = int(robndbox.find('ymin').text)
xmax = int(robndbox.find('xmax').text)
ymax = int(robndbox.find('ymax').text)
p0x = xmin
p0y = ymin
p1x = xmax
p1y = ymin
p2x = xmax
p2y = ymax
p3x = xmin
p3y = ymax
data = str(p0x) + " " + str(p0y) + " " + str(p1x) + " " + str(p1y) + " " + \
str(p2x) + " " + str(p2y) + " " + str(p3x) + " " + str(p3y) + " "
data = data + name + " "+ '0' + "\n"
out_file.write(data)
##################################################################################################################################################### main
if __name__ == '__main__':
args = sys.argv
inputstr = args[1]
outputstr = args[2]
##################yolo to voc###############
if inputstr == "yolo" and outputstr == "voc":
#python geshi.py yolo voc C:/Users/qiaomengyu/Desktop/testdata/JPEGImages/ C:/Users/qiaomengyu/Desktop/testdata/labels/ C:/Users/qiaomengyu/Desktop/testdata/Annotations/ C:/Users/qiaomengyu/Desktop/testdata/voc.names
'''
# 图片文件夹,后面的/不能省
img_path = 'C:/Users/qiaomengyu/Desktop/testyolo/JPEGImages/'
# txt文件夹,后面的/不能省
labels_path = 'C:/Users/qiaomengyu/Desktop/testyolo/labels/'
# xml存放的文件夹,后面的/不能省
annotations_path = 'C:/Users/qiaomengyu/Desktop/testyolo/Annotations/'
#voc读取目标种类名字
voc_path = 'C:/Users/qiaomengyu/Desktop/testyolo/voc.names'
'''
print(" [Info]_yolo to voc",flush=True)
try:
if os.path.exists(args[3]) == False:
print(" [Error]_img_path no exist, The data cannot be converted")
exit()
else:
str_imgpath = args[3]
########################################################################
if os.path.exists(args[4]) == False:
print(" [Error]_labels_path no exist, The data cannot be converted")
exit()
else:
str_labelpath = args[4]
########################################################################
if os.path.exists(args[5]) == False:
print(" [Info]_annotations_path no exist, Now create the folder")
os.makedirs(args[5])
str_annotationspath = args[5]
else:
str_annotationspath = args[5]
########################################################################
if os.path.exists(args[6]) == False:
print(" [Error]_vocnames_path no exist, The data cannot be converted")
exit()
else:
str_vocpath = args[6]
########################################################################
img_path = str_imgpath
labels_path = str_labelpath
annotations_path = str_annotationspath
voc_path = str_vocpath
read_txt(labels_path,voc_path)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################voc to yolo###############
elif inputstr == "voc" and outputstr == "yolo":
#python geshi.py voc yolo C:/Users/qiaomengyu/Desktop/testdata/ C:/Users/qiaomengyu/Desktop/testdata/labels/ ship car person
#[输入格式] [输出格式] [voc的路径(包含Annotations,JPEGImages)] [输出路径]
#注:voc路径会校验,没有Annotations和JPEGIamges会报错
print(" [Info]_voc to yolo", flush=True)
try:
voc_data_path = args[3]
label_save_path = args[4]
i_path = 5
class_list = []
for i in range(len(args)) :
if i_path < len(args):
class_list.append(args[i_path])
i_path = i_path + 1
class_str = str(class_list)
if class_list == []:
print(' [Error]_The class name is empty, please input clasee name and try again',flush=True)
exit()
else:
voc_label(voc_data_path,label_save_path,class_str,class_list)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################dota to voc###############
elif inputstr == 'dota' and outputstr =='voc':
#python geshi.py dota voc C:/Users/qiaomengyu/Desktop/testdata/dota/labels/ C:/Users/qiaomengyu/Desktop/testdata/dota/JPEGImages/ C:/Users/qiaomengyu/Desktop/testdata/dota/Annotations/
#[输入格式] [输出格式] [dota的label路径] [dota的影像路径] [输出的标注文件]
print(" [Info]_dota to voc",flush=True)
try:
txt_path = args[3]
img_path = args[4]
xml_path = args[5]
if os.path.exists(args[3]) == False:
print(" [Error]_The dota data set labels file no exist, The data cannot be converted")
exit()
if os.path.exists(args[4]) == False:
print(" [Error]_The dota data set image file no exist, The data cannot be converted")
exit()
if os.path.exists(args[5]) == False:
print(" [Error]_Xml save path no exist, The data cannot be converted")
exit()
'''
txt_path = 'C:/Users/qiaomengyu/Desktop/testdata/dota/labels/'
xml_path = 'C:/Users/qiaomengyu/Desktop/testdata/dota/Annotations/'
img_path = 'C:/Users/qiaomengyu/Desktop/testdata/dota/JPEGImages/'
'''
dota_load(txt_path,img_path,xml_path)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################voc to dota###############
elif inputstr == 'voc' and outputstr == 'dota':
#python geshi.py voc dota C:/Users/qiaomengyu/Desktop/testdata/dota/Annotations/ C:/Users/qiaomengyu/Desktop/testdata/dota/Annotations/txtlabel/
#[输入格式] [输出格式] [voc的label路径] [输出的label路径]
print(" [Info]_voc to dota",flush=True)
try:
root_path = args[3]
save_path = args[4]
if os.path.exists(args[3]) == False:
print(" [Info]_voc data set Annotations file no exist, The data cannot be converted")
exit()
if os.path.exists(args[4]) == False:
print(" [Info]_save path no exist, The data cannot be converted")
exit()
file_list = os.listdir(root_path)
jishu = 0
jindu_int = 0
jindu_flag = 0
for i in range(0, len(file_list)):
if ('.xml' in file_list[i]) or ('.XML' in file_list[i]):
voc_to_dota(root_path, file_list[i],save_path)
jindu_tmp = ((jishu/len(file_list)))*100
jindu_int = int(jindu_tmp)
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
print('[Percent]_100'+'%',flush=True)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################voc to coco###############
elif inputstr == 'voc' and outputstr == 'coco':
print(" [Info]_voc to coco",flush=True)
try:
coco = dict()
coco['images'] = []
coco['type'] = 'instances'
coco['annotations'] = []
coco['categories'] = []
category_set = dict()
image_set = set()
category_item_id = -1
image_id = 000000
annotation_id = 0
voc_data_dir = args[3]
json_save_path = args[4]
#voc_data_dir = 'C:/Users/qiaomengyu/Desktop/testdata/Annotations/'
#json_save_path = 'C:/Users/qiaomengyu/Desktop/testdata/train.json'
#python geshi.py voc coco C:/Users/qiaomengyu/Desktop/testdata/voc_tmp/ C:/Users/qiaomengyu/Desktop/testdata/train_test.json
#[输入格式] [输出格式] [voc label路径] [输出coco的json]
parseXmlFilse_c(data_dir=voc_data_dir, json_save_path=json_save_path)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################coco to voc###############
elif inputstr == 'coco' and outputstr == 'voc':
print(" [Info]_coco to voc",flush=True)
try:
data_dir = args[3]
xml_save_path = args[4]
#python geshi.py coco voc C:/Users/qiaomengyu/Desktop/testdata/data/train.json C:/Users/qiaomengyu/Desktop/testdata/data/Annotations/
#python geshi.py coco voc C:/Users/qiaomengyu/Desktop/testdata/train_test.json C:/Users/qiaomengyu/Desktop/testdata/1111/
#[输入格式] [输出格式] [coco的json] [输出voc label路径]
#data_dir = 'C:/Users/qiaomengyu/Desktop//testdata/train_test.json'
#xml_save_path = 'C:/Users/qiaomengyu/Desktop/testdata/1111/'
try:
parseJsonFile(data_dir=data_dir, xmls_save_path=xml_save_path)
except AssertionError:
print(" [Error]_json file is no exist, Please Check and try again")
exit()
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################yolo to coco###############
elif inputstr == 'yolo' and outputstr == 'coco':
print(" [Info]_yolo to coco",flush=True)
try:
coco = dict()
coco['images'] = []
coco['type'] = 'instances'
coco['annotations'] = []
coco['categories'] = []
category_set = dict()
image_set = set()
image_id = 000000
annotation_id = 0
"""
脚本说明:
本脚本用于将yolo格式的标注文件.txt转换为coco格式的标注文件.json
参数说明:
anno_path:标注文件txt存储路径
save_path:json文件输出的文件夹
image_path:图片路径
json_name:json文件名字
anno_path = 'C:/Users/qiaomengyu/Desktop/testdata/data/labels/'
save_path = 'C:/Users/qiaomengyu/Desktop/testdata/data/coco/'
image_path = 'C:/Users/qiaomengyu/Desktop/testdata/data/JPEGImages/'
name_path = 'C:/Users/qiaomengyu/Desktop/testdata/data/labels/voc.names'
json_name = 'trainyolo.json'
"""
anno_path = args[3]
image_path = args[4]
name_path = args[5]
save_path = args[6]
json_name = args[7]
if os.path.exists(image_path) == False:
print('[Error]_The yolo image path not exist',flush=True)
exit()
elif os.path.exists(anno_path) == False:
print('[Error]_The yolo classes labels path not exist',flush=True)
exit()
else:
parseXmlFilse_y(image_path, anno_path, name_path,save_path,json_name)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################coco to yolo###############
elif inputstr == 'coco' and outputstr == 'yolo':
print(" [Info]_coco to yolo",flush=True)
images_nums = 0
category_nums = 0
bbox_nums = 0
json_path = args[3]
txt_save_path = args[4]
try:
if os.path.exists(json_path) == False:
print(" [Error]_The json file is no exist ,pleaes check again!")
exit()
else:
parseJsonFile_c_y(json_path, txt_save_path)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################coco to dota###############
elif inputstr == 'coco' and outputstr == 'dota':
print(" [Info]_coco to dota",flush=True)
try:
json_path = args[3]
save_path = args[4]
i_path = 5
class_list = []
for i in range(len(args)) :
if i_path < len(args):
class_list.append(args[i_path])
i_path = i_path + 1
class_str = str(class_list)
print(" [Info]_The categories that need to be converted are "+class_str,flush=True)
if class_list == []:
print(' [info]_Please input clasee name and try again',flush=True)
exit()
if os.path.exists(save_path) == False:
print(" [Error]_The save path is no exist ,pleaes check again!")
exit()
our_category = class_list
#json_path = 'C:/Users/qiaomengyu/Desktop/testdata/train.json'
#save_path = 'C:/Users/qiaomengyu/Desktop/testdata/dota_new/'
if os.path.exists(json_path) == False:
print(" [Error]_The json file is no exist ,pleaes check again!")
exit()
coco_to_dota(our_category,json_path,save_path,class_list,class_str)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################dota to coco###############
elif inputstr == 'dota' and outputstr == 'coco':
print(" [Info]_dota to coco",flush=True)
try:
dota_label_path = args[3]
dota_img_path = args[4]
save_path = args[5]
#dota_label_path = 'C:/Users/qiaomengyu/Desktop/testdata/dota_new/'
#dota_img_path = 'C:/Users/qiaomengyu/Desktop/testdata/data/JPEGimages/'
#save_path = 'C:/Users/qiaomengyu/Desktop/testdata/tarin_new.json'
if os.path.exists(dota_label_path) == False:
print("[Info]_The DOTA dataset label path does not exist, please check ang try again")
exit()
if os.path.exists(dota_img_path) == False:
print("[Info]_The DOTA dataset image path does not exist, please check ang try again")
exit()
linshi_path, linshi_file = os.path.split(save_path)
tmp_path = linshi_path + "/voc_tmp/"
if os.path.exists(tmp_path) == False:
os.makedirs(tmp_path)
dota_load_dota2coco(dota_label_path,dota_img_path,tmp_path)
#[dota的label路径] [输出的标注文件] [dota的影像路径] ,dota->voc
coco = dict()
coco['images'] = []
coco['type'] = 'instances'
coco['annotations'] = []
coco['categories'] = []
category_set = dict()
image_set = set()
category_item_id = -1
image_id = 000000
annotation_id = 0
voc_data_dir = tmp_path
json_save_path = save_path
parseXmlFilse_voctococo(data_dir=voc_data_dir, json_save_path=json_save_path)
shutil.rmtree(tmp_path)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################dota to yolo###############
elif inputstr == 'dota' and outputstr == 'yolo':
print(" [Info]_dota to yolo",flush=True)
try:
dota_label_path = args[3]
#dota_label_path = 'C:/Users/qiaomengyu/Desktop/testdata/dota_new/'
dota_img_path = args[4]
#dota_img_path = 'C:/Users/qiaomengyu/Desktop/testdata/data/JPEGimages/'
label_save_path = args[5]
# label_save_path = 'C:/Users/qiaomengyu/Desktop/testdata/yolo_test11/'
i_path = 6
class_list = []
for i in range(len(args)) :
if i_path < len(args):
class_list.append(args[i_path])
i_path = i_path + 1
class_str = str(class_list)
print(" [Info]_The categories that need to be converted are "+class_str,flush=True)
if class_list == []:
print(' [info]_Please input clasee name and try again',flush=True)
exit()
tmp_path = label_save_path + "/voc_tmp/"
if os.path.exists(tmp_path) == False:
os.makedirs(tmp_path)
dota_load_dota2coco(dota_label_path,dota_img_path,tmp_path)
#[dota的label路径] [输出的标注文件] [dota的影像路径] ,dota->voc
voc_label_path = tmp_path
voc_img_path = dota_img_path
voc_label_dota2yolo(voc_label_path,voc_img_path,label_save_path,class_str,class_list)
#voc标签路径,voc图像路径,yolo label存储路径,class
shutil.rmtree(tmp_path)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
##################yolo to dota###############
elif inputstr == 'yolo' and outputstr == 'dota':
print(" [Info]_yolo to dota",flush=True)
try:
img_path = args[3]
# img_path = 'C:/Users/qiaomengyu/Desktop/testdata/data/JPEGImages/'
labels_path = args[4]
# labels_path = 'C:/Users/qiaomengyu/Desktop/testdata/yolo_new/'
#annotations_path = 'C:/Users/qiaomengyu/Desktop/testdata/voc_tmp/'
voc_path = args[5]
save_path = args[6]
#voc_path = 'C:/Users/qiaomengyu/Desktop/testdata/voc.names'
annotations_path = save_path + "/voc_tmp/"
root_path = annotations_path
if os.path.exists(annotations_path) == False:
os.makedirs(annotations_path)
read_txt_yolo2dota(labels_path,voc_path,annotations_path)
#save_path = "C:/Users/qiaomengyu/Desktop/testdata/dota_11/"
#[voc的label路径] [输出的label路径]
if os.path.exists(labels_path) == False:
print(" [Info]_The yolo labels file no exist, The data cannot be converted")
exit()
if os.path.exists(save_path) == False:
os.makedirs(save_path)
file_list = os.listdir(root_path)
jishu = 0
jindu_int = 0
jindu_flag = 0
for i in range(0, len(file_list)):
if ('.xml' in file_list[i]) or ('.XML' in file_list[i]):
voc_to_dota_yolo2dota(root_path, file_list[i],save_path)
jindu_tmp = ((jishu/len(file_list)))*100
jindu_int = int(jindu_tmp/2)+50
if jindu_int > jindu_flag:
print('[Percent]_'+str(jindu_int)+'%',flush=True)
jindu_flag = jindu_int
jishu = jishu +1
print('[Percent]_100'+'%',flush=True)
shutil.rmtree(annotations_path)
except IndexError:
print(" [Error]_The number of input parameters is incorrect, please check and try again!", flush=True)
else:
print('[Error]_The input parameter is incorrect, Please check the format',flush=True)