【轉(zhuǎn)載】VOC_layer.py詳解,即Python層作為輸入

https://blog.csdn.net/Tramac/article/details/70158426


Python層作為輸入的四個(gè)必須的函數(shù):

setup(self, bottom, top)

reshape(self, bottom, top)

forward(self, bottom, top)

backward(self, bottom, top)

class VOCSegDataLayer(caffe.layer) #定義為Python層

該類的作用:獲取所需要的image對,即input image、label image,作為FCN的輸入。


①def setup(self, bottom, top)

setup()的參數(shù):voc_dir:數(shù)據(jù)的根目錄. split:train/val/test模式的選擇. mean:圖片的均值. randomize:初始化隨機(jī)數(shù)生成,作用? seed:隨機(jī)化seed,起點(diǎn),作用?

以下為該5個(gè)參數(shù)的初始化:

params = eval(self.param_str) #將字符串當(dāng)成有效的表達(dá)式來求值并返回計(jì)算結(jié)果

self.voc_dir = params['voc_dir']

self.split = params['split']

self.mean = np.array(params['mean']) #變成數(shù)組

self.random = params.get('randomize', True) #初始化self.random,默認(rèn)為True

self.seed = params.get('seed', None)

if len(top)!= 2: #判斷輸出是否為2(data和label)

? 報(bào)錯(cuò)

if len(bottom) != 0 #判斷輸入是否為0(數(shù)據(jù)層無bottom)

#load indices for images and labels(獲取image和lable的索引)

split_f = '{}/ImageSets/Segmentation/{}.txt'.format(self.voc_dir, self.split) #.format() 用{}代替%,()中的內(nèi)容按順序放入前面的{}中,txt文件中存的是圖片的索引

self.indices = open(split_f, 'r').read().splitline() #open()文件打開操作,'r'讀模式, 'w'寫模式,'a'追加, 'b'二進(jìn)制, '+'讀/寫. read()用于從文件讀取指定的字節(jié)數(shù),若未給定或?yàn)樨?fù)值則讀取所有. splitline()按照行('\r','\r\n','\n')分隔,返回一個(gè)包含各行作為元素的列表,默認(rèn)不包含換行符.

self.idx = 0

#如果不是train模式,則不需要參數(shù)self.random

if 'train' not in self.split: #not in 運(yùn)算符,如果在指定的序列中沒有找到值,返回True,否則返回False.

#如果是train模式,則需要初始化self.random.

if self.random:

? random.seed(self.seed) #seed()不能直接訪問,需要導(dǎo)入random模塊.()中的self.seed為改變隨機(jī)數(shù)生成器的種子seed.無返回值. 作用:設(shè)置生成隨機(jī)數(shù)用的起始值,調(diào)用任何其他random模塊函數(shù)之前調(diào)用這個(gè)函數(shù).

? self.idx = random.randint(0, len(self.indices)-1) #random.randint(a, b)用于生成一個(gè)指定范圍內(nèi)的整數(shù),用來打亂'txt'中文件的順序?


②def reshape(self, bottom, top): #獲取image+label對

self.data = self.load_image(self.indices[self.idx]) #self.indices前面得到的文件名列表,self.idx索引值

self.label = self.load_label(self.indices[self.idx])

#load_image()和load_label()定義的兩個(gè)數(shù)據(jù)接口函數(shù)

#reshape輸出的形狀

top[0].reshape(1, *self.data.shape) #image

top[1].reshape(1, *self.label.shape) #label


③def forward(self, bottom, top): #assign output分配輸出

top[0].data[...] = self.data #將self.data,self.label賦值到top.data?

top[1].data[...] = self.label

#選擇下一個(gè)輸入

if self.randon:

? self.idx = random.randint(0, len(self.indices)-1)

else:

? self.idx +=1 #若不是train,idx沒有隨機(jī),從0開始

? if self.idx == len(self.indices):

? ? ? self.idx = 0


④def backward(self, top, propagate_down, bottom)

pass #無反向過程

def load_image(self.idx): #調(diào)用時(shí),輸入的為indices[idx]

#獲取輸入的圖像,預(yù)處理來適配caffe:轉(zhuǎn)為float→改變通道(RGB→BGR)→減去均值→改為CxHxW

im = Image.open('{}/JPEGImage/{}.jpg'.format(self.voc_dir, idx)) #打開圖片

in_ = np.array(im, dtype = np.float32 #創(chuàng)建數(shù)組并制定數(shù)組中元素的類型

in_ = in_[:,:,::-1] #RGB-BGR?

in_ -= self.mean #減去均值

in_ = in_.transpose((2,0,1)) #改變通道順序

return in_


def load_label(self.idx) #獲取label,label為1xHxW單通道,整數(shù)數(shù)組,單通道是由loss決定的

im = Image.open('{}/SegmentationClass/{}.png'.format(self.voc_dir, idx))

label = np.array(im, dtype = np.unit8)

label = label[np.newaxis,...]

return label

#[...]代表許多產(chǎn)生一個(gè)完整的索引元組必要的分號,label本來為2維圖像,只有H,W,需要將其變?yōu)?維,即1xHxW.

---------------------

本文來自 Tramac 的CSDN 博客 ,全文地址請點(diǎn)擊:https://blog.csdn.net/Tramac/article/details/70158426?utm_source=copy

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容