深度学习数据处理

一 数据格式的转换脚本

   1 将DOTA(HBB)数据集格式转换为yolo数据

"""
#2019.4.4: 将DOTA(HBB)数据集格式转换成YOLO数据集格式
欠缺将标签保存的Txt文档保存
"""
import cv2
import os
from collections import defaultdict

imagepath="/data/maq/DataSet/pytorch_yolov3/guigang/images"
labeltxt_DOTA="/data/maq/DataSet/pytorch_yolov3/guigang/labels_dota_hbb4"

labeltxt_YOLO="/data/maq/DataSet/pytorch_yolov3/guigang/labels"


def readsingletxt_all_dotalabel(imagepath,labelspath,outputfile):

    img = cv2.imread(imagepath)
    size = img.shape
    f = open(labelspath, 'r')
    lines = f.readlines()
    file_label = open(outputfile, "a")
    for line in lines:
        line = line.split(" ")
        #取出DOTA中的标签参数
        x1=min(float(line[0]),float(line[2]),float(line[4]),float(line[6]))
        x3 = max(float(line[0]), float(line[2]), float(line[4]), float(line[6]))
        y1 = min(float(line[1]), float(line[3]), float(line[5]), float(line[7]))
        y3 = max(float(line[1]), float(line[3]), float(line[5]), float(line[7]))
        x,y,w,h=dota_convert_yolo(size, x1, y1, x3, y3)
        catrgory_label= int(line[8])-1
        #catrgory_val=line[9].split("\n")[0]
        #将类别标签保存成字典,并将数据按照YOLO标签保存到txt
        string=str(catrgory_label)+" "+str(x)+" "+str(y)+" "+str(w)+" "+str(h)+"\n"
        file_label.write(string)
    file_label.close()

#dota数据转换成yolo格式
def dota_convert_yolo(size,x1,y1,x3,y3):
    height = size[0]  # 图片的高
    dh = 1 / height
    width = size[1]  # 图片的宽
    dw = 1 / width
    # 还原YOLO中拿去的min_row,min_col,max_row,max_col
    min_row = y1
    min_rol = x1
    max_row = y3
    max_rol = x3
    # 转换成YOLO中可以用的坐标
    x = min_rol + (max_rol - min_rol) / 2
    y = min_row + (max_row - min_row) / 2
    w = max_rol - min_rol
    h = max_row - min_row
    # 将坐标进行归一化
    x = x * dw
    y = y * dh
    w = w * dw
    h = h * dh
    return (x,y,w,h)

def main():
    tempfilename = os.listdir(imagepath)
    for file in tempfilename:  # 遍历文件夹
        (filename, extension) = os.path.splitext(file)
        imagepath_tif = os.path.join(imagepath + "/" + file)
        labeltxt_dota = os.path.join(labeltxt_DOTA + "/" + filename + '.txt')  # 获取对应的DOTA数据.txt标签文件
        labeltxt_yolo = os.path.join(labeltxt_YOLO + "/" + filename + '.txt')  # 输出DOTA标签转变为yolo标签的文件
        if os.path.exists(labeltxt_yolo):  # 判断文件是否存在,存在就越过
            # continue
            os.remove(labeltxt_yolo)
        readsingletxt_all_dotalabel(imagepath_tif, labeltxt_dota, labeltxt_yolo)

if __name__=='__main__':
    main()
    print("finished!!")

  2  将VOC数据集转换成yolo数据

 

"""
#2019.4.4 将PASCAL VOC数据集转换成yolo数据集格式
"""
import xml.etree.ElementTree as ET
import os


pascal_Ann_path="C:\\Users\\lijian\\Desktop\\PASCAL_VOC\\Annotations"
yolo_Output_txt="C:\\Users\\lijian\\Desktop\\PASCAL_VOC\\VOC_TO_YOLO"

#对voc中的坐标进行转换
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)

classes={'person':1} #检测的内容类别

