На самом деле, это неправильно:
Мне удалось получить их, если для каждого изображения есть только одна коробка
Ваш код работает только для первой строки, потому что вы запрашиваете индекс 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
используется для итерации по каждой строке каждого подкадра с целью извлечения значения и построения маски.
Как видите, маска строится на каждой итерации внешнего цикла, оставляя внутренний цикл для «рисования» различных прямоугольников маски, по одному прямоугольнику для каждой строки подкадра.
EDIT
Аналогичное, но немного более быстрое решение для внутреннего цикла вместо iterrows
:
for x1, y1, x2, y2 in zip(subdf['xmin'], subdf['ymin'], subdf['xmax'], subdf['ymax']):
mask[y1:y2, x1:x2] = 1
Если у вас большое количество строк, может быть полезно.