边界框的语义分割

时间:2018-11-18 11:42:10

标签: python numpy machine-learning computer-vision

假设您正在执行语义分割。为简单起见,我们假设这是1D分割而不是2D分割(即我们只关心查找具有宽度的对象)。

所以我们模型的期望输出可能是这样的:

[
    [0, 0, 0, 0, 1, 1, 1], # label channel 1 
    [1, 1, 1, 0, 0, 1, 1], # label channel 2 
    [0, 0, 0, 1, 1, 1, 0], # label channel 3
    #...
]

但是,我们训练有素的不完美模型可能更像

[
    [0.1,  0.1,  0.1,  0.4,  0.91, 0.81, 0.84], # label channel 1 
    [0.81, 0.79, 0.85, 0.1,  0.2,  0.61, 0.91], # label channel 2 
    [0.3,  0.1,  0.24, 0.87, 0.62, 1,    0   ], # label channel 3
    #...
]

使用python获取标签(或边界框)边界的有效方式是什么

例如(零索引)

[
    [[4, 6]],        # "objects" of label 1
    [[0, 2], [5, 6]] # "objects" of label 2
    [[3, 5]],        # "objects" of label 3
]

如果有帮助,也许将其转换为二进制掩码会更有用?

def binarize(arr, cutoff=0.5):
  return (arr > cutoff).astype(int)

使用二进制掩码,我们只需要查找非零值索引的连续整数:

def连续(数据,步骤大小= 1):     返回np.split(data,np.where(np.diff(data)!=步骤大小)[0] +1)

找到标签“运行”:

def binary_boundaries(labels, cutoff=0.5):  
  return [consecutive(channel.nonzero()[0]) for channel in binarize(labels, cutoff)]

根据频道名称命名对象:

def binary_objects(labels, cutoff=0.5, channel_names=None):
  if channel_names == None: 
    channel_names = ['channel {}'.format(i) for i in range(labels.shape[0])]

  return dict(zip(channel_names, binary_boundaries(labels, cutoff)))

1 个答案:

答案 0 :(得分:0)

您训练有素的模型返回的是您要查找的float image,而不是int image(如果小数困扰着您,这并不是“不完美”),是的!您确实需要threshold才能获得binary image

一旦有了二进制映像,就让skimage做一些工作。

label_mask = measure.label(mask)
props = measure.regionprops(label_mask)

遮罩是您的二进制图像,在这里,您确实拥有props实际上被检测到的所有区域的属性。

在这些属性中,存在边界框!