根据位置从两张图像中标记对象

时间:2020-08-19 19:39:43

标签: python opencv image-segmentation

我正在尝试根据对象在2张或更多图片中的位置来标记对象。 基本算法理论上应该很简单:

  • 从img_a中选择项目
  • 检查它是否与img_b中的任何对象重叠
    • 检查它是否仅与img_b中的一个对象重叠
      • 如果是,则两个标签具有相同的标签
    • 否则:检查最大的重叠并相应地分配标签

下面的图像有助于可视化该问题,其中左侧的图像将是img_b的分割图,右侧的图像将是img_a的分割目标(来自img_b的红色标记仅供参考,不应该属于结果)。

Labelling goal example

这些图像与我使用的图像不完全相同,但是非常相似。对象具有不规则的形状(例如,中间图像上的红色对象/组),尺寸变化很大,并且沿图像不规则地分布。当我应用如下所示的解决方案时,即使img_b是img_a与另一个图像的并集,我仍会在目标seg_map中注意到许多丢失的对象,好像没有找到重叠。

直到现在,我一直在尝试通过使用bbox和图像的分割图生成数据框(通过cv.connectedComponentWithStats())。然后,我尝试通过测试是否有任何边界框重叠来匹配对象,如果是,我将新标签设置为df中的列。下一步是仅基于“新”标签值映射seg_map中的值。

进行测试:img_a img_b

def create_table_from_bin(bin_img):
    connectivity = 8

    nb_components, seg_map, stats, centroids =  cv.connectedComponentsWithStats(bin_img, connectivity,  cv.CV_32S)

    spots_df = pd.DataFrame(stats)
    spots_df.columns = ['x', 'y', 'w', 'h', 'Area']
    spots_df['centroids_x'] = centroids[:, 0]
    spots_df['centroids_y'] = centroids[:, 1]
    
    for i in range(nb_components):
        if spots_df['Area'].loc[i] < 50:
            seg_map[seg_map==i] = 0
            spots_df = spots_df.drop(i)

    spots_df = spots_df.drop(0)

    return spots_df, seg_map
def overlap(bbox1, bbox2):
    #for x axis 
    if (bbox1.x < bbox2.x < (bbox1.x + bbox1.w)) or (bbox1.x < (bbox2.x + bbox2.w)< (bbox1.x + bbox1.w)):
        if (bbox1.y < bbox2.y < (bbox1.y + bbox1.h)) or (bbox1.y < (bbox2.y + bbox2.h)< (bbox1.y + bbox1.h)):
            return True
    return False

def match_tables(df_a, df_b):
 
    
    match_table = df_b.copy()
    
    df0 = df_a.copy()
    df1 = df_b.copy()
    
    match_table['label'] = None
    
    
    for i in tqdm(df1.index):
        for o in df0.index:
            if match_table['label'].loc[o]==None:
                if overlap(df1.loc[i], df0.loc[o]):
                    match_table['label'].loc[o] = i



    return match_table

0 个答案:

没有答案