从装订盒到口罩

时间:2019-05-28 08:10:49

标签: python-3.x pandas image numpy annotations

我有一个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)

谢谢!

1 个答案:

答案 0 :(得分:1)

实际上,这是错误的:

  

如果每张图像只有一个盒子,我就成功获得了它们

您的代码仅适用于第一行,因为您请求索引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

如果您有很多行可能会有用。