精华内容
下载资源
问答
  • 数据集扩增

    2020-10-13 16:29:52
    UAV里面是单目标标注,其他目标需要自己手动标注,每隔20张取一张标注,再数据增强扩增数据集 import os import numpy as np import cv2 import random from PIL import Image import matplotlib.pyplot as plt from...

    仅作笔记整理搬运使用,没有任何程序原创部分,主要给自己提个醒,避免重复搜索工作
    不会编程,只能拼凑

    一、数据增强(亮度、对比度)

    UAV里面是单目标标注,其他目标需要自己手动标注,每隔20张取一张标注,再数据增强扩增数据集

    import os
    import numpy as np
    import cv2
    import random
    from PIL import Image
    import matplotlib.pyplot as plt
    from matplotlib import cm as CM
    
    def flip_img(image, img_name):
        img1 = cv2.flip(image, 1)
        cv2.imwrite(path_name + '/' + img_name + '_flip.jpg', img1)
    
    
    # def contrast_img(img_name, image, label, h_image, h_label, c, d, e, f):
    def contrast_img(img_name, image, c, d, e, f):
        img2 = np.uint8(np.clip((c * image + random.randint(-30, 30)), 0, 255))
        img3 = np.uint8(np.clip((d * image + random.randint(-30, 30)), 0, 255))
        img4 = np.uint8(np.clip((e * image + random.randint(-30, 30)), 0, 255))
        img5 = np.uint8(np.clip((f * image + random.randint(-30, 30)), 0, 255))
    
        # h_img2 = np.uint8(np.clip((c * h_image + random.randint(-30, 30)), 0, 255))
        # h_img3 = np.uint8(np.clip((d * h_image + random.randint(-30, 30)), 0, 255))
        # h_img4 = np.uint8(np.clip((e * h_image + random.randint(-30, 30)), 0, 255))
        # h_img5 = np.uint8(np.clip((f * h_image + random.randint(-30, 30)), 0, 255))
    
        cv2.imwrite(save_name + '/' + img_name + '_LD1.jpg', img2)
        # label.save(save_label + '/' + img_name + '_LD1.png')
    
        cv2.imwrite(save_name + '/' + img_name + '_LD2.jpg', img3)
        # label.save(save_label + '/' + img_name + '_LD2.png')
    
        cv2.imwrite(save_name + '/' + img_name + '_LD3.jpg', img4)
        # label.save(save_label + '/' + img_name + '_LD3.png')
    
        cv2.imwrite(save_name + '/' + img_name + '_LD4.jpg', img5)
        # label.save(save_label + '/' + img_name + '_LD4.png')
    
    
        # cv2.imwrite(save_name + '/' + img_name + '_flip_LD1.jpg', h_img2)
        # h_label.save(save_label + '/' + img_name + '_flip_LD1.png')
        #
        # cv2.imwrite(save_name + '/' + img_name + '_flip_LD2.jpg', h_img3)
        # h_label.save(save_label + '/' + img_name + '_flip_LD2.png')
        #
        # cv2.imwrite(save_name + '/' + img_name + '_flip_LD3.jpg', h_img4)
        # h_label.save(save_label + '/' + img_name + '_flip_LD3.png')
        #
        # cv2.imwrite(save_name + '/' + img_name + '_flip_LD4.jpg', h_img5)
        # h_label.save(save_label + '/' + img_name + '_flip_LD4.png')
        #
        #
        # cv2.imwrite(save_name + '/' + img_name + '_flip_LD0.jpg', h_image)
        # h_label.save(save_label + '/' + img_name + '_flip_LD0.png')
    
    
    if __name__ == "__main__":
        path_name = 'C:/Users/SHS/Desktop/img1'         #图片地址
        # label_dir = 'data_ROAD/new_Labels_40_15'
    
        save_name = 'C:/Users/SHS/Desktop/img_pro'         #增强后图片地址
        # save_label = 'data_ROAD/new_imp_Labels_40_15'
        num = 0
        color = (0, 255, 0)
    
        for dir_item in os.listdir(path_name):
            # 从初始路径开始叠加,合并成可识别的操作路径
            if dir_item.endswith('.jpg'):
                img_name = os.path.splitext(dir_item)[0]
                # full_path = os.path.abspath(os.path.join(path_name, dir_item))
                image = cv2.imread(os.path.abspath(os.path.join(path_name, dir_item)))
                # label = cv2.imread(os.path.abspath(os.path.join(label_dir, img_name+'.png')))
                # label = Image.open(os.path.abspath(os.path.join(label_dir, img_name+'.png')))
                # print(label)
                # print(origin)
                # origin = np.array(origin)
                # plt.imshow(origin, cmap=CM.jet)
                # plt.show()
                # h_image = cv2.flip(image, 1)  # 图像水平翻转
                # h_label = label.transpose(Image.FLIP_LEFT_RIGHT)
    
                # contrast_img(img_name, image, label, h_image, h_label, 0.5, 0.8, 1.3, 1.6)
                contrast_img(img_name, image, 0.5, 0.8, 1.3, 1.6)
    
                print(img_name)
    
    

    需要图片整体批量重命名

    然后把xml复制四遍,批量重命名后需要把xml中的filename换成本身的文件名

    二、图片翻转

    img和xml同时翻转

    import cv2
    from PIL import Image
    import xml.etree.ElementTree as ET
    from tqdm import tqdm
    import os
    
    
    def flip_horizontal(jpg_file, new_jpg):
        im = Image.open(jpg_file)
        # out = im.transpose(Image.ROTATE_180)
        out = im.transpose(Image.FLIP_LEFT_RIGHT)
        out.save(new_jpg)
    
    
    def flip_xml(xml_file, new_xml):
        tree = ET.parse(xml_file)
        objs = tree.findall('object')
        for ix, obj in enumerate(objs):
            name = obj.find('name').text
            if name == 'car':
                print(xml_file)
                obj_new = obj.find('bndbox')
                xmin = str(1280 - int(obj_new.find('xmin').text))
                xmax = str(1280 - int(obj_new.find('xmax').text))
                obj_new.find('xmin').text = xmin
                obj_new.find('xmax').text = xmax
                tree.write(new_xml)
    
    
    if __name__ == '__main__':
        path = r'C:/Users/SHS/Desktop/img_flip'
        xml_files = [os.path.join(rootdir, file) for rootdir, _, files in os.walk(path) for file in files if
                     (file.endswith('.xml'))]
        jpg_files = [xmlfile.replace('Annotations', 'JPEGImages').replace('xml', 'jpg') for xmlfile in xml_files]
        files = zip(jpg_files, xml_files)
        for jpg_file, xml_file in tqdm(files):
            new_jpg = jpg_file.replace(jpg_file.split('\\')[-1].split('.')[0],
                                       jpg_file.split('\\')[-1].split('.')[0] + '_filp')
            new_xml = new_jpg.replace('JPEGImages', 'Annotations').replace('jpg', 'xml')
            flip_xml(xml_file, new_xml)
            flip_horizontal(jpg_file, new_jpg)
    

    三、图片旋转90度(如果img中只有一个目标)

    新建img、txt、xml文件夹

    
    import os
    import cv2
    import time
    import numpy as np
    import xml.dom.minidom as xmldom
    
    from xml.dom import minidom
    import os
    import cv2
    
    
    def parse_xml(fn):
        xml_file = xmldom.parse(fn)
        eles = xml_file.documentElement
        # print(eles.tagName)
        label = eles.getElementsByTagName("name")[0].firstChild.data
        xmin = eles.getElementsByTagName("xmin")[0].firstChild.data
        xmax = eles.getElementsByTagName("xmax")[0].firstChild.data
        ymin = eles.getElementsByTagName("ymin")[0].firstChild.data
        ymax = eles.getElementsByTagName("ymax")[0].firstChild.data
        # print(xmin, xmax, ymin, ymax)
        return label, xmin, ymin, xmax, ymax
    
    
    def rotate_img(image, angle):  # 自定义旋转函数,使用opencv自带的旋转函数旋转后会有黑边
        (h, w) = image.shape[:2]
        center = (w // 2, h // 2)
        M = cv2.getRotationMatrix2D(center, angle, 1.0)  # 获得旋转矩阵
        # print(M)
        cos = np.abs(M[0, 0])
        sin = np.abs(M[0, 1])
        nW = int((h * sin) + (w * cos))
        nH = int((h * cos) + (w * sin))
        M[0, 2] += (nW / 2) - center[0]
        M[1, 2] += (nH / 2) - center[1]
        rotated = cv2.warpAffine(image, M, (nW, nH))
        return rotated
    
    
    def convert_coo(j, loc_re):  # 修改旋转后的坐标及label
        angle_list = [0, 90, 180, 270, 0, 90, 180, 270]
        if int(initial_angle) in angle_list:
            idx = angle_list.index(int(initial_angle))
            # print(idx)
            add_idx = int(j / 90)
            idx += add_idx
        # w_list = [new_label + str(angle_list[idx])]
        w_list = [new_label]
        # print(w_list)
        if j == 90:
            for l in loc_re:
                x_r, y_r = l[1], w_src - l[0]
                w_list.append(x_r)
                w_list.append(y_r)
        elif j == 180:
            for l in loc_re:
                x_r, y_r = w_src - l[0], h_src - l[1]
                w_list.append(x_r)
                w_list.append(y_r)
        elif j == 270:
            for l in loc_re:
                x_r, y_r = h_src - l[1], l[0]
                w_list.append(x_r)
                w_list.append(y_r)
        return w_list
    
    
    p = 'C:/Users/SHS/Desktop/img_rotate'
    files = [os.path.splitext(i)[0] for i in os.listdir(p) if '.xml' in i]
    angle_list = [90, 180, 270]
    for i in range(len(files)):
        # print('-' * 50)
        # print(files[i] + '.jpg')
        # print(files[i] + '.xml')
        img = cv2.imread(os.path.join(p, files[i] + '.jpg'))
        w_src = img.shape[1] #取图片宽高像素
        h_src = img.shape[0]
        # print(w_src,h_src)
        label, xmin, ymin, xmax, ymax = parse_xml(os.path.join(p, files[i] + '.xml'))
        # new_label = label[:15]
        new_label = label
        # initial_angle = label[15:]
        initial_angle = 0
        print(new_label, xmin,ymin,initial_angle)
    
        loc_re = np.array([float(xmin), float(ymin), float(xmax), float(ymax)]).reshape((2, 2))
        print(loc_re)
        # for j in angle_list:
        #     rotated = rotate_img(img, j)
        #     w_list = convert_coo(j, loc_re)  # 得到的只是旋转前的左上右下对应的旋转后的坐标,并不是旋转后图像的左上右下坐标
        #     # 坐上、右下坐标
        #     res = [None] * 5
        #     res[0] = w_list[0]
        #     res[1] = ((w_list[1] + w_list[3]) / 2) - (abs(w_list[3] - w_list[1]) / 2)
        #     res[2] = ((w_list[2] + w_list[4]) / 2) - (abs(w_list[4] - w_list[2]) / 2)
        #     res[3] = ((w_list[1] + w_list[3]) / 2) + (abs(w_list[3] - w_list[1]) / 2)
        #     res[4] = ((w_list[2] + w_list[4]) / 2) + (abs(w_list[4] - w_list[2]) / 2)
        #     res = [str(k) for k in res]
        #
        #     cv2.imwrite(os.path.join('C:/Users/SHS/Desktop/img_rotate/rotate_img', files[i] + '_' + str(j) + '.jpg'), rotated)
        #     f = open(os.path.join('C:/Users/SHS/Desktop/img_rotate/rotate_txt', files[i] + '_' + str(j) + '.txt'), 'w')
        #     f.write(' '.join(res))
        j = 90
        rotated = rotate_img(img, j)
        w_list = convert_coo(j, loc_re)  # 得到的只是旋转前的左上右下对应的旋转后的坐标,并不是旋转后图像的左上右下坐标
        # 坐上、右下坐标
        res = [None] * 5
        res[0] = w_list[0]
        res[1] = ((w_list[1] + w_list[3]) / 2) - (abs(w_list[3] - w_list[1]) / 2)
        res[2] = ((w_list[2] + w_list[4]) / 2) - (abs(w_list[4] - w_list[2]) / 2)
        res[3] = ((w_list[1] + w_list[3]) / 2) + (abs(w_list[3] - w_list[1]) / 2)
        res[4] = ((w_list[2] + w_list[4]) / 2) + (abs(w_list[4] - w_list[2]) / 2)
        res = [str(k) for k in res]
    
        cv2.imwrite(os.path.join('C:/Users/SHS/Desktop/img_rotate/rotate_img', files[i] + '_' + str(j) + '.jpg'),
                    rotated)
        f = open(os.path.join('C:/Users/SHS/Desktop/img_rotate/rotate_txt', files[i] + '_' + str(j) + '.txt'), 'w')
        f.write(' '.join(res))
    # print(xmin)
    
    
    jpg_list = os.listdir('C:/Users/SHS/Desktop/img_rotate/rotate_img')
    # txt_list=os.listdir(r'label_class/')
    for filename0 in jpg_list:
        print(filename0)
        xml_filename = os.path.splitext(filename0)[0]
        jpg_dirtory = os.path.join(r'C:/Users/SHS/Desktop/img_rotate/rotate_img', filename0)  # jpg文件路径
        txt_dirtory = os.path.join(r'C:/Users/SHS/Desktop/img_rotate/rotate_txt', xml_filename + '.txt')  # txt文件路径
        img_name = jpg_dirtory.split('/')[-1]
        floder = jpg_dirtory  # .split('/')
        im = cv2.imread(jpg_dirtory)
        w = im.shape[1]
        h = im.shape[0]
        d = im.shape[2]
        doc = minidom.Document()  # 创建DOM树对象
        annotation = doc.createElement('annotation')  # 创建子节点
        doc.appendChild(annotation)  # annotation作为doc树的子节点
        folder = doc.createElement('folder')
        folder.appendChild(doc.createTextNode(floder))  # 文本节点作为floder的子节点
        annotation.appendChild(folder)  # folder作为annotation的子节点
        filename = doc.createElement('filename')
        filename.appendChild(doc.createTextNode(img_name))
        annotation.appendChild(filename)
        source = doc.createElement('source')
        database = doc.createElement('database')
        database.appendChild(doc.createTextNode("Unknown"))
        source.appendChild(database)
        annotation.appendChild(source)
        size = doc.createElement('size')
        width = doc.createElement('width')
        width.appendChild(doc.createTextNode("%d" % w))
        size.appendChild(width)
        height = doc.createElement('height')
        height.appendChild(doc.createTextNode("%d" % h))
        size.appendChild(height)
        depth = doc.createElement('depth')
        depth.appendChild(doc.createTextNode("%d" % d))
        annotation.appendChild(size)
        segmented = doc.createElement('segmented')
        segmented.appendChild(doc.createTextNode("0"))
        annotation.appendChild(segmented)
        txtLabel = open(txt_dirtory, 'r')
        boxes = txtLabel.read().splitlines()  # splitlines代替readlines去掉换行符
        for box in boxes:
            box = box.split(' ')
            object = doc.createElement('object')
            nm = doc.createElement('name')
            nm.appendChild(doc.createTextNode(box[0]))
            object.appendChild(nm)
            pose = doc.createElement('pose')
            pose.appendChild(doc.createTextNode("Unspecified"))
            object.appendChild(pose)
            truncated = doc.createElement('truncated')
            truncated.appendChild(doc.createTextNode("0"))
            object.appendChild(truncated)
            difficult = doc.createElement('difficult')
            difficult.appendChild(doc.createTextNode("0"))
            object.appendChild(difficult)
            bndbox = doc.createElement('bndbox')
            xmin = doc.createElement('xmin')
            xmin.appendChild(doc.createTextNode(box[1]))
            bndbox.appendChild(xmin)
            ymin = doc.createElement('ymin')
            ymin.appendChild(doc.createTextNode(box[2]))
            bndbox.appendChild(ymin)
            xmax = doc.createElement('xmax')
            xmax.appendChild(doc.createTextNode(box[3]))
            bndbox.appendChild(xmax)
            ymax = doc.createElement('ymax')
            ymax.appendChild(doc.createTextNode(box[4]))
            bndbox.appendChild(ymax)
            object.appendChild(bndbox)
            annotation.appendChild(object)
    
            p = 'C:/Users/SHS/Desktop/img_rotate/rotate_xml/' + xml_filename + '.xml'  # xml文件保存路径
            savefile = open(p, 'w')
            savefile.write(doc.toprettyxml())
            savefile.close()
    

    四、图片旋转90度(如果img中有多个目标)

    需要把上述三中操作分开

    1. 图片旋转

    import numpy as np
    import os
    import cv2
    
    def rotate_img(image, angle):  # 自定义旋转函数,使用opencv自带的旋转函数旋转后会有黑边
        (h, w) = image.shape[:2]
        center = (w // 2, h // 2)
        M = cv2.getRotationMatrix2D(center, angle, 1.0)  # 获得旋转矩阵
        # print(M)
        cos = np.abs(M[0, 0])
        sin = np.abs(M[0, 1])
        nW = int((h * sin) + (w * cos))
        nH = int((h * cos) + (w * sin))
        M[0, 2] += (nW / 2) - center[0]
        M[1, 2] += (nH / 2) - center[1]
        rotated = cv2.warpAffine(image, M, (nW, nH))
        return rotated
    
    p = 'C:/Users/SHS/Desktop/img_rotate'  #原图片所在路径
    files = [os.path.splitext(i)[0] for i in os.listdir(p) if '.xml' in i]
    angle_list = [90, 180, 270]
    for i in range(len(files)):
        # print('-' * 50)
        # print(files[i] + '.jpg')
        # print(files[i] + '.xml')
        img = cv2.imread(os.path.join(p, files[i] + '.jpg'))
        w_src = img.shape[1] #取图片宽高像素
        h_src = img.shape[0]
        print(w_src,h_src)
        j = 90
        rotated = rotate_img(img, j)
        #保存新的旋转图片文件夹
        cv2.imwrite(os.path.join('C:/Users/SHS/Desktop/img_rotate/rotate_img', files[i] + '_' + str(j) + '.jpg'),
                rotated)
    
    

    2.读xm计算旋转box并转成txtl

    import os
    import xml.etree.ElementTree as ET
    import glob
    import numpy as np
    
    
    def convert_coo(j, loc_re):  # 修改旋转后的坐标及label
        angle_list = [0, 90, 180, 270, 0, 90, 180, 270]
        new_label = 'car'
        initial_angle = 0
        if int(initial_angle) in angle_list:
            idx = angle_list.index(int(initial_angle))
            # print(idx)
            add_idx = int(j / 90)
            idx += add_idx
        # w_list = [new_label + str(angle_list[idx])]
        w_list = [new_label]
        # print(w_list)
        if j == 90:
            for l in loc_re:
                x_r, y_r = l[1], 1280 - l[0]
                w_list.append(x_r)
                w_list.append(y_r)
        # elif j == 180:
        #     for l in loc_re:
        #         x_r, y_r = w_src - l[0], h_src - l[1]
        #         w_list.append(x_r)
        #         w_list.append(y_r)
        # elif j == 270:
        #     for l in loc_re:
        #         x_r, y_r = h_src - l[1], l[0]
        #         w_list.append(x_r)
        #         w_list.append(y_r)
        return w_list
    
    
    def xml_to_txt(indir, outdir):
        os.chdir(indir)
        annotations = os.listdir('.')
        annotations = glob.glob(str(annotations) + '*.xml')
        print(annotations)
        for i, file in enumerate(annotations):
    
            file_save = file.split('.')[0] + '_90'+'.txt'
            # file_txt=os.path.join(outdir,file_save)
            file_txt = outdir + "\\" + file_save
            # print(file_save)
            f_w = open(file_txt, 'w')
    
            # actual parsing
            in_file = open(file)
            tree = ET.parse(in_file)
            root = tree.getroot()
            filename = root.find('filename').text  # 这里是xml的根,获取filename那一栏
            for obj in root.iter('object'):
                current = list()
                name = obj.find('name').text  # 这里获取多个框的名字,底下是获取每个框的位置
    
                xmlbox = obj.find('bndbox')
                xn = xmlbox.find('xmin').text
                xx = xmlbox.find('xmax').text
                yn = xmlbox.find('ymin').text
                yx = xmlbox.find('ymax').text
    
                # print(new_label, xmin,ymin,initial_angle)
    
                loc_re = np.array([float(xn), float(yn), float(xx), float(yx)]).reshape((2, 2))
                j = 90
                # rotated = rotate_img(img, j)
                w_list = convert_coo(j, loc_re)  # 得到的只是旋转前的左上右下对应的旋转后的坐标,并不是旋转后图像的左上右下坐标
                # 坐上、右下坐标
                res = [None] * 5
                res[0] = w_list[0]
                res[1] = ((w_list[1] + w_list[3]) / 2) - (abs(w_list[3] - w_list[1]) / 2)
                res[2] = ((w_list[2] + w_list[4]) / 2) - (abs(w_list[4] - w_list[2]) / 2)
                res[3] = ((w_list[1] + w_list[3]) / 2) + (abs(w_list[3] - w_list[1]) / 2)
                res[4] = ((w_list[2] + w_list[4]) / 2) + (abs(w_list[4] - w_list[2]) / 2)
                res = [str(k) for k in res]
                # print xn
                f_w.write(res[0] + ' ' + res[1] + ' ' + res[2] + ' ' + res[3] + ' ' + res[4] + ' ')
                # f_w.write(filename + ' ' + xn + ' ' + yn + ' ' + xx + ' ' + yx + ' ')
                f_w.write('\n')
    
    
    indir = 'C:/Users/SHS/Desktop/img_rotate'  # xml目录
    outdir = 'C:/Users/SHS/Desktop/img_rotate/rotate_txt'  # txt目录
    
    xml_to_txt(indir, outdir)
    

    3.把txt转换成xml

    from xml.dom import minidom
    import os
    import cv2
    
    jpg_list = os.listdir('C:/Users/SHS/Desktop/img_rotate/rotate_img')
    # txt_list=os.listdir(r'label_class/')
    for filename0 in jpg_list:
        print(filename0)
        xml_filename = os.path.splitext(filename0)[0]
         # jpg文件路径↓
        jpg_dirtory = os.path.join(r'C:/Users/SHS/Desktop/img_rotate/rotate_img', filename0) 
         # txt文件路径↓
        txt_dirtory = os.path.join(r'C:/Users/SHS/Desktop/img_rotate/rotate_txt', xml_filename + '.txt') 
        img_name = jpg_dirtory.split('/')[-1]
        floder = jpg_dirtory  # .split('/')
        im = cv2.imread(jpg_dirtory)
        w = im.shape[1]
        h = im.shape[0]
        d = im.shape[2]
        doc = minidom.Document()  # 创建DOM树对象
        annotation = doc.createElement('annotation')  # 创建子节点
        doc.appendChild(annotation)  # annotation作为doc树的子节点
        folder = doc.createElement('folder')
        folder.appendChild(doc.createTextNode(floder))  # 文本节点作为floder的子节点
        annotation.appendChild(folder)  # folder作为annotation的子节点
        filename = doc.createElement('filename')
        filename.appendChild(doc.createTextNode(img_name))
        annotation.appendChild(filename)
        source = doc.createElement('source')
        database = doc.createElement('database')
        database.appendChild(doc.createTextNode("Unknown"))
        source.appendChild(database)
        annotation.appendChild(source)
        size = doc.createElement('size')
        width = doc.createElement('width')
        width.appendChild(doc.createTextNode("%d" % w))
        size.appendChild(width)
        height = doc.createElement('height')
        height.appendChild(doc.createTextNode("%d" % h))
        size.appendChild(height)
        depth = doc.createElement('depth')
        depth.appendChild(doc.createTextNode("%d" % d))
        annotation.appendChild(size)
        segmented = doc.createElement('segmented')
        segmented.appendChild(doc.createTextNode("0"))
        annotation.appendChild(segmented)
        txtLabel = open(txt_dirtory, 'r')
        boxes = txtLabel.read().splitlines()  # splitlines代替readlines去掉换行符
        for box in boxes:
            box = box.split(' ')
            object = doc.createElement('object')
            nm = doc.createElement('name')
            nm.appendChild(doc.createTextNode(box[0]))
            object.appendChild(nm)
            pose = doc.createElement('pose')
            pose.appendChild(doc.createTextNode("Unspecified"))
            object.appendChild(pose)
            truncated = doc.createElement('truncated')
            truncated.appendChild(doc.createTextNode("0"))
            object.appendChild(truncated)
            difficult = doc.createElement('difficult')
            difficult.appendChild(doc.createTextNode("0"))
            object.appendChild(difficult)
            bndbox = doc.createElement('bndbox')
            xmin = doc.createElement('xmin')
            xmin.appendChild(doc.createTextNode(box[1]))
            bndbox.appendChild(xmin)
            ymin = doc.createElement('ymin')
            ymin.appendChild(doc.createTextNode(box[2]))
            bndbox.appendChild(ymin)
            xmax = doc.createElement('xmax')
            xmax.appendChild(doc.createTextNode(box[3]))
            bndbox.appendChild(xmax)
            ymax = doc.createElement('ymax')
            ymax.appendChild(doc.createTextNode(box[4]))
            bndbox.appendChild(ymax)
            object.appendChild(bndbox)
            annotation.appendChild(object)
    
            p = 'C:/Users/SHS/Desktop/img_rotate/rotate_xml/' + xml_filename + '.xml'  # xml文件保存路径
            savefile = open(p, 'w')
            savefile.write(doc.toprettyxml())
            savefile.close()
    

    4.批量重命名

    消除因为重命名而在文件名字中出现的空格
    img和xml都要重命名和去空格

    https://blog.csdn.net/Sunhansong/article/details/107281225

    5.把xml中filename模块中改成重命名好的图片名字

    import os
    #input_dir='./xml'
    input_dir=r"C:/Users/SHS/Desktop/uav/VOCdevkit/VOC2007/Annotations/"#xml路径
    import xml.etree.ElementTree as ET
    for filename in os.listdir(input_dir):
        file_path = os.path.join(input_dir, filename)
        out_path='C:/Users/SHS/Desktop/xml_rename/'+filename#生成新的路径
        dom = ET.parse(file_path)
        root = dom.getroot()
        for ann in root.iter('annotation'):#获取filename节点
            ann.find('filename').text=filename[:-4]+'.jpg'
        dom.write(out_path, xml_declaration=True)
    

    如果出错就是环境的问题,稍微调一下

    参考博客:
    https://blog.csdn.net/qq_41192383/article/details/95140597
    https://blog.csdn.net/weixin_42486139/article/details/102896267
    https://blog.csdn.net/qq_21997625/article/details/85068098

    展开全文
  • 针对在回归测试中原有的测试数据集往往难以满足新版本软件的测试需求问题,提出一种基于搜索的分层回归测试数据集扩增方法,主要包含覆盖目标方法集获取模块和测试数据生成模块。首先对新版本程序进行抽象分析,提取...
  • 正则化方法 L1和L2 regularization 数据集扩增 dropout
                         

    本文是《Neural networks and deep learning》概览 中第三章的一部分,讲机器学习/深度学习算法中常用的正则化方法。(本文会不断补充)



    正则化方法:防止过拟合,提高泛化能力

    在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合)。其直观的表现如下图所示,随着训练过程的进行,模型复杂度增加,在training data上的error渐渐减小,但是在验证集上的error却反而渐渐增大——因为训练出来的网络过拟合了训练集,对训练集外的数据却不work。

    为了防止overfitting,可以用的方法有很多,下文就将以此展开。有一个概念需要先说明,在机器学习算法中,我们常常将原始数据集分为三部分:training data、validation data,testing data。这个validation data是什么?它其实就是用来避免过拟合的,在训练过程中,我们通常用它来确定一些超参数(比如根据validation data上的accuracy来确定early stopping的epoch大小、根据validation data确定learning rate等等)。那为啥不直接在testing data上做这些呢?因为如果在testing data做这些,那么随着训练的进行,我们的网络实际上就是在一点一点地overfitting我们的testing data,导致最后得到的testing accuracy没有任何参考意义。因此,training data的作用是计算梯度更新权重,validation data如上所述,testing data则给出一个accuracy以判断网络的好坏。

    避免过拟合的方法有很多:early stopping、数据集扩增(Data augmentation)、正则化(Regularization)包括L1、L2(L2 regularization也叫weight decay),dropout。



    L2 regularization(权重衰减)

    L2正则化就是在代价函数后面再加上一个正则化项:

    C0代表原始的代价函数,后面那一项就是L2正则化项,它是这样来的:所有参数w的平方的和,除以训练集的样本大小n。λ就是正则项系数,权衡正则项与C0项的比重。另外还有一个系数1/2,1/2经常会看到,主要是为了后面求导的结果方便,后面那一项求导会产生一个2,与1/2相乘刚好凑整。

    L2正则化项是怎么避免overfitting的呢?我们推导一下看看,先求导:

    可以发现L2正则化项对b的更新没有影响,但是对于w的更新有影响:

    在不使用L2正则化时,求导结果中w前系数为1,现在w前面系数为 1−ηλ/n ,因为η、λ、n都是正的,所以 1−ηλ/n小于1,它的效果是减小w,这也就是权重衰减(weight decay)的由来。当然考虑到后面的导数项,w最终的值可能增大也可能减小。

    另外,需要提一下,对于基于mini-batch的随机梯度下降,w和b更新的公式跟上面给出的有点不同:

    对比上面w的更新公式,可以发现后面那一项变了,变成所有导数加和,乘以η再除以m,m是一个mini-batch中样本的个数。

    到目前为止,我们只是解释了L2正则化项有让w“变小”的效果,但是还没解释为什么w“变小”可以防止overfitting?一个所谓“显而易见”的解释就是:更小的权值w,从某种意义上说,表示网络的复杂度更低,对数据的拟合刚刚好(这个法则也叫做奥卡姆剃刀),而在实际应用中,也验证了这一点,L2正则化的效果往往好于未经正则化的效果。当然,对于很多人(包括我)来说,这个解释似乎不那么显而易见,所以这里添加一个稍微数学一点的解释(引自知乎):

    过拟合的时候,拟合函数的系数往往非常大,为什么?如下图所示,过拟合,就是拟合函数需要顾忌每一个点,最终形成的拟合函数波动很大。在某些很小的区间里,函数值的变化很剧烈。这就意味着函数在某些小区间里的导数值(绝对值)非常大,由于自变量值可大可小,所以只有系数足够大,才能保证导数值很大。

    而正则化是通过约束参数的范数使其不要太大,所以可以在一定程度上减少过拟合情况。



    L1 regularization

    在原始的代价函数后面加上一个L1正则化项,即所有权重w的绝对值的和,乘以λ/n(这里不像L2正则化项那样,需要再乘以1/2,具体原因上面已经说过。)

    同样先计算导数:

    上式中sgn(w)表示w的符号。那么权重w的更新规则为:

    比原始的更新规则多出了η * λ * sgn(w)/n这一项。当w为正时,更新后的w变小。当w为负时,更新后的w变大——因此它的效果就是让w往0靠,使网络中的权重尽可能为0,也就相当于减小了网络复杂度,防止过拟合。

    另外,上面没有提到一个问题,当w为0时怎么办?当w等于0时,|W|是不可导的,所以我们只能按照原始的未经正则化的方法去更新w,这就相当于去掉η*λ*sgn(w)/n这一项,所以我们可以规定sgn(0)=0,这样就把w=0的情况也统一进来了。(在编程的时候,令sgn(0)=0,sgn(w>0)=1,sgn(w<0)=-1)



    Dropout

    L1、L2正则化是通过修改代价函数来实现的,而Dropout则是通过修改神经网络本身来实现的,它是在训练网络时用的一种技巧(trike)。它的流程如下:

    假设我们要训练上图这个网络,在训练开始时,我们随机地“删除”一半的隐层单元,视它们为不存在,得到如下的网络:

    保持输入输出层不变,按照BP算法更新上图神经网络中的权值(虚线连接的单元不更新,因为它们被“临时删除”了)。

    以上就是一次迭代的过程,在第二次迭代中,也用同样的方法,只不过这次删除的那一半隐层单元,跟上一次删除掉的肯定是不一样的,因为我们每一次迭代都是“随机”地去删掉一半。第三次、第四次……都是这样,直至训练结束。

    以上就是Dropout,它为什么有助于防止过拟合呢?可以简单地这样解释,运用了dropout的训练过程,相当于训练了很多个只有半数隐层单元的神经网络(后面简称为“半数网络”),每一个这样的半数网络,都可以给出一个分类结果,这些结果有的是正确的,有的是错误的。随着训练的进行,大部分半数网络都可以给出正确的分类结果,那么少数的错误分类结果就不会对最终结果造成大的影响。

    更加深入地理解,可以看看Hinton和Alex两牛2012的论文《ImageNet Classification with Deep Convolutional Neural Networks》



    数据集扩增(data augmentation)

    “有时候不是因为算法好赢了,而是因为拥有更多的数据才赢了。”

    不记得原话是哪位大牛说的了,hinton?从中可见训练数据有多么重要,特别是在深度学习方法中,更多的训练数据,意味着可以用更深的网络,训练出更好的模型。

    既然这样,收集更多的数据不就行啦?如果能够收集更多可以用的数据,当然好。但是很多时候,收集更多的数据意味着需要耗费更多的人力物力,有弄过人工标注的同学就知道,效率特别低,简直是粗活。

    所以,可以在原始数据上做些改动,得到更多的数据,以图片数据集举例,可以做各种变换,如:

    • 将原始图片旋转一个小角度

    • 添加随机噪声

    • 一些有弹性的畸变(elastic distortions),论文《Best practices for convolutional neural networks applied to visual document analysis》对MNIST做了各种变种扩增。

    • 截取(crop)原始图片的一部分。比如DeepID中,从一副人脸图中,截取出了100个小patch作为训练数据,极大地增加了数据集。感兴趣的可以看《Deep learning face representation from predicting 10,000 classes》.

      更多数据意味着什么?

    用50000个MNIST的样本训练SVM得出的accuracy94.48%,用5000个MNIST的样本训练NN得出accuracy为93.24%,所以更多的数据可以使算法表现得更好。在机器学习中,算法本身并不能决出胜负,不能武断地说这些算法谁优谁劣,因为数据对算法性能的影响很大。



    转载请注明出处:http://blog.csdn.net/u012162613/article/details/44261657

               
    展开全文
  • 正则化方法:L1和L2 regularization、数据集扩增、dropout

    本文是《Neural networks and deep learning》概览 中第三章的一部分,讲机器学习/深度学习算法中常用的正则化方法。(本文会不断补充)



    正则化方法:防止过拟合,提高泛化能力

    在训练数据不够多时,或者overtraining时,常常会导致overfitting(过拟合)。其直观的表现如下图所示,随着训练过程,网络在training data上的error渐渐减小,但是在验证集上的error却反而渐渐增大——因为训练出来的网络过拟合了训练集,对训练集外的数据却不work。

    技术分享

    为了防止overfitting,可以用的方法有很多,下文就将以此展开。有一个概念需要先说明,在机器学习算法中,我们常常将原始数据集分为三部分:training data、validation data,testing data。这个validation data是什么?它其实就是用来避免过拟合的,在训练过程中,我们通常用它来确定一些超参数(比如根据validation data上的accuracy来确定early stopping的epoch大小、根据validation data确定learning rate等等)。那为啥不直接在testing data上做这些呢?因为如果在testing data做这些,那么随着训练的进行,我们的网络实际上就是在一点一点地overfitting我们的testing data,导致最后得到的testing accuracy没有任何参考意义。因此,training data的作用是计算梯度更新权重,validation data如上所述,testing data则给出一个accuracy以判断网络的好坏。

    避免过拟合的方法有很多:early stopping、数据集扩增(Data augmentation)、正则化(Regularization)包括L1、L2(L2 regularization也叫weight decay),dropout。



    L2 regularization(权重衰减)

    L2正则化就是在代价函数后面再加上一个正则化项:

    技术分享

    C0代表原始的代价函数,后面那一项就是L2正则化项,它是这样来的:所有参数w的平方的和,除以训练集的样本大小n。λ就是正则项系数,权衡正则项与C0项的比重。另外还有一个系数1/2,1/2经常会看到,主要是为了后面求导的结果方便,后面那一项求导会产生一个2,与1/2相乘刚好凑整。

    L2正则化项是怎么避免overfitting的呢?我们推导一下看看,先求导:

    技术分享

    可以发现L2正则化项对b的更新没有影响,但是对于w的更新有影响:

    技术分享

    在不使用L2正则化时,求导结果中w前系数为1,现在w前面系数为 1?ηλ/n ,因为η、λ、n都是正的,所以 1?ηλ/n小于1,它的效果是减小w,这也就是权重衰减(weight decay)的由来。当然考虑到后面的导数项,w最终的值可能增大也可能减小。

    另外,需要提一下,对于基于mini-batch的随机梯度下降,w和b更新的公式跟上面给出的有点不同:

    技术分享

    技术分享

    对比上面w的更新公式,可以发现后面那一项变了,变成所有导数加和,乘以η再除以m,m是一个mini-batch中样本的个数。

    到目前为止,我们只是解释了L2正则化项有让w“变小”的效果,但是还没解释为什么w“变小”可以防止overfitting?人们普遍认为:更小的权值w,从某种意义上说,表示网络的复杂度更低,对数据的拟合刚刚好(这个法则也叫做奥卡姆剃刀)。而在实际应用中,也验证了这一点,L2正则化的效果往往好于未经正则化的效果。



    L1 regularization

    在原始的代价函数后面加上一个L1正则化项,即所有权重w的绝对值的和,乘以λ/n(这里不像L2正则化项那样,需要再乘以1/2,具体原因上面已经说过。)

    技术分享

    同样先计算导数:

    技术分享

    上式中sgn(w)表示w的符号。那么权重w的更新规则为:

    技术分享

    比原始的更新规则多出了η * λ * sgn(w)/n这一项。当w为正时,更新后的w变小。当w为负时,更新后的w变大——因此它的效果就是让w往0靠,使网络中的权重尽可能为0,也就相当于减小了网络复杂度,防止过拟合。

    另外,上面没有提到一个问题,当w为0时怎么办?当w等于0时,|W|是不可导的,所以我们只能按照原始的未经正则化的方法去更新w,这就相当于去掉η*λ*sgn(w)/n这一项,所以我们可以规定sgn(0)=0,这样就把w=0的情况也统一进来了。(在编程的时候,令sgn(0)=0,sgn(w>0)=1,sgn(w<0)=-1)



    数据集扩增(data augmentation)

    “有时候不是因为算法好赢了,而是因为拥有更多的数据才赢了。”

    不记得原话是哪位大牛说的了,hinton?从中可见训练数据有多么重要,特别是在深度学习方法中,更多的训练数据,意味着可以用更深的网络,训练出更好的模型。

    既然这样,收集更多的数据不就行啦?如果能够收集更多可以用的数据,当然好。但是很多时候,收集更多的数据意味着需要耗费更多的人力物力,有弄过人工标注的同学就知道,效率特别低,简直是粗活。

    所以,可以在原始数据上做些改动,得到更多的数据,以图片数据集举例,可以做各种变换,如:

    • 将原始图片旋转一个小角度

    • 添加随机噪声

    • 一些有弹性的畸变(elastic distortions),论文《Best practices for convolutional neural networks applied to visual document analysis》对MNIST做了各种变种扩增。

    • 截取(crop)原始图片的一部分。比如DeepID中,从一副人脸图中,截取出了100个小patch作为训练数据,极大地增加了数据集。感兴趣的可以看《Deep learning face representation from predicting 10,000 classes》.

      更多数据意味着什么?

    用50000个MNIST的样本训练SVM得出的accuracy94.48%,用5000个MNIST的样本训练NN得出accuracy为93.24%,所以更多的数据可以使算法表现得更好。在机器学习中,算法本身并不能决出胜负,不能武断地说这些算法谁优谁劣,因为数据对算法性能的影响很大。

    技术分享



    转载请注明出处:http://blog.csdn.net/u012162613/article/details/44261657

    展开全文
  • 正则化方法:防止过拟合,提高泛化能力 ...数据集扩增;Droupout方法   (1) L1正则化 (2) L2正则化 (3) Droupout 【参考】https://blog.csdn.net/u012162613/article/details/44261657  ...

    正则化方法:防止过拟合,提高泛化能力

     

    常用的正则化方法有:L1正则化;L2正则化;数据集扩增;Droupout方法

     

    (1) L1正则化

    (2) L2正则化

    (3) Droupout

    【参考】https://blog.csdn.net/u012162613/article/details/44261657
     

    展开全文
  • 深度学习目标检测数据集扩增方法

    千次阅读 2019-07-03 14:33:02
    先放出链接吧,后续跑得时候补充 论文传送门: https://arxiv.org/abs/1906.11172 代码传送门: https://github.com/tensorflow/tpu/tree/master/models/official/detection
  • 避免过拟合的方法:early stopping、数据集扩增(Data augmentation)、正则化(Regularization,dropout等。正则化方法:防止过拟合,提高泛化能力在训练数据不够多时,或者overtraining时,常常会导致overfitting...
  • 百度直接进入keras官网 找到Image Preprocessing类 根据需求填写对应的参数可快速增加自己的数据集
  • 其直观的表现如下图所示,随着训练过程的进行,模型复杂度增加,在training data上的error渐渐减小,但是在验证上的error却反而渐渐增大——因为训练出来的网络过拟合了训练,对训练外的数据却不work。...
  • 其直观的表现如下图所示,随着训练过程的进行,模型复杂度增加,在training data上的error渐渐减小,但是在验证上的error却反而渐渐增大——因为训练出来的网络过拟合了训练,对训练外的数据却不work。...

空空如也

空空如也

1 2 3 4 5 ... 16
收藏数 312
精华内容 124
关键字:

数据集扩增