取得DOTA数据集
https://captain-whu.github.io/DOTA/dataset.html
DOTA2.0 已经于2021.2.26更新了数据集和trainval的标注 本次验证使用1.5版本
DOTA数据集标注转voc
https://github.com/freepoet/CaptureTargetInImage/blob/master/DataTransformation/DOTA2VOC.py
# -*- coding: utf-8 -*-
# @Time : 18/09/2020 09:07
# @Author : Mingqiang Ning
# @Email : ningmq_cv@foxmail.com
# @File : DOTA2VOC.py
# @Software: PyCharm
import os
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
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)
nodebndbox = doc.createElement('bndbox')
nodex1 = doc.createElement('x1')
nodex1.appendChild(doc.createTextNode(str(box[0])))
nodebndbox.appendChild(nodex1)
nodey1 = doc.createElement('y1')
nodey1.appendChild(doc.createTextNode(str(box[1])))
nodebndbox.appendChild(nodey1)
nodex2 = doc.createElement('x2')
nodex2.appendChild(doc.createTextNode(str(box[2])))
nodebndbox.appendChild(nodex2)
nodey2 = doc.createElement('y2')
nodey2.appendChild(doc.createTextNode(str(box[3])))
nodebndbox.appendChild(nodey2)
nodex3 = doc.createElement('x3')
nodex3.appendChild(doc.createTextNode(str(box[4])))
nodebndbox.appendChild(nodex3)
nodey3 = doc.createElement('y3')
nodey3.appendChild(doc.createTextNode(str(box[5])))
nodebndbox.appendChild(nodey3)
nodex4 = doc.createElement('x4')
nodex4.appendChild(doc.createTextNode(str(box[6])))
nodebndbox.appendChild(nodex4)
nodey4 = doc.createElement('y4')
nodey4.appendChild(doc.createTextNode(str(box[7])))
nodebndbox.appendChild(nodey4)
# ang = doc.createElement('angle')
# ang.appendChild(doc.createTextNode(str(angle)))
# nodebndbox.appendChild(ang)
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)
with open(p, 'r') as f:
for line in f.readlines()[2:]:
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]4. 数据集划分
#print(label)
text_polys.append([x1, y1, x2, y2, x3, y3, x4, y4])
text_tags.append(label)
return np.array(text_polys, dtype=np.float), np.array(text_tags, dtype=np.str)
txt_path = '../datasets/DOTA/train/labelTxt-v1.5/DOTA-v1.5_train/'
xml_path = '../datasets/DOTA/train/VOC/'
img_path = '../datasets/DOTA/train/images/'
print(os.path.exists(txt_path))
txts = os.listdir(txt_path)
for count, t in enumerate(txts):
boxes, labels = load_annoataion(os.path.join(txt_path, t))
xml_name = t.replace('.txt', '.xml')
img_name = t.replace('.txt', '.png')
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)
if count % 1000 == 0:
print(count)
–
Edge Box 生成
原作者说明:
改ID和生成voc形式标注都比较简单。生成Edge Boxes的过程没有给出直接的方法。打开VOC中的 EdgeBoxesVOC2007test.mat 文件得到其结构:
那么我们只需要通过调用opencv-contrib 中的Edge boxes算法,生成预选框并保存为同样格式的mat文件即可。
因为mat,cell格式算是matlab特有的,python里不好直接保存为对应格式,自己也没查到(拉跨),所以将数据以list保存下来后再使用matlab对数据进行处理,保存为对应的格式。
注意这里VOC中给出的box结构是(y1,x1,y2,x2),左上角点和右下角点。而opencv算法得出的是(x,y,w,h)
写了一个.m程序生成好对的mat 这一步也完成了
Debug
github上有wsddn的pytorch实现 直接拿来用,更改源码中数据集的路径即可
但是实际训练后会发现dota1.5的标注数据是有问题的,一个是标注超出了图片边界,比如图片的宽度是1338,但是标注写到了1339,这样就会报错。另一个是标注远在图片之外,怀疑标注时用的图片比实际给出的图片大,比如图片宽度是4389, 标注写到了7348。
将超出图片范围几个像素的标注都修复掉,然后把出错的几张图片删掉,就可以开始训练了。
train中
2123 1531 没有目标
1872 0334 严重越界
val中
2152 2330 没有目标