分類問題:

對於分類問題,raw為影象,label為數字,在這個例子中我的資料格式為:

共有12類,每個類有他自己的資料夾,也就是共12個資料夾,這十二個資料夾又都在image_set資料夾下,如圖:

針對(影象)分割與分類問題的tfrecord使用方法

大致思路為:獲取每個圖片的路徑及其label——>在for迴圈中開啟每個圖片並存儲進tfrecord中——>decode

第一部分

:獲取每個圖片的路徑及其對應的label:

def

get_file

file_dir

):

images

=

[]

temp

=

[]

labels

=

[]

i

=

0

for

root

dirs

files

in

os

walk

file_dir

):

for

name

in

files

images

append

os

path

join

root

name

))

#將路徑新增到images中 第一個E:\Lucas_up\Alexnet\image_set\ant

for

name

in

dirs

temp

append

os

path

join

root

name

))

#比image更下一層 第一個E:\Lucas_up\Alexnet\image_set\ant\image_0001。jpg

for

one_floder

in

temp

n_img

=

len

os

listdir

one_floder

))

#每一個類的圖片有多少張

labels

=

np

append

labels

n_img

*

i

])

#建立標籤矩陣:每一種圖片的數量n_img乘以矩陣[i]append到後面

i

=

i

+

1

temp

=

np

array

([

images

labels

])

#temp。shape = (2,711)

temp

=

temp

transpose

()

#轉置

np

random

shuffle

temp

#隨機,是真的可以隨機。。。

image_list

=

list

temp

[:,

0

])

#路徑

label_list

=

list

temp

[:,

1

])

#現在是一個list而不是矩陣#2。0 numpy。str

label_list

=

int

float

n

))

for

n

in

label_list

return

image_list

label_list

輸入為image_set的資料夾路徑,輸出為每張照片的路徑及其對應label:

data_dir = ‘E:\\Lucas_up\\Alexnet\\image_set’

image_dir,label = get_file(data_dir)

print(image_dir)

print(label)

如圖:

針對(影象)分割與分類問題的tfrecord使用方法

iamge_dir

針對(影象)分割與分類問題的tfrecord使用方法

label

第二部分

:生成tfrecord檔案

程式碼如下

def convert_to_tfrecord(images,labels,save_dir,name):

filename = os。path。join(save_dir,name + ‘。tfrecord’)

n_samples = len(labels)

if np。shape(images)[0] != n_samples:

raise ValueError(‘Image size %d does not match label size %d。’%(images。shape,n_samples。shape))

writer = tf。python_io。TFRecordWriter(filename)

print(‘\nTransform start。。。。’)

for i in np。arange(n_samples):

try:

image = Image。open(images[i])

image = image。resize((227,227))

image = np。array(image)

if image。shape != (227,227,3):

print(images[i])

print(labels[i])

#os。remove(images[i]) # 去除掉所有的非rgb圖

image_raw = image。tostring()

label = int(labels[i])

example = tf。train。Example(features = tf。train。Features(

feature = {“label”:tf。train。Feature(int64_list = tf。train。Int64List(value = [label])),

“img_raw”:tf。train。Feature(bytes_list = tf。train。BytesList(value = [image_raw]))}

))

writer。write(example。SerializeToString())

except IOError as e:

print(‘Could not read:’,images[i])

print(‘error : %s’ %e)

print(‘Skip it! \n’)

writer。close()

print(“Transform done!”)

這裡用Image。open讀取影象,需要 將其轉化成numpy陣列再轉為string最後寫入tfrecord,這個過程很麻煩而且生成的tfrecord檔案會很大,在下面分割問題中tfrecord的使用時會介紹一種新的方法。

第三部分

:讀取tfrecord檔案

程式碼如下:

def read_and_decode(tfrecords_file,batch_size):

filename_queue = tf。train。string_input_producer([tfrecords_file])

reader = tf。TFRecordReader()

_,serialized_example = reader。read(filename_queue)

img_features = tf。parse_single_example(serialized_example,

features={

‘label’:tf。FixedLenFeature([],tf。int64),

‘img_raw’:tf。FixedLenFeature([],tf。string),

})

image = tf。decode_raw(img_features[‘img_raw’],tf。uint8)

image = tf。reshape(image,[227,227,3])

image = tf。cast(image, tf。float32) * (1。 / 255) #在流中丟擲img張量

label = tf。cast(img_features[‘label’],tf。int32)

image_batch,label_batch = tf。train。batch([image,label],

batch_size=batch_size,

num_threads = 2,

capacity=32)

label_batch = tf。reshape(label_batch,[batch_size])

print(“Read tfrecord doc done!”)

return image_batch,label_batch

得到的image_batch,label_batch可以直接拿去用

測試:

這裡提供展示的程式碼:

BATCH_SIZE = 20

def plot_images(images,labels):

for i in np。arange(0,BATCH_SIZE):

plt。subplot(4,5,i + 1)

plt。axis(‘off’)

plt。title(labels[i],fontsize = 14)

plt。subplots_adjust(top = 1。5)

plt。imshow(images[i])

plt。show()

log_dir = ‘E:\\Lucas_up\\Alexnet\\tfrecord\\test。tfrecord’

image_batch,label_batch = read_and_decode(log_dir,BATCH_SIZE)

x = image_batch

in_channels = x。get_shape()[-1]

with tf。Session() as sess:

i = 0

coord = tf。train。Coordinator()

threads = tf。train。start_queue_runners(coord = coord)

try:

while not coord。should_stop() and i<1:

#just plot one batch size

image,label = sess。run([image_batch,label_batch])

#print(label。shape)

plot_images(image,label)

i = i+1

except tf。errors。OutOfRangeError:

print(‘done!’)

finally:

coord。request_stop()

coord。join(threads)

結果 如圖:

針對(影象)分割與分類問題的tfrecord使用方法

show

分割問題:

我做的是對於肝臟的分割,資料集是這樣的:

在bmp肝圖檔案中存放的是raw,在白色mask中存放的是label,與分類問題不同,分割問題的label是影象並非數字,同樣也分三個部分。

第一部分

:獲取每張影象的路徑,程式碼如下

def gen_road(raw_dir,target_dir):

raw = []

for root,dirs,files in os。walk(raw_dir):

for name in files:

raw。append(os。path。join(root,name))#將路徑新增到images中 第一個E:\Lucas_up\Alexnet\image_set\ant

target = []

for root,dirs,files in os。walk(target_dir):

for name in files:

target。append(os。path。join(root,name))

return raw,target

raw,target = gen_road(raw_dir,target_dir)

第二部分

:讀取每張圖片並寫入tfrecord,程式碼如下(未封裝):

def _bytes_feature(value,TFRECORD_PATH):

return tf。train。Feature(bytes_list=tf。train。BytesList(value=[value]))

writer = tf。python_io。TFRecordWriter(TFRECORD_PATH)

n_samples = len(raw)

print(n_samples)

for i in np。arange(n_samples):

img = tf。gfile。FastGFile(raw[i], ‘rb’)。read()

label = tf。gfile。FastGFile(target[i], ‘rb’)。read()

example = tf。train。Example(features=tf。train。Features(feature={

‘raw_image’: _bytes_feature(img,TFRECORD_PATH),

‘label’: _bytes_feature(label,TFRECORD_PATH)

}))

# 最後將example寫入TFRecord檔案

writer。write(example。SerializeToString())

writer。close()

在這裡,直接用tf。gfile。FastGFile讀取圖片,生成的record檔案相較於上一種方法要小。

第三部分

:讀取tfrecord檔案

def decode_and_gen_batch(BATCH_SIZE,TFRECORD_PATH):

# 1。 把所有的TFRecord檔名列表寫入佇列中(只有一個就寫一個檔名在列表中,多個就寫多個)

queue = tf。train。string_input_producer([TFRECORD_PATH], shuffle=True)

# 2。 建立一個讀取器

reader = tf。TFRecordReader()

# 3。 將佇列中的tfrecord檔案讀取為example格式

_, serialized_example = reader。read(queue)

# 4。 根據定義資料的方式對應說明讀取的方式

features = tf。parse_single_example(serialized_example,

features={

‘raw_image’: tf。FixedLenFeature([], tf。string),

‘label’: tf。FixedLenFeature([], tf。string)

})

img = features[‘raw_image’]

label = features[‘label’]

# 5。 對圖片進行解碼

img = tf。image。decode_bmp(img, channels=3)

label = tf。image。decode_bmp(label, channels=3)

img = tf。reshape(img,[512,512,3])

label = tf。reshape(label,[512,512,3])

# 然後就可以用tf。train。batch方法來生成一個batch的image和label啦

image_batch,label_batch = tf。train。batch([img,label],

batch_size=50,

num_threads = 2,

capacity=32)

return image_batch,label_batch

因為我的所有影象都是bmp格式的,所以用tf。image。decode_bmp解碼,解碼之後千萬要reshape[512,512,3],不然會報錯:

All shapes must be fully defined: [TensorShape([Dimension(None), Dimension(None), Dimension(3)]), TensorShape([Dimension(None), Dimension(None), Dimension(3)])]

測試

image_batch,label_batch = decode_and_gen_batch(BATCH_SIZE,TFRECORD_PATH)

with tf。Session() as sess:

i = 0

coord = tf。train。Coordinator()

threads = tf。train。start_queue_runners(coord = coord)

image,label = sess。run([image_batch,label_batch])

plt。figure(1)

plt。imshow(image[25])

plt。figure(2)

plt。imshow(label[25])

結果如圖:

針對(影象)分割與分類問題的tfrecord使用方法

以上就是tfrecord在分類與分割問題中的使用方法。

參考: