在进行语义分割训练时,不同算法支持的数据集格式不同(例如mmsegmentation中每个算法的主页都给出了文件支持的数据集格式),因此有时需要转换数据集的格式
在进行语义分割任务时,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")
文件格式:
ann_dir – train (用于训练的标注文件)
– val (用于测试的标注文件)
img_dir – train (用于训练的原图)
– val (用于测试的标注文件)
训练与测试直接通过放置在对应文件夹来体现。
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)
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)
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)