首页 > 解决方案 > 从边界框到面具

问题描述

我有一个csv数据框如下:

    filename  width  height  class  xmin  ymin  xmax  ymax
0     1.jpg   2048    1251    1      706   513   743   562
1    10.jpg   1600     980    1      715   157   733   181
2    11.jpg   2828    1828    1      460  1530   482  1557
3    12.jpg   1276    1754    1      846   517   878   563
....
19   10.jpg   1600     980    1      428    83   483   145

我想为每张图片获取面具。如果每个图像只有一个框,我已经成功获得它们,但是有些图像有多个边界框(例如 10.jpg)。我怎样才能将该边界框添加到蒙版?

到目前为止,我的代码如下(如果图像有 1 行效果很好):

for idimage in annotations['filename']:
    img = cv2.imread('images/'+idimage)

    x1 = annotations[annotations['filename'] == idimage]['xmin'][0]
    y1 = annotations[annotations['filename'] == idimage]['ymin'][0]
    x2 = annotations[annotations['filename'] == idimage]['xmax'][0]
    y2 = annotations[annotations['filename'] == idimage]['ymax'][0]


    mask = np.zeros((img.shape[0],img.shape[1])).astype('uint8')
    mask[y1:y2, x1:x2] = 1



    mask = cv2.imwrite('mask/'+idimage,mask)

谢谢 !

标签: python-3.xpandasimagenumpyannotations

解决方案


实际上,这是错误的:

如果每张图片只有一个盒子,我已经成功获得它们

您的代码仅适用于第一行,因为您请求索引 0。所有其他行都失败,因为数据帧记住了它们的原始索引。

在这种情况下,groupby可以解决问题。

for fn, subdf in annotations.groupby('filename'):
    img = cv2.imread('images/'+fn)
    mask = np.zeros((img.shape[0],img.shape[1])).astype('uint8')
    for _, row in subdf.iterrows():
        mask[row['ymin']:row['ymax'], row['xmin']:row['xmax']] = 1

    cv2.imwrite('mask/'+fn, mask)

这里groupby允许迭代一系列具有相同'filename'.
然后在嵌套循环iterrows中用于迭代每个子数据帧的每一行,以提取值并构建掩码。
如您所见,外循环的每次迭代都会构建掩码,让内循环“绘制”掩码的不同矩形,子数据帧的每一行一个矩形。

编辑

内部循环的类似但稍快的解决方案,而不是iterrows

for x1, y1, x2, y2 in zip(subdf['xmin'], subdf['ymin'], subdf['xmax'], subdf['ymax']):
    mask[y1:y2, x1:x2] = 1

如果您有大量的行可能会很有用。


推荐阅读