我有一个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)
谢谢!
答案 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
如果您有很多行可能会有用。