用圖片加.xls格式的label讀入數據集
先來看看我的代碼吧:
import os
import xlrd
#*******************製作‘路徑 標籤’格式的.txt文件****************************
xl = xlrd.open_workbook(r'E:\Python\project\DIY\MESSIDOR\val\Annotation_Base2.xls')
table = xl.sheets()[0]
nRow=table.nrows #行數
nCol=table.ncols #列數
list=[]
# for i in range(nCol):
for j in range(1,nRow):
list.append(str(table.row_values(j)[2])) #[n] n爲要讀取數據的列數
for i in range(len(list)):
try:
list[i] = float(list[i])
list[i] = int(list[i])
except:
pass
print(list)
list1=[]
for j in range(1,nRow):
list1.append(str(table.row_values(j)[0])) #[n] n爲要讀取數據的列數
# for i in range(len(list)):
# try:
# list[i] = float(list[i])
# list[i] = int(list[i])
# except:
# pass
print(list1)
def generate(dir, label, Pic_name):
i=0
files = os.listdir(dir)
files.sort()
print('****************')
print('input :', dir)
print('start...')
# listText = open(dir + '\\' + 'list.txt', 'w')
listText = open('E:/Python/project/DIY/MESSIDOR/val' + '\\' + 'list.txt', 'w')
for file in files:
fileType = os.path.split(file)
if fileType[1] == '.txt':
continue
name =dir + '/' + str(Pic_name[i]) + ' ' + str(label[i]) + '\n'
listText.write(name)
i=i+1
if i==360:
i=0
# listText.close()
print('down!')
print('****************')
if __name__ == '__main__':
# generate('E:/Python/project/DIY/MESSIDOR/train/Base1', list,list1)
generate('E:/Python/project/DIY/MESSIDOR/val/Base2', list,list1)
# generate('E:/Python/project/DIY/MESSIDOR/all/Base', list, list1)
我的數據集的格式爲:所有的圖片都在一個文件夾裏面,然後是.xls格式的label。之前有試過製作cifar10格式的數據集,結果卡在了.meta文件這個步驟上。後來又查找了好多大神的教程,圈定了這個比較友好的製作數據集的格式。製作一個.txt格式的文件,之後可以自己定義一個dataload類讀取數據集
label的格式是這個樣子的:
圖片數據集的格式是這樣的
在網絡裏可以直接讀取這個.txt格式的文件,list.txt中的圖片地址可以直接鏈接到圖片,list.txt中的label直接就讀成label就行。這對小白很友好啊有沒有
# 首先繼承上面的dataset類。然後在__init__()方法中得到圖像的路徑,然後將圖像路徑組成一個數組,這樣在__getitim__()中就可以直接讀取:
class MyDataset(Dataset): # 創建自己的類:MyDataset,這個類是繼承的torch.utils.data.Dataset
def __init__(self, txt, transform=None, target_transform=None, loader=default_loader): # 初始化一些需要傳入的參數
super(MyDataset, self).__init__() # 對繼承自父類的屬性進行初始化
fh = open(txt, 'r') # 按照傳入的路徑和txt文本參數,打開這個文本,並讀取內容
imgs = []
for line in fh: # 迭代該列表#按行循環txt文本中的內
line = line.strip('\n')
line = line.rstrip('\n') # 刪除 本行string 字符串末尾的指定字符,這個方法的詳細介紹自己查詢python
words = line.split() # 用split將該行分割成列表 split的默認參數是空格,所以不傳遞任何參數時分割空格
imgs.append((words[0], int(words[1]))) # 把txt裏的內容讀入imgs列表保存,具體是words幾要看txt內容而定
# 很顯然,根據我剛纔截圖所示txt的內容,words[0]是圖片信息,words[1]是lable
self.imgs = imgs
self.transform = transform
self.target_transform = target_transform
self.loader = loader
def __getitem__(self, index): # 這個方法是必須要有的,用於按照索引讀取每個元素的具體內容
fn, label = self.imgs[index] # fn是圖片path #fn和label分別獲得imgs[index]也即是剛纔每行中word[0]和word[1]的信息
img = self.loader(fn) # 按照路徑讀取圖片
if self.transform is not None:
img = self.transform(img) # 數據標籤轉換爲Tensor
return img, label # return回哪些內容,那麼我們在訓練時循環讀取每個batch時,就能獲得哪些內容
def __len__(self): # 這個函數也必須要寫,它返回的是數據集的長度,也就是多少張圖片,要和loader的長度作區分
return len(self.imgs)
大部分的代碼及註釋來自網絡,我再找一找加上引用。(大神們請原諒)
# 數據集加載方式設置
train_data = MyDataset(txt=root1 + 'list.txt', transform=train_transforms)
test_data = MyDataset(txt=root2 + 'list.txt', transform=text_transforms)
# 然後就是調用DataLoader和剛剛創建的數據集,來創建dataloader,這裏提一句,每次加載loader的長度是有多少個batch,所以和batch_size有關
train_loader = DataLoader(dataset=train_data, batch_size=Batch_Size, shuffle=True, num_workers=0,drop_last=False)
test_loader = DataLoader(dataset=test_data, batch_size=Batch_Size, shuffle=True, num_workers=0,drop_last=False)
可是後來我發現,我的.txt文件的第一個與最後一個是一樣的
於是我就從新檢查我的.txt文件的製作過程
發現自己手賤非要在不該清零的地方給i清零了
for file in files:
fileType = os.path.split(file)
if fileType[1] == '.txt':
continue
name =dir + '/' + str(Pic_name[i]) + ' ' + str(label[i]) + '\n'
listText.write(name)
i=i+1
# if i==360:
# i=0
listText.close()
print('down!')
print('****************')
大功告成!如果對您有幫助請給我點個贊再走哦,我想我會經常更新我的踩坑歷程的歡迎關注!