我正在使用Tensorflow作为Keras的后端,并尝试理解如何将图像分割训练的标签引入。
我正在使用LFW Parts数据集,它既有地面真实图像,也有地面真实掩码,看起来像这个* 1500张训练图像:
按照我的理解,在训练期间,我要同时加载
- (X) 图像
- (Y) 掩码图像
以批处理的方式满足我的需求。现在我的问题是,仅仅将它们(图像和掩码图像)作为NumPy数组(N,N,3)加载是否足够,还是需要以某种方式处理/重构掩码图像。实际上,掩码/标签表示为[R,G,B]像素,其中:
- [255, 0, 0] 头发
- [0, 255, 0] 脸部
- [0, 0, 255] 背景
我可以像这样对其进行归一化为0-1,但我不知道是否应该:
im = Image.open(path)
label = np.array(im, dtype=np.uint8)
label = np.multiply(label, 1.0/255)
所以我最终得到:
- [1, 0, 0] 发型
- [0, 1, 0] 脸部
- [0, 0, 1] 背景
在网上找到的所有内容都使用tensorflow或keras中的现有数据集。如果您拥有可能被认为是自定义数据集的数据,那么没有什么是真正清楚的。
我发现与Caffe有关:https://groups.google.com/forum/#!topic/caffe-users/9qNggEa8EaQ
他们提倡将掩码图像转换为(H,W,1)
(HWC)?其中我的类分别为背景、发型和脸部,其值为0,1,2
。
可能这是一个重复的问题(类似问题/答案的组合):
Tensorflow:如何创建Pascal VOC风格的图像
我找到了一个处理PascalVOC的例子,将其转换为(N, N, 1):
LFW_PARTS_PALETTE = {
(0, 0, 255) : 0 , # background (blue)
(255, 0, 0) : 1 , # hair (red)
(0, 0, 255) : 2 , # face (green)
}
def convert_from_color_segmentation(arr_3d):
arr_2d = np.zeros((arr_3d.shape[0], arr_3d.shape[1]), dtype=np.uint8)
palette = LFW_PARTS_PALETTE
for i in range(0, arr_3d.shape[0]):
for j in range(0, arr_3d.shape[1]):
key = (arr_3d[i, j, 0], arr_3d[i, j, 1], arr_3d[i, j, 2])
arr_2d[i, j] = palette.get(key, 0) # default value if key was not found is 0
return arr_2d
我认为这可能接近我想要的,但不完全符合。我认为需要它是(N,N,3),因为我有3个类别?上面版本还有另一个来源于这两个位置:
https://github.com/martinkersner/train-CRF-RNN/blob/master/utils.py#L50
https://github.com/DrSleep/tensorflow-deeplab-resnet/blob/ce75c97fc1337a676e32214ba74865e55adc362c/deeplab_resnet/utils.py#L41 (此链接对值进行one-hot编码)