python 将Mnist数据集转为jpg,并按比例/标签拆分为多个子数据集


现有条件:Mnist数据集,下载地址:跳转 下载后的四个.gz文件解压后放到同一个文件夹下,如:/raw

Step 1:将Mnist数据集转为jpg图片(代码来自这篇博客)

 1 import os  2 from skimage import io  3 import torchvision.datasets.mnist as mnist  4 
 5 root='./raw'
 6 train_set = (  7     mnist.read_image_file(os.path.join(root, 'train-images.idx3-ubyte')),  8     mnist.read_label_file(os.path.join(root, 'train-labels.idx1-ubyte'))  9  ) 10 test_set = ( 11     mnist.read_image_file(os.path.join(root, 't10k-images.idx3-ubyte')), 12     mnist.read_label_file(os.path.join(root, 't10k-labels.idx1-ubyte')) 13  ) 14 # print("training set :",train_set[0].size())
15 # print("test set :",test_set[0].size())
16 
17 def convert_to_img(train=True): 18     if(train): 19         f=open(root+'train.txt','w') 20         data_path=root+'/train/'
21         if(not os.path.exists(data_path)): 22  os.makedirs(data_path) 23         for i, (img,label) in enumerate(zip(train_set[0],train_set[1])): 24             img_path=data_path+str(i)+'.jpg'
25             # io.imsave(img_path,img.numpy())
26             f.write(img_path+' '+str(label)+'\n') 27  f.close() 28     else: 29         f = open(root + 'test.txt', 'w') 30         data_path = root + '/test/'
31         if (not os.path.exists(data_path)): 32  os.makedirs(data_path) 33         for i, (img,label) in enumerate(zip(test_set[0],test_set[1])): 34             img_path = data_path+ str(i) + '.jpg'
35             # io.imsave(img_path, img.numpy())
36             f.write(img_path + ' ' + str(label) + '\n') 37  f.close() 38 
39 convert_to_img(True)#转换训练集
40 convert_to_img(False)#转换测试集
View Code

此时,转换后的jpg存储格式如下:

test和train中的图片全是未按标签分类的混合jpg图片

Step 1.1: 将数据根据txt文件按label分类

在train和test文件夹下分别手动创建10个文件夹,命名从0-9,如新建一个文件夹,文件夹名字为6

