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 关于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)

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)


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)

你可能感兴趣的:(视觉,图像处理,python,计算机视觉,opencv)