#读出文件夹中XML文件,并寻找相应的尺寸
def convert_annotation(input_vocxml_file,output_yolo_txt):
    in_file = open(input_vocxml_file)
    out_file = open(output_yolo_txt, 'a')
    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'):
        cls = obj.find('name').text
        if cls not in classes :
            continue
        cls_id = classes[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')



def main():
    tempfilename = os.listdir(pascal_Ann_path)
    for file in tempfilename: #遍历文件夹
        (filename,extension)=os.path.splitext(file)
        pascal_ann_path=os.path.join(pascal_Ann_path+"\\"+file) #存放.XML的文件件
        yolo_output_txt=os.path.join(yolo_Output_txt+"\\"+filename+'.txt')

        if os.path.exists(yolo_output_txt):
            os.remove(yolo_output_txt)
        convert_annotation(pascal_ann_path,yolo_output_txt)

if __name__ == '__main__':
    main()
3 YOLO数据转DOTA(HBB)
"""
# 2019.4.3 : 将YOLO检测数据集格式转换成DOTA数据集格式(HBB)
"""
import cv2
import os

imagepath="/data/maq/DataSet/xue_oilwell_2019619/images"
labelspath="/data/maq/DataSet/xue_oilwell_2019619/labels"

output="/data/maq/DataSet/xue_oilwell_2019619/labels_dota"

def readsingletxt_all_yololabel(imagepath,labelspath,outputfile):

    img = cv2.imread(imagepath)
    size = img.shape
    # height = size[0]  # 图片的高
    # width = size[1]  # 图片的宽
    # print("####labels:", labelspath)
    # os._exit()
    f = open(labelspath, 'r')
    lines = f.readlines()
    for line in lines:
        line = line.split(" ")
        catrgory_val = int(line[0])
        if ((line[1]=="NA") + (line[2]=="NA") |(line[3]=="NA")|(line[3]=="NA"))>0:
            print("####labelspath:", labelspath)
            continue
        min_row, min_col, max_row, max_col=dota_convert_yolo(size,line[1],line[2],line[3],line[4])
        #构建矩形框在原图中的位置
        x1, y1 = min_col, min_row
        x2, y2 = max_col, min_row
        x3, y3 = max_col, max_row
        x4, y4 = min_col, max_row
        string = str(x1) + " " + str(y1) + " " + str(x2) + " " + str(y2) + " " + str(x3) + " " + str(y3) + " " + str(
            x4) + " " + str(y4)
        DOTAlabel_writetxt(string,catrgory_val,outputfile)

#yolo数据转换成dota格式
def dota_convert_yolo(size,x,y,w,h):
    height = size[0]  # 图片的高
    width = size[1]  # 图片的宽
    # 取出yolo中的标签参数
    x = float(x) * width
    y = float(y) * height
    w = float(w) * width
    h = float(h) * height
    # 还原矩形框最小/大的行/列数值
    min_row = round(y - h / 2)
    max_row = round(y + h / 2)
    min_col = round(x - w / 2)
    max_col = round(x + w / 2)
    return min_row,min_col,max_row,max_col

catrgory={"oilwell":0}
#将DOTA数据加上相应标签写入文件
def DOTAlabel_writetxt(string,catrgory_val,outputfile):
    for catr, val in catrgory.items():
        if val == catrgory_val:
            stringall = string + " " + catr + " " + str(val) + "\n"
            file_label = open(outputfile, "a")
            file_label.write(stringall)

def main():
    tempfilename = os.listdir(imagepath)
    for file in tempfilename:  # 遍历文件夹
        (filename, extension) = os.path.splitext(file)
        imagepath_tif = os.path.join(imagepath + "/" + file)
        labelspath_txt = os.path.join(labelspath + "/" + filename + '.txt')  # 获取对应的.txt标签文件
        output_file = os.path.join(output + "/" + filename + '.txt')  # 输出yolo标签转变为DOTA标签的文件
        if os.path.exists(output_file):  # 判断文件是否存在,存在就越过
            # continue
            os.remove(output_file)
        readsingletxt_all_yololabel(imagepath_tif, labelspath_txt, output_file)

if __name__ == '__main__':
    main()
    print("finished!!!")

4 YOLO转VOC数据格式

"""
2019.4.8: 将YOLO数据集格式转换成VOC数据集格式
"""

import os
from xml.dom.minidom import Document
import cv2

input_Yolo_txt="C:\\Users\\lijian\\Desktop\\lables1"
input_Yolo_image="C:\\Users\\lijian\\Desktop\\image_labels1"
output_Voc_xml="C:\\Users\\lijian\\Desktop\\voc_xml"


def get_YoloInfo(txt_dir):
    f = open(txt_dir, 'r')
    line_info = f.readlines()

    L = len(line_info)
    label_classes = []
    for line in range(L):
        label_classes.append('x')
        line_info[line] = line_info[line].strip()
        each_data = line_info[line].split(' ')
        classes = int(each_data[0])
        x_center = float(each_data[1])
        y_center = float(each_data[2])
        width_nor = float(each_data[3])
        height_nor = float(each_data[4])

        label_classes[line] = [classes, x_center, y_center, width_nor, height_nor]
    return label_classes

catrgory={"house":1}   #原始字典
new_dict = {v : k for k, v in catrgory.items()}   #将原始字典的key与val相互换

#将yolo的原始数据进行转换
def Yolo_voc_data(size,yoloinfo):
    ##修改label类别
    num = len(yoloinfo)
    # 修改图片数据
    height = size[0]  # 图片的高
    width = size[1]  # 图片的宽
    voc_data = []
    for each in range(num):
        voc_data.append('x')

        classes = new_dict[yoloinfo[each][0]]
        x_center = yoloinfo[each][1] * width
        y_center = yoloinfo[each][2] * height
        width_nor = yoloinfo[each][3] * width
        height_nor = yoloinfo[each][4] * height

        voc_xmin = str(int(x_center - (width_nor / 2)))
        voc_ymin = str(int(y_center - (height_nor / 2)))
        voc_xmax = str(int(x_center + (width_nor / 2)))
        voc_ymax = str(int(y_center + (height_nor / 2)))

        voc_data[each] = [classes, voc_xmin, voc_ymin, voc_xmax, voc_ymax]
    return voc_data

# list3存储VOC格式的数据信息
def list_save_voc(filename_txt,file_name,path_txt,info_voc,size,output_voc_xml):
    folder_txt = filename_txt
    file_name = file_name
    path_txt = path_txt
    #print(folder_txt)
    width_str = str(size[1])
    height_str =str(size[0])
    depth_str = str(size[2])
    info_voc = info_voc

    doc = Document()
    annotation = doc.createElement('annotation')

    doc.appendChild(annotation)
    # folder
    folder = doc.createElement('folder')
    folder_txt = doc.createTextNode(folder_txt)
    folder.appendChild(folder_txt)
    annotation.appendChild(folder)

    # filename
    filename = doc.createElement('filename')
    filename_txt = doc.createTextNode(file_name)
    filename.appendChild(filename_txt)
    annotation.appendChild(filename)

    # path
    path = doc.createElement('path')
    path_txt = doc.createTextNode(path_txt)
    path.appendChild(path_txt)
    annotation.appendChild(path)

    # source
    source = doc.createElement('source')
    annotation.appendChild(source)

    # database
    database = doc.createElement('database')
    database_txt = doc.createTextNode('Unknown')
    database.appendChild(database_txt)
    source.appendChild(database)

    # size
    size = doc.createElement('size')
    annotation.appendChild(size)

    # width
    width = doc.createElement('width')
    width_txt = doc.createTextNode(width_str)
    width.appendChild(width_txt)
    size.appendChild(width)

    # height
    height = doc.createElement('height')
    height_txt = doc.createTextNode(height_str)
    height.appendChild(height_txt)
    size.appendChild(height)

    # depth
    depth = doc.createElement('depth')
    depth_txt = doc.createTextNode(depth_str)
    depth.appendChild(depth_txt)
    size.appendChild(depth)

    # segmented
    segmented = doc.createElement('segmented')
    segmented_txt = doc.createTextNode('0')
    segmented.appendChild(segmented_txt)
    annotation.appendChild(folder)
    object1 = []
    for i in range(len(info_voc)):
        object1.append('name' + str(i))
        object1[i] = doc.createElement('object')
        annotation.appendChild(object1[i])

        # name
        name = doc.createElement('name')
        name_txt = doc.createTextNode(info_voc[i][0])
        name.appendChild(name_txt)
        object1[i].appendChild(name)

        # pose
        pose = doc.createElement('pose')
        pose_txt = doc.createTextNode('Unspecified')
        pose.appendChild(pose_txt)
        object1[i].appendChild(pose)

        # truncated
        truncated = doc.createElement('truncated')
        truncated_txt = doc.createTextNode('0')
        truncated.appendChild(truncated_txt)
        object1[i].appendChild(truncated)

        # difficult
        difficult = doc.createElement('difficult')
        difficult_txt = doc.createTextNode('0')
        difficult.appendChild(difficult_txt)
        object1[i].appendChild(difficult)

        # bndbox
        bndbox = doc.createElement('bndbox')
        object1[i].appendChild(bndbox)

        # xmin
        xmin = doc.createElement('xmin')
        xmin_txt = doc.createTextNode(info_voc[i][1])
        xmin.appendChild(xmin_txt)
        bndbox.appendChild(xmin)

        # ymin
        ymin = doc.createElement('ymin')
        ymin_txt = doc.createTextNode(info_voc[i][2])
        ymin.appendChild(ymin_txt)
        bndbox.appendChild(ymin)

        # xmax
        xmax = doc.createElement('xmax')
        xmax_txt = doc.createTextNode(info_voc[i][3])
        xmax.appendChild(xmax_txt)
        bndbox.appendChild(xmax)

        # ymax
        ymax = doc.createElement('ymax')
        ymax_txt = doc.createTextNode(info_voc[i][4])
        ymax.appendChild(ymax_txt)
        bndbox.appendChild(ymax)
    dirrr = output_voc_xml
    #print(dirrr)
    f = open(dirrr, 'w')
    doc.writexml(f, indent='\t', newl='\n', addindent='\t', encoding='utf-8')
    f.close()


def main():
    tmp_yolo_txt = os.listdir(input_Yolo_txt)
    for file in tmp_yolo_txt:
        (filename, extension) = os.path.splitext(file)
        input_yolo_txt = os.path.join(input_Yolo_txt + "\\" + file)
        input_yolo_image = os.path.join(input_Yolo_image + "\\" + filename + ".tif")
        output_voc_xml = os.path.join(output_Voc_xml + "\\" + filename+".xml")

        if os.path.exists(output_voc_xml):
            os.remove(output_voc_xml)

        img = cv2.imread(input_yolo_image)
        size = img.shape
        info_1 = get_YoloInfo(input_yolo_txt)
        filname_txt = input_yolo_txt.split("\\")[-2]
        file_name = input_yolo_txt.split('\\')[-1]
        path_txt = input_yolo_txt

        info_voc = Yolo_voc_data(size, info_1)
        list_save_voc(filname_txt, file_name, path_txt, info_voc, size, output_voc_xml)

if __name__=="__main__":
    main()

5 DOTA(OBB)转DOTA(HBB)

"""
2019.6.5 将dota的OBB(4点数据)数据转换成dota的HBB数据(4点)
"""
import os

#将dota的OBB数据转换成dota的HBB数据
def OBB_conver_HBB(txtfile,final_savetxt_path):

    file=open(txtfile,'r')
    if os.path.exists(final_savetxt_path):
        os.remove(final_savetxt_path)
    out_file = open(final_savetxt_path, 'a')

    for line in file:
        splitline=line.split(" ")
        xmin=min(float(splitline[0]),float(splitline[2]),float(splitline[4]),float(splitline[6]))
        xmax = max(float(splitline[0]), float(splitline[2]), float(splitline[4]), float(splitline[6]))
        ymin = min(float(splitline[1]), float(splitline[3]), float(splitline[5]), float(splitline[7]))
        ymax = max(float(splitline[1]), float(splitline[3]), float(splitline[5]), float(splitline[7]))

        x1,y1=xmin,ymin
        x2,y2=xmax,ymin
        x3,y3=xmax,ymax
        x4,y4=xmin,ymax

        string=str(x1)+" "+str(y1)+" "+str(x2)+" "+str(y2)+" "+str(x3)+" "+str(y3)+" "+str(x4)+" "+str(y4)+" "+splitline[8]
        # print("###string:",string)
        # os._exit()
        out_file.write(string)


if __name__=="__main__":
    inputfile='/data/maq/DataSet/pytorch_yolov3/guigang/labels_dota_obb4'
    outputfile='/data/maq/DataSet/pytorch_yolov3/guigang/labels_dota_hbb4'

    tempfilename=os.listdir(inputfile)
    for file in tempfilename:
        txtfile=os.path.join(inputfile+"/"+file)
        final_savetxt_path=os.path.join(outputfile+"/"+file)
        OBB_conver_HBB(txtfile,final_savetxt_path)
    print("finished!!!")

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值