代码实现过程中由于有些需要重复操作,为了便于直接使用 我下面直接按使用步骤全部贴出(可能重复代码有点多,看懂后你可以直接修改

 1 # 1.1.1 将train文件中的tensor(换为=
 2     fileName = 'rawtrain.txt'
 3     f = open(fileName,'w')  4     lines = f.readlines()  5 
 6     for line in lines:  7         f.write(line.replace("tensor(","="))  8  f.close()  9 # 1.1.2 将train文件中的)去掉,不能同时执行tensor(和)的操作,必须顺序执行
10     fileName = 'rawtrain.txt'
11     f = open(fileName,'w') 12     lines = f.readlines() 13 
14     for line in lines: 15         f.write(line.replace(")", "")) 16  f.close() 17 
18 # 1.1.3 将上述的文件名换为'rawtest.txt' 重复执行
19 
20 # 1.1.4 按rawtrain.txt文件将图片移动至对对应标签的文件夹下
21     fileName = 'rawtrain.txt'
22     f = open(fileName,'r') 23     lines = f.readlines() 24     label = [-1] 25     f = open(fileName,'w') 26 
27     for line in lines: 28         splitL = line.split('=') 29         labelnum = int(splitL[1]) 30  label.append(labelnum) 31  f.close() 32     del label[0] 33     # 此时label存储图片标签
34 
35     # 读取图片并移动
36     root = './raw/train'
37     i = 0 38     lens = len(os.listdir(root)) 39     while(lens > 10): 40         img_path = os.path.join(root, str(i)+'.jpg') 41         img_label = label[i] 42         img_new_path = os.path.join(root, str(img_label), str(i)+'.jpg') 43  shutil.move(img_path, img_new_path) 44         i += 1
45         lens = len(os.listdir(root)) 46 
47 
48 # 1.1.5 按rawtest.txt文件将图片移动至对对应标签的文件夹下
49     fileName = 'rawtest.txt'
50     f = open(fileName,'r') 51     lines = f.readlines() 52     label = [-1] 53     f = open(fileName,'w') 54 
55     for line in lines: 56         # f.write(line.replace("tensor(","="))
57         # f.write(line.replace(")", ""))
58         splitL = line.split('=') 59         labelnum = int(splitL[1]) 60  label.append(labelnum) 61  f.close() 62     del label[0] 63     # 此时label存储图片标签
64 
65     # 读取图片
66     root = './raw/test'
67     i = 0 68     lens = len(os.listdir(root)) 69     while(lens > 10): 70         img_path = os.path.join(root, str(i)+'.jpg') 71         img_label = label[i] 72         img_new_path = os.path.join(root, str(img_label), str(i)+'.jpg') 73  shutil.move(img_path, img_new_path) 74         i += 1
75         lens = len(os.listdir(root))
View Code

 

Step 2: 将raw下的jpg图片随机分为10个数据集,每个数据集中的图片数相同(包括train and test),并且每个数据集下的图片按标签分类

分类后的结构如下图:

代码实现:

Step 2.1:新建所需要的所有文件夹

 1 root = './newDataSet/'
 2     for labelname in range(10):  3         # domain
 4         domain_path = os.path.join(root, "domain"+str(labelname))  5         # train / test
 6         for use2 in range(2):  7             useName = ''
 8             if use2 == 0:  9                 useName = 'train'
10             else: 11                 useName = 'test'
12             use_path = os.path.join(domain_path, useName) 13             # label
14             for i in range(10): 15                 label_path = os.path.join(use_path, str(i)) 16                 if os.path.exists(label_path) != True: 17                     try: 18                         os.mkdir(label_path)  # 创建单层文件夹
19                     except Exception as e: 20                         os.makedirs(label_path)  # 创建多层文件夹
View Code

Step 2.2: 将raw下的数据按一定比例复制到新的文件夹下(我的代码下不同子数据集的训练数据是来自train的每个标签200张-无交叉,test每个标签50张)

 1    num = 0  2     d_num = 0  3     src_root = './raw/train'
 4     # src_root = './raw/test' # 先执行train 执行结束后再注释掉train 执行test图片复制
 5     dst_root = './newDataSet/'
 6     aims = 'train'
 7     # aims = 'test'
 8     for label in os.listdir(src_root):  # 0
 9         label_path = os.path.join(src_root, label) 10         for img in os.listdir(label_path):  # 1.jpg
11             img_path = os.path.join(label_path, str(img)) 12             img_new_path = os.path.join(dst_root, "domain"+str(d_num), aims, str(label), str(img)) 13  shutil.copyfile(img_path, img_new_path) 14             num += 1
15             if num == 200: 16             # if num == 50: # for test
17                 d_num += 1
18                 num = 0 19                 if d_num == 10: 20                     d_num = 0 21                     break
View Code

 

Step 3: 将raw下的jpg图片分为10个数据集,每个数据集中的图片数相同(包括train and test),并且每个数据集下的图片仅包含一个标签的图片,虽然文件夹结构和第2步相同,但是,如/domain 8/train/1路径下无图片,仅/domain 8/train/8下有数字8的图片,而domain0也仅是Label为0的文件夹下有数字为0的图片

Step 3.1:新建所需的所有文件夹,代码参考Step 2.1 只是需要将root名称换一个

Step 3.2: 将raw下数据按标签和一定比例复制到新的文件夹下。

 1  num = 0  2     # src_root = './raw/test'
 3     src_root = './raw/train'  # 对train文件操作后需要对test文件执行相同的操作
 4     dst_root = './newDatSet1/'
 5     aims = 'train'
 6     # aims = 'test'
 7     for label in os.listdir(src_root):  # 0
 8         label_path = os.path.join(src_root, label)  9         for img in os.listdir(label_path):  # 1.jpg
10             img_path = os.path.join(label_path, str(img)) 11             img_new_path = os.path.join(dst_root, "domain" + str(label), aims, str(label), str(img)) 12  shutil.copyfile(img_path, img_new_path) 13             num += 1
14             if num == 2000:  # train数据为2k,测试数据为500,全部为一个Label的数据
15             # if num == 500:
16                 num = 0 17                 break
View Code

至此 两个需要的新的拆分格式的数据集创建完毕。所有代码已经测试,均正常运行。

 

后续:我的方法好像有点繁琐了...参考这篇tensorflow的博客好像更简单。。。

Step 2: 将raw下的jpg图片随机分为10个数据集,每个数据集中的图片数相同(包括train and test),并且每个数据集下的图片按标签分类


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM