Заменить экземпляр класса новым экземпляром

#python #class #tensor #faster-rcnn #detectron

#python #класс #тензор #быстрее-rcnn #detectron

Вопрос:

Я работаю над обнаружением объекта detectron2. Я столкнулся с проблемой фильтрации обнаруженных объектов.

Вот прогнозируемый результат detectron2:

 Instances(num_instances=9, image_height=547, image_width=820, fields=[pred_boxes: Boxes(tensor([[3.1173e 01, 3.8368e 01, 5.3751e 02, 5.4078e 02],
    [5.9945e 02, 2.6412e 02, 6.8196e 02, 5.1333e 02],
    [4.4486e 02, 1.7210e 02, 4.9981e 02, 2.5596e 02],
    [1.1566e-01, 2.3533e 02, 8.5483e 01, 3.6838e 02],
    [3.0897e 02, 2.4964e 02, 3.5739e 02, 4.8948e 02],
    [7.6962e-03, 2.3240e 02, 8.5447e 01, 3.7128e 02],
    [2.7454e 02, 2.6212e 02, 3.3122e 02, 4.5928e 02],
    [6.4399e 02, 3.0057e 02, 6.6374e 02, 3.8033e 02],
    [3.1025e 02, 2.5372e 02, 3.3572e 02, 3.5059e 02]])), scores: tensor([0.9998, 0.9994, 0.9941, 0.8815, 0.8447, 0.3559, 0.1484, 0.1304, 0.0928]), pred_classes: tensor([ 0,  0, 67,  2, 27,  7, 27, 27, 27]), pred_masks: tensor([[[False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     ...,
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False]],

    [[False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     ...,
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False]],

    [[False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     ...,
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False]],

    ...,

    [[False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     ...,
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False]],

    [[False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     ...,
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False]],

    [[False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     ...,
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False],
     [False, False, False,  ..., False, False, False]]])])
  

Я выполнил фильтрацию и создал новый список (dict) с предсказанными классами объектов, оценками и блоками. Я хотел построить график и визуализировать это на изображении:

Фильтрующий код:

 idxofClass = [i for i, x in enumerate(list(outputs['instances'].pred_classes)) if (x == 0)]
outputs_new = [{'pred_classes': o.pred_classes[idxofClass], 'scores':o.scores[idxofClass], 'pred_boxes':o.pred_boxes[idxofClass] }]
  

Теперь я могу получить отфильтрованные значения, как показано ниже:

 [{'pred_classes': tensor([ 0,  0, 67]), 'scores': tensor([0.9998, 0.9994, 0.9941]), 'pred_boxes': Boxes(tensor([[ 31.1728,  38.3685, 537.5092, 540.7788],
    [599.4498, 264.1228, 681.9622, 513.3326],
    [444.8603, 172.1017, 499.8055, 255.9632]]))}]
  

При передаче этого значения в визуализатор, получаю приведенную ниже ошибку:

 Traceback (most recent call last):
  File "apimodel.py", line 96, in <module>
    out = v.draw_instance_predictions(outputs_new)
  File "/root/anaconda3/envs/ml-engine/lib/python3.8/site-packages/detectron2/utils/visualizer.py", line 366, in draw_instance_predictions
    boxes = predictions.pred_boxes if predictions.has("pred_boxes") else None
AttributeError: 'list' object has no attribute 'has'
  

Тип данных исходного вывода — экземпляр класса:

 o = outputs["instances"]
print("data type:", type(o))
<class 'detectron2.structures.instances.Instances'>
  

Результатом вновь созданного отфильтрованного вывода является список (dict):

 <class 'list'>
  

Моя цель — построить ограничивающую рамку на основе отфильтрованной оценки. Я пытался заменить исходные значения выходных данных, но безуспешно. Пожалуйста, помогите в этом.

Ответ №1:

После двух дней поисков я нашел способ достичь своей цели. Я пишу ответ, как класс detectron2, так что, если кто-то ищет подобный подход, получит выгоду.

Фильтрующий индекс классов:

 idxofClass = [i for i, x in enumerate(list(outputs['instances'].pred_classes)) if x == 0]
  

Создавайте новые классы, боксы, партитуры и маски:

 classes = o.pred_classes[idxofClass]
scores = o.scores[idxofClass]
boxes = o.pred_boxes[idxofClass]
masks = o.pred_masks[idxofClass]
  

Определите новый экземпляр и задайте новые значения для нового экземпляра. Примечание: модуль detectron2 предоставляет этот метод set .

 obj = detectron2.structures.Instances(image_size=(480, 640))

obj.set('pred_classes', classes)
obj.set('scores', scores)
obj.set('pred_boxes', boxes)
obj.set('pred_masks', masks)
  

Теперь вы можете использовать этот новый экземпляр obj для другой обработки и визуализации:

 out = v.draw_instance_predictions(obj.to("cpu"))
  

Комментарии:

1. Как получить только значение поля в приведенном выше решении? Я тоже сталкиваюсь с той же проблемой, я хочу, чтобы в выходных данных были только поля [«Экземпляры»]

2. @suji Boxes вы можете получить его из исходных экземпляров, нет необходимости создавать отфильтрованный экземпляр. поля вывода=предсказания (ввода) = output[‘instances’].pred_boxes. оценки = output[‘экземпляры’].оценки классов = output[‘экземпляры’].маски pred_classes= output[‘экземпляры’].маски

Ответ №2:

Вот эффективный способ создать новый Instances объект после применения преобразования к данным предыдущего Instances объекта. В этом случае я применяю пороговое значение оценки, чтобы отфильтровать поля с низкими оценками прогнозирования ниже 0.5 .

Я использую преобразования torch для создания индексов, используемых для фильтрации. Кроме того, новый Instances класс может быть инициализирован со всеми установленными полями.

 instances = predictor(img)["instances"]
score_threshold = 0.5

filter_mask = instances.scores > score_threshold
indices = torch.nonzero(filter_mask).flatten().tolist()
filtered_instances = Instances(
    image_size=instances.image_size,
    pred_classes=instances.pred_classes[indices],
    scores=instances.scores[indices],
    pred_boxes=instances.pred_boxes[indices],
    pred_masks=instances.pred_masks[indices],
)