Привет, Детектрон,
Недавно я попытался добавить свои собственные данные кокоса для запуска Detectron и столкнулся со следующими проблемами.
(1) «сегментация» в данных о кокосе, как показано ниже ,
{"сегментация": [[ 499.71, 397.28, ...... 342.71, 172.31 ]] , "область": 43466.12825, "iscrowd": 0, "image_id": 182155, "bbox": [338.89, 51.69, 205.82, 367.61], "category_id": 1, "id": 1248258},
{"segmentation": {"counts": [66916, 6, 587, ..... 1, 114303], "size": [594, 640] }, "area": 6197, "iscrowd": 1, «image_id»: 284445, «bbox»: [112, 322, 335, 94], «category_id»: 1, «id»: 9.001002844e + 11},
Первый формат «сегментации» - многоугольник, а второй нужен для кодирования / декодирования для формата RLE.
Вышеуказанные форматы могут работать на Detectron.
(2) Я добавил новую категорию и сгенерировал новый формат RLE для поля «сегментация» с помощью маски кодирования () / декодирования () coco api.
Я сгенерировал такие данные.
"сегментация": [{ "рассчитывает ": "MNG = 1fb02O1O1O001N2O001O1O0O2O1O1O001N2O001O1O0O2O1O001O1O1O010000O01000O010000O01000O01000O01000O01N2N2M2O2N2N1O2N2O001O10O B000O10O1O001 ^ OQ ^ O9Pb0EQ ^ О; Wb0OO01O1O1O001O1N2N`jT3?"," размер": [600,1000]}]
Я обнаружил, что выделенные жирным шрифтом символы отличаются от исходного json-формата "сегментации" coco, хотя он может работать в реализации MatterPort для Mask-RCNN.
Кроме того, я попытался изменить некоторый код Detectron в соответствии с моими требованиями, но для меня это было очень сложно, потому что нужно изменить много кода.
Не могли бы вы дать мне несколько советов по использованию моих пользовательских данных?
Спасибо.
У меня была аналогичная проблема: некоторые функции в lib / utils / segms.py ожидают, что сегментирование будет в формате «поли», и прерываются, когда они предоставляются в RLE.
Это неудобно, но, похоже, соответствует спецификации для малонаселенных регионов (iscrowd = 0):
Формат сегментации зависит от того, представляет ли экземпляр отдельный объект (iscrowd = 0, в этом случае используются многоугольники) или коллекцию объектов (iscrowd = 1, в этом случае используется RLE).
[1] http://cocodataset.org/#download , раздел «4.1. Аннотации экземпляров объекта»
Для меня обходным путем было преобразование в формат «поли», который по сути представляет собой список вершин (x, y).
-Леша.
2 февраля 2018 г. в 06:41 Ху Сингуи [email protected] написал:
Привет, Детектрон,
Недавно я попытался добавить свои собственные данные кокоса для запуска Detectron и столкнулся со следующими проблемами.
(1) «сегментация» в данных о кокосе, как показано ниже ,{"сегментация": [[499.71, 397.28, ...... 342.71, 172.31]], "область": 43466.12825, "iscrowd": 0, "image_id": 182155, "bbox": [338.89, 51.69, 205.82, 367.61], "category_id": 1, "id": 1248258},
{"segmentation": {"counts": [66916, 6, 587, ..... 1, 114303], "size": [594, 640]}, "area": 6197, "iscrowd": 1, «image_id»: 284445, «bbox»: [112, 322, 335, 94], «category_id»: 1, «id»: 9.001002844e + 11},
Первый формат «сегментации» - многоугольник, а второй нужен для кодирования / декодирования для формата RLE.Вышеуказанные форматы могут работать на Detectron.
(2) Я добавил новую категорию и сгенерировал новый формат RLE для поля «сегментация» с помощью маски кодирования () / декодирования () coco api.
Я сгенерировал такие данные."Сегментация": [{ "рассчитывает": "MNG = 1fb02O1O1O001N2O001O1O0O2O1O1O001N2O001O1O0O2O1O001O1O1O010000O01000O010000O01000O01000O01000O01N2N2M2O2N2N1O2N2O001O10O B000O10O1O001 ^ OQ ^ O9Pb0EQ ^ О; Wb0OO01O1O1O001O1N2N`jT3?", "Размер": [600,1000]}]
Я обнаружил, что выделенные жирным шрифтом символы отличаются от исходного json-формата "сегментации" coco, хотя он может работать в реализации MatterPort для Mask-RCNN.
Кроме того, я попытался изменить некоторый код Detectron в соответствии с моими требованиями, но для меня это было очень сложно, потому что нужно изменить много кода.
Не могли бы вы дать мне несколько советов по использованию моих пользовательских данных?
Спасибо.
-
Вы получаете это, потому что подписаны на эту ветку.
Ответьте на это письмо напрямую, просмотрите его на GitHub или отключите чат.
@amokeev , как конвертировать "RLE" в "poly" формат по вашему обходному пути?
@amokeev , Вы уверены, что количество в сегментации (x, y) вершин? Например «66916», большое количество! Другой, хотя я установил "iscrowd" как "1" для формата RLE, все же не смог работать на Detectron.
Я интерпретирую поли как список многоугольников, определенных вершинами, например [[x1, y1, x2, y2… xN, yN],… [x1, y1, x2, y2… xN, yN]], где координаты тот же масштаб, что и изображение.
Маски, закодированные таким образом, правильно отображаются в CocoAPI [1]
Но вы можете получить «официальный» ответ.
[1] https://github.com/cocodataset/cocoapi https://github.com/cocodataset/cocoapi
2 февраля 2018 г. в 09:18 Ху Сингуи [email protected] написал:
@amokeev https://github.com/amokeev , вы уверены, что число в сегментации составляет (x, y) вершин? Например «66916», большое количество! Другой, хотя я установил "iscrowd" как "1" для формата RLE, все же не смог работать на Detectron.
-
Вы получаете это, потому что вас упомянули.
Ответьте на это письмо напрямую, просмотрите его на GitHub https://github.com/facebookresearch/Detectron/issues/100#issuecomment-362516928 или отключите поток https://github.com/notifications/unsubscribe-auth/AFlh63ObnXg- DcaDKwIi3pB4Ppig464Hks5tQsTkgaJpZM4R2tN3 .
@topcomma
Может быть, вы можете попробовать преобразовать маску в полигоны.
labels_info = []
for mask in mask_list:
# opencv 3.2
mask_new, contours, hierarchy = cv2.findContours((mask).astype(np.uint8), cv2.RETR_TREE,
cv2.CHAIN_APPROX_SIMPLE)
# before opencv 3.2
# contours, hierarchy = cv2.findContours((mask).astype(np.uint8), cv2.RETR_TREE,
# cv2.CHAIN_APPROX_SIMPLE)
segmentation = []
for contour in contours:
contour = contour.flatten().tolist()
# segmentation.append(contour)
if len(contour) > 4:
segmentation.append(contour)
if len(segmentation) == 0:
continue
# get area, bbox, category_id and so on
labels_info.append(
{
"segmentation": segmentation, # poly
"area": area, # segmentation area
"iscrowd": 0,
"image_id": index,
"bbox": [x1, y1, bbox_w, bbox_h],
"category_id": category_id,
"id": label_id
},
)
@amokeev ,
@Sundrops
Спасибо за ваши предложения.
Попытаюсь.
@Sundrops , как ваш способ конвертировать, может получить результат "поли" списка. Большое спасибо! Но я все еще не знаю, почему координата в файле COCO json имеет большое / маленькое число, например «66916» или «1»?
Аннотации @topcomma COCO имеют два типа аннотаций сегментации
Многоугольник и несжатый RLE будут преобразованы в компактный формат RLE с помощью MaskApi.
Компактный формат RLE:
Сегментация ": [{" рассчитывает ": "MNG = 1fb02O1O1O001N2O001O1O0O2O1O1O001N2O001O1O0O2O1O001O1O1O010000O01000O010000O01000O01000O01000O01N2N2M2O2N2N1O2N2O001O10O B000O10O1O001 ^ OQ ^ O9Pb0EQ ^ О; Wb0OO01O1O1O001O1N2N`jT3"," размер ": [600,1000]}]
@Sundrops ,
Спасибо за вашу огромную помощь.
Мои пользовательские кокосовые данные теперь можно обучить на Detectron.
@topcomma ,
У меня такая же проблема, как и у тебя.
Как метод Sundrops, я не могу найти файл для преобразования маски в полигоны.
Не могли бы вы сказать мне, какой файл? Большое спасибо!
@ lg12170226 ,
Вы можете сослаться на код python coco stuff (https://github.com/nightrome/cocostuff), чтобы реализовать его самостоятельно.
В кодовой базе нет файла соответствующей аннотации.
@topcomma : у меня есть необработанное изображение и изображения N
. Каждая метка хранится в одном файле, поэтому у меня есть N
image для метки. Я хочу обучить Mask RCNN в моем собственном наборе данных, поэтому сначала мне нужно преобразовать в формат COCO. Не могли бы вы поделиться кодом, как преобразовать его в стиль COCO? Спасибо
Просто интересно, есть ли способ конвертировать сжатые RLE в polys / несжатые RLE?
@realwecan после декодирования RLE с помощью pycocotools.mask.decode, вы можете проверить мою реализацию для генерации полигонов с помощью opencv:
@hazirbas : спасибо за ваш код. Почему бы не использовать Davis 2017, который содержит сегментирование экземпляров? Можем ли мы использовать ваш код для преобразования Davis 2017 в формат coco, чтобы использовать эту реализацию maskrcnn?
@ John1231983 вам необходимо соответствующим образом изменить скрипт для чтения разделенных файлов, а также файла db_info.yml. Для моих собственных исследований он мне понадобился для DAVIS 2016.
Другое решение для создания многоугольников, но с использованием skimage
вместо opencv
.
import json
import numpy as np
from pycocotools import mask
from skimage import measure
ground_truth_binary_mask = np.array([[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
[ 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
[ 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
[ 0, 0, 0, 0, 0, 1, 1, 1, 0, 0],
[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]], dtype=np.uint8)
fortran_ground_truth_binary_mask = np.asfortranarray(ground_truth_binary_mask)
encoded_ground_truth = mask.encode(fortran_ground_truth_binary_mask)
ground_truth_area = mask.area(encoded_ground_truth)
ground_truth_bounding_box = mask.toBbox(encoded_ground_truth)
contours = measure.find_contours(ground_truth_binary_mask, 0.5)
annotation = {
"segmentation": [],
"area": ground_truth_area.tolist(),
"iscrowd": 0,
"image_id": 123,
"bbox": ground_truth_bounding_box.tolist(),
"category_id": 1,
"id": 1
}
for contour in contours:
contour = np.flip(contour, axis=1)
segmentation = contour.ravel().tolist()
annotation["segmentation"].append(segmentation)
print(json.dumps(annotation, indent=4))
как бы вы преобразовали двоичную маску или закодированный RLE в несжатый RLE для использования в поле «iscrowd: 1» «counts»?
@waspinator Сегментация вашего кода с использованием skimage отличается от кода @Sundrops, использующего cv2.
Правильны ли оба этих результата и могут ли оба эти результата использоваться Detectron? Пожалуйста, дайте мне совет, спасибо. @waspinator @Sundrops
Результаты с использованием вашего кода с skimage:
{"сегментация": [[0,0, 252.00196078431372, 1.0, 252.00196078431372, 2.0, 252.00196078431372, 3.0, 252.00196078431372, 4.0, 252.00196078431372, 5.0, 252.00196078431372, 6.0, 252.0019607843132.0043, 252.00196078431372, 6.0, 252.001960784313260.00, 252.0013232880.0043, 252.00196078431372.0043.0, 252.00196078431372.004.0, 252.001960784313260.0043, 7.0192.00196078431372.00 , 11.0, +252,00196078431372, 12,0, +252,00196078431372, 13,0, +252,00196078431372, 14,0, +252,00196078431372, 15,0, +252,00196078431372, 16,0, +252,00196078431372, 17,0, +252,00196078431372, 18,0, +252,00196078431372, 19,0, +252,00196078431372, 20,0, +252,00196078431372, 21,0, +252,00196078431372, 22,0, +252,00196078431372, 23,0 , +252,00196078431372, 24,0, +252,00196078431372, 25,0, +252,00196078431372, 26,0, +252,00196078431372, 27,0, +252,00196078431372, 28,0, +252,00196078431372, 29,0, +252,00196078431372, 30,0, +252,00196078431372, 31,0, +252,00196078431372, 32,0, +252,00196078431372, 33,0, +252,00196078431372, 34.0, +252,00196078431372, 35,0, +252,00196078431372 , 36.0, 252.00196078431372, 37.0, 252.00196078431372, 38. 0, +252,00196078431372, 39,0, +252,00196078431372, 40.0, +252,00196078431372, 41,0, +252,00196078431372, 42,0, +252,00196078431372, 43,0, +252,00196078431372, 44,0, +252,00196078431372, 45,0, +252,00196078431372, 46,0, +252,00196078431372, 47,0, +252,00196078431372, 48.0, +252,00196078431372, 49.0, +252,00196078431372, 50,0, +252,00196078431372, 51,0, +252,00196078431372, 52,0, +252,00196078431372, 53,0, +252,00196078431372, 54,0, +252,00196078431372, 55,0, +252,00196078431372, 56,0, +252,00196078431372, 57,0, +252,00196078431372, 58,0, +252,00196078431372, 59,0, +252,00196078431372, 60,0, +252,00196078431372, 61.0, +252,00196078431372, 62.0, +252,00196078431372, 63,0, +252,00196078431372, 64,0, +252,00196078431372, 65.0, +252,00196078431372, 66,0, +252,00196078431372, 67,0, +252,00196078431372, 68.0, +252,00196078431372, 69,0, +252,00196078431372, 70,0, +252,00196078431372, 71,0, +252,00196078431372, 72,0, +252,00196078431372, 73,0, +252,00196078431372, 74.0, +252,00196078431372, 75,0, 252.00196078431372, 76.0, 252.00196 078431372, 77,0, +252,00196078431372, 78,0, +252,00196078431372, 79.0, +252,00196078431372, 80,0, +252,00196078431372, 81,0, +252,00196078431372, 82.0, +252,00196078431372, 83,0, +252,00196078431372, 84,0, +252,00196078431372, 85.0, +252,00196078431372, 86,0, +252,00196078431372, 87,0, +252,00196078431372, 88.0, +252,00196078431372, 89.0, 252.00196078431372, 90.0, 252.00196078431372, 91.0, 252.00196078431372, 92.0, 252.00196078431372, 93.0, 252.00196078431372, 93.00196078431372, 252.0, 94.0, 251.00196078431372, 9560,0 ...
Результаты с @Sundrops код с использованием CV2:
[94, 252, 93, 253, 0, 253, 0, 286, 188, 286, 188, 269, 187, 268, 187, 252]
@Kongsea Я не тестировал реализацию @Sundrops cv2, но основная идея должна быть такой же. Они будут давать разные результаты, поскольку существует бесконечное количество наборов точек, которые вы можете использовать для описания формы. Но в остальном они оба должны работать. У меня просто не было установленного cv2, поэтому я написал кое-что, что этого не требует.
@Kongsea @waspinator Я проверил свой код. Оно работает.
Спасибо @Sundrops @waspinator .
Я попробую.
@waspinator Есть ли способ преобразовать
@Sundrops Почему вы прокомментировали эту часть кода?
# if len(contour) > 4:
# segmentation.append(contour)
# if len(segmentation) == 0:
# continue
Нам действительно нужно разобраться с таким делом, верно?
@ Yuliang-Zou Вы должны раскомментировать эту часть, когда контуры используются для Detectron. Beacase детектор будет рассматривать его как прямоугольник, когда len (contour) == 4. Я обновил свой предыдущий код.
@Sundrops Спасибо. Но нам все еще нужно обрабатывать len(contour)==2
, верно?
@ Yuliang-Zou Да, но код if len(contour) > 4:
имеет дескриптор len(contour)==2
и len(contour)==4
.
@Sundrops Понятно , спасибо!
Я написал библиотеку и статью, чтобы помочь с созданием наборов данных в стиле COCO.
@Sundrops & @topcomma У меня проблема с загрузкой аннотированных данных в pycocotols, поскольку моя аннотация включает сегментацию без маски. есть идеи, как визуализировать аннотацию без маски в pycocotools?
@Sundrops
Аня: {
"сегментация": [
[312,29, 562,89, 402,25, 511,49, 400,96, 425,38, 398,39, 372,69, 388,11, 332,85, 318,71, 325,14, 295,58, 305,86, 269,88, 314,86, 258,31, 337,99, 217,13, 321,29, 132, 347,41,3, 347,13 , 358,55, 159,36, 377,83, 116,95, 421,53, 167,07, 499,92, 232,61, 560,32, 300,72, 571,89]
],
«площадь»: 54652.9556, г.
"iscrowd": 0,
"image_id": 480023,
"bbox": [116.95, 305.86, 285.3, 266.03],
"category_id": 58,
"id": 86
}
Как я могу рассчитать площадь с помощью mask.py в coco-api? Спасибо.
Мой код выглядит следующим образом, но с ошибкой:
segmentation = ann ['сегментация']
bimask = np.array (сегментация, dtype = np.uint8, порядок = 'F')
print ("бимаска:", бимаска)
rleObjs = mask.encode (бимаска)
print ("rleObjs:", rleObjs)
area = mask.area (rleObjs)
print ("область:", область)
@manketon
Возможно, вы можете попробовать cv2, но я не уверен, что это правильно. Это просто пример из раздела Удаление контуров с изображения с помощью Python и OpenCV .
def is_contour_bad(c):
# approximate the contour
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.02 * peri, True)
# return True if it is not a rectangle
return not len(approx) == 4
image = cv2.imread('xx.jpg')
contours = ann['segmentation']
mask = np.ones(image.shape[:2], dtype="uint8") * 255
# loop over the contours
for c in contours:
# if the contour is not a rectangle, draw it on the mask
if is_contour_bad(c):
cv2.drawContours(mask, [c], -1, 0, -1)
area = (mask==0).sum()
@Sundrops @waspinator У меня вопрос. Если моя исходная маска объекта имеет большие дыры, когда она преобразуется в полигоны, как мне правильно преобразовать ее обратно? Функции декодирования и слияния в coco API будут обрабатывать дыры как части объекта, поэтому при обратном преобразовании дыры становятся масками. Как мне поступить в этом случае?
@ wangg12 Насколько я знаю, в COCO нет собственного способа кодирования дыр.
for contour in contours:
contour = contour.flatten().tolist()
segmentation.append(contour)
if len(contour) > 4:
segmentation.append(contour)
Привет, @Sundrops , искренне спасибо за коды. Я новичок в Detectron. Я не понимаю, почему длина контура (который представляет собой список) должна быть больше 4, другими словами, что произойдет с моделью, когда длина меньше 4. В одном из ваших ответов говорилось, что Detectron будет рассматривать его как прямоугольник. На мой взгляд, там могут быть объекты прямоугольной формы, так что я думаю, что это нормально. Кроме того, мне интересно, добавляете ли вы контур дважды за одну итерацию. Думаю, правильный код должен быть.
for contour in contours:
contour = contour.flatten().tolist()
if len(contour) > 4:
segmentation.append(contour)
Буду очень признателен, если вы дадите мне несколько предложений. Большое спасибо!
@BobZhangHT Да, он должен добавлять контур один раз за одну итерацию.
Что касается вашего первого вопроса, если len (ann ['segmentation'] [0]) == 4, cocoapi будет считать, что все прямоугольные.
# cocoapi/PythonAPI/pycocotools/coco.py
def annToRLE(self, ann):
t = self.imgs[ann['image_id']]
h, w = t['height'], t['width']
segm = ann['segmentation']
if type(segm) == list:
rles = maskUtils.frPyObjects(segm, h, w)
rle = maskUtils.merge(rles)
......
# cocoapi/PythonAPI/pycocotools/_mask.pyx
def frPyObjects(pyobj, h, w):
# encode rle from a list of python objects
if type(pyobj) == np.ndarray:
objs = frBbox(pyobj, h, w)
elif type(pyobj) == list and len(pyobj[0]) == 4:
objs = frBbox(pyobj, h, w)
elif type(pyobj) == list and len(pyobj[0]) > 4:
objs = frPoly(pyobj, h, w)
......
@Sundrops Спасибо за ответ!
Я интерпретирую поли как список многоугольников, определенных вершинами, например [[x1, y1, x2, y2… xN, yN],… [x1, y1, x2, y2… xN, yN]], где координаты тот же масштаб, что и изображение. Маски, закодированные таким образом, правильно отображаются в CocoAPI [1]. Но вы можете захотеть получить «официальный» ответ. [1] https://github.com/cocodataset/cocoapi https://github.com/cocodataset/cocoapi
…
2 февраля 2018 г. в 09:18 Ху Сингуи @ . * > писал: @amokeev https://github.com/amokeev , вы уверены, что число в сегментации равно (x, y) вершин? Например «66916», большое количество! Другой, хотя я установил "iscrowd" как "1" для формата RLE, все же не смог работать на Detectron. - Вы получили это, потому что вас упомянули. Ответьте на это письмо напрямую, просмотрите его на GitHub < # 100 (comment) > или отключите поток https://github.com/notifications/unsubscribe-auth/AFlh63ObnXg-DcaDKwIi3pB4Ppig464Hks5tQsTkgaJpZM4R2tN3 .
Как я могу преобразовать RLE в полигоны, когда iscrowd равно «1», потому что материальный порт / MaskRCNN работает только с полигонами. @amokeev. Я хочу использовать материальную реализацию maskRCNN с набором данных coco, созданным с помощью pycococreator.
Самый полезный комментарий
@topcomma
Может быть, вы можете попробовать преобразовать маску в полигоны.