• python代码:VOC to cityscapes标注文件转换


    在进行语义分割训练时,不同算法支持的数据集格式不同(例如mmsegmentation中每个算法的主页都给出了文件支持的数据集格式),因此有时需要转换数据集的格式

    一、数据集简介

    1.1 关于VOC

    在进行语义分割任务时,VOC的数据集必要的格式为:
    在这里插入图片描述
    其中JPEGImages中为原图,SegmentationonClass中为标注的彩色图,ImageSets中包含两个txt,分别将用于训练和用于测试的图片名称写入。

    可以用以下代码根据某文件夹的名称,将其中所有图片文件名写入txt:

    # -*- coding: utf-8 -*
    import os
    # readInfo函数,根据文件夹路径读取文件夹下所有文件名
    def readInfo():
        filePath = '/你用于训练的图片路径'
        name = os.listdir(filePath)         # os.listdir方法返回一个列表对象
        return name
    
    # 程序入口
    if __name__ == "__main__":
        fileList = readInfo()       # 读取文件夹下所有的文件名,返回一个列表
        file = open('/你的txt路径/train.txt', 'w')   # 创建文件,权限为写入
        print("fileList_size:",len(fileList))
        file_len = len(fileList)
        for i in range(0,file_len):
            fileList[i]=fileList[i][:-4]
        print("-------romove the .png --------")
        #fileList=list(map(int,fileList))
        #fileList.sort()
        print(fileList)
        print("------- sort the list --------")
        for i in fileList:
            #imageDir = 'JPEGImages/' + i
            #annotationDir = 'Annotations/' + i
            #rowInfo = imageDir + ' ' + annotationDir + '\n'
            img_name = i
            #img_name = str(i) 
            print(img_name)
            file.write(img_name)
            file.write("\n")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    1.2 关于cityscapes

    文件格式:
    ann_dir – train (用于训练的标注文件)
    – val (用于测试的标注文件)

    img_dir – train (用于训练的原图)
    – val (用于测试的标注文件)
    训练与测试直接通过放置在对应文件夹来体现。

    1.3 关于标注

    • VOC数据集在标注时使用三通道RGB进行标注,例如有4类,对应的RGB分别为[0,0,0],[255,0,0],[0,255,0],[0,0,255];
    • 而cityscapes数据集的标注文件是8位灰度图,使用灰度值的0,1,2,3等作为标签

    二、一些程序

    1. png-jpg互转

    VOC与 cityscapes好像原图的图片格式不一样,一个是jpg一个是png,这里有一个小的png-jpg互转的程序(直接读入文件名然后将后缀进行更改是会影响图片无法读出的):

    ### jpg--png 互转程序
    import os
    import cv2
    import numpy as np
    from PIL import Image
    
    filepath = r"/原路径/"
    filename = os.listdir(filepath)
    base_dir = filepath + "/"
    new_dir = r"/转换后的路径/"
    
    for img in filename:
        ### png 2 jpg,如果需要jpg 2 png的话把后缀位置的string改一下即可
        if os.path.splitext(img)[1] == '.png' or '.PNG':
            name = os.path.splitext(img)[0]
            newFileName = name + ".jpg"
        im = Image.open(base_dir + img)
        im_gray1 = np.array(im)
        im_gray1 = cv2.cvtColor(im_gray1, cv2.COLOR_BGR2RGB)
        cv2.imwrite(new_dir + newFileName, im_gray1)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2. 批量voc2cityscapes(反向转的话修改if即可)

    import cv2
    import numpy as np
    import os, random, shutil
    from PIL import Image
    
    
    def voc2cityscapes(fileDir,tarDir):
        pathDir = os.listdir(fileDir)    #取图片的原始路径
        filenumber=len(pathDir)
        sample = random.sample(pathDir, filenumber)  
        for name in sample:
            dirpath = fileDir + name
            img_new = trans(dirpath)
            path_name = tarDir + name
            im = Image.fromarray(np.uint8(img_new))
            im = im.convert('L')  # 这样才能转为灰度图,如果是彩色图则改L为‘RGB’
            print("------name-----:",name)
            im.save(path_name)
    
    def trans(dirpath):
        img = cv2.imread(dirpath)
        img_new = np.zeros((len(img),len(img[0])),np.uint8)
        
        for i in range(0,len(img)):
            for j in range(0,len(img[0])):
    ## 视自己的标注文件情况修改RGB
                if (img[i][j][2] == 128 and img[i][j][1]== 0 ): 
                    img_new[i][j] = 1
                elif (img[i][j][1] == 128 and img[i][j][2]== 0):  
                    img_new[i][j] = 2
                elif (img[i][j][1] == 128 and img[i][j][2]== 128): 
                    # img_new[i][j][0] = 0
                    # img_new[i][j][1] = 0
                    # img_new[i][j][2] = 255
                    img_new[i][j] = 3
                    
        # im = Image.fromarray(np.uint8(img_new))
        # im.show()
                      
        return img_new
    
    
    ############################################
    ####### cityscapes 2 voc ####################
    
    # img = cv2.imread(dirpath)
    
    # print("shape of img:",img.shape)
    # print("type of img:",type(img))
    
    # for i in range(0,720):
    #     for j in range(0,1280):
    #         if (img[i][j][0]==1):
    #             img[i][j][0] = 255
    #             img[i][j][1] = 0
    #             img[i][j][2] = 0
    #         elif (img[i][j][0]==2):
    #             img[i][j][0] = 0
    #             img[i][j][1] = 255
    #             img[i][j][2] = 0
    #         elif (img[i][j][0]==3):
    #             img[i][j][0] = 0
    #             img[i][j][1] = 0
    #             img[i][j][2] = 255
    
    # cv2.imwrite('/home/sirlab/zzx_ws/mmsegmentation/data/test_0.png', img)
    
    
    if __name__ == '__main__':
        fileDir = "/home/.../SegmentationClass/"    #源图片文件夹路径
        tarDir  = "/home/.../.../"       #移动到新的文件夹路径
        voc2cityscapes(fileDir,tarDir)
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

    3. 在某文件夹中挑选固定比例的图片(可以用于分开训练集和测试集)

    import os, random, shutil
    def moveFile(fileDir,tarDir):
            pathDir = os.listdir(fileDir)    #取图片的原始路径
            filenumber=len(pathDir)
            rate=0.2                        #自定义抽取图片的比例,比方说100张抽10张,那就是0.1
            picknumber=int(filenumber*rate) #按照rate比例从文件夹中取一定数量图片
            sample = random.sample(pathDir, picknumber)  #随机选取picknumber数量的样本图片
    
            for name in sample:
                shutil.move(fileDir+name, tarDir+name)
    
    if __name__ == '__main__':
        fileDir = "/home/.../"    #源图片文件夹路径
        tarDir  = "/home/.../"       #移动到新的文件夹路径
        
        moveFile(fileDir,tarDir)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
  • 相关阅读:
    ES6中Proxy和Proxy实例
    caffe安装探索整理
    为什么要用PLL时钟芯片替换传统晶体和振荡器?
    【附源码】Python计算机毕业设计球迷信息交流论坛
    Mysql索引优化1
    AI无处不在,科技改变生活:开放原子全球开源峰会参会感悟
    【Linux】:Linux软件包管理器yum
    Python学习(5)-基础语法(输入和输出)
    CLion用于STM32开发
    go-zero微服务实战系列(九、极致优化秒杀性能)
  • 原文地址:https://blog.csdn.net/hongliyu_lvliyu/article/details/126297298