這段時間在看DeepLab的源碼。看到標籤處理和損失函數的時候確實覺得智商不夠用了。
整個代碼的思路就是,先讀取圖像和標籤製作tfrecord,其中標籤是單通道的,一個灰度值對應一種類別。
image_reader = build_data.ImageReader('jpeg', channels=3)
label_reader = build_data.ImageReader('png', channels=1)
def __init__(self, image_format='jpeg', channels=3):
"""Class constructor.
Args:
image_format: Image format. Only 'jpeg', 'jpg', or 'png' are supported.
channels: Image channels.
"""
with tf.Graph().as_default():
self._decode_data = tf.placeholder(dtype=tf.string)
self._image_format = image_format
self._session = tf.Session()
if self._image_format in ('jpeg', 'jpg'):
self._decode = tf.image.decode_jpeg(self._decode_data,
channels=channels)
elif self._image_format == 'png':
self._decode = tf.image.decode_png(self._decode_data,
channels=channels)
然後我把VOC數據集中的標籤拉出來看,嗯,彩色的,沒毛病,這裏tensorflow裏面解析圖片的時候,設定channel就能把彩色圖盤轉成灰度嗎?當時就很疑惑,然後接着往下看。當然是後來才注意到,人家讀的標籤圖片是在這樣一個文件夾下:
而我們下載的VOC數據集裏面是沒有這個文件夾的,但是當時我瞎沒看到,但是也繼續往下看代碼了。
中間網絡結構部分至今還不太明白,我帶着疑惑直接跳到了損失函數的地方。
沒毛病,就是先算出Logits,然後再計算交叉熵。然後這裏根據類別數計算了label的one-hot編碼了。接下來我就十分不解了,灰度範圍是[0,255],這裏的類別數加上背景才21種,這怎麼搞也不行嘛。。我想標籤數據一定是預處理了,然後倒回去看製作數據和數據讀取,都沒看到預處理的影子。
根據經驗又檢查了一遍datasets文件夾中的.py文件,發現有一個文件叫remove_gt_colormap,進去一看,哦,人家這個就是直接把彩色圖像轉換爲標籤圖的代碼,我打我自己。。。
但是看這個處理流程是這個亞子的:
直接用PIL讀一遍然後再保存就完事了???
網上找資料發現有人和我一樣懵逼。看他的答案:Tensorflow Deeplab image colormap removal confusion
好吧說實話做了很久的圖像處理,但是圖像格式相關的知識在腦子裏是一團亂麻。。。
但是這裏只是給出了這種數據標籤的轉換方式,那麼我們自己製作的標籤要怎麼轉換呢?除了用標記軟件,那用ps也是很方便的,這裏自己寫了一段轉換的代碼:
def remove_color_map():
files_label = os.listdir(Config.train_label_path)
for file in files_label:
img = cv2.imread(os.path.join(Config.train_label_path, file))
size = img.shape
new_label = np.zeros((size[0],size[1]), dtype=np.uint8)
color_map = np.array(Config.color_map)
for i in range(len(color_map)):
bi = (cv2.inRange(img, color_map[i], color_map[i]) / 255) * i
new_label = new_label + bi
cv2.imwrite(os.path.join(Config.train_label_raw_path,file), new_label)
其中,color_map就是標記顏色的list,比如:
color_map = [[0,0,0],[255,0,0],[0,255,0]]
背景也是要手動加上去的。
以上~~~