Сохранение заданного процента координат контура формы

Я создаю проект на Detectron2 с некоторыми грибами в качестве темы. Прогноз работает нормально, и теперь я пытаюсь сгенерировать COCO-подобные аннотации изображений с предсказанной областью (все координаты области XY). Для этого мне нужно сделать две вещи:

  • Получить координаты XY предсказанной формы / области и "уменьшить ее", чтобы сохранить только основные края (во избежание сохранения слишком большого количества точек данных)
  • Нанесите "сохраненные" точки обратно на основное изображение, чтобы пользователь мог оценить, достаточно ли точек сохраняется.

К сожалению, у меня ничего не получается. По первому пункту я (думаю), что у меня то же самое, что и у двоичного объекта numpy, но я удивлен его размером, И мне не удается преобразовать его в наборы координат XY

По второму пункту я получаю сообщение об ошибке, которое не могу понять, как отладить:

/usr/local/lib/python3.6/dist-packages/google/colab/patches/__init__.py in cv2_imshow(a)
     20       image.
     21   """
---> 22   a = a.clip(0, 255).astype('uint8')
     23   # cv2 stores colors as BGR; convert to RGB
     24   if a.ndim == 3:

AttributeError: 'cv2.UMat' object has no attribute 'clip'

Часть кода, которую я использую, находится здесь:

from detectron2.utils.visualizer import ColorMode

## Predicts some random image
dataset_dicts = get_all_mushroom_dicts(mushroom_categories, "mushroom_dataset_small/val")
d = random.sample(dataset_dicts, 1)  
im = cv2.imread(d["file_name"])
mushroom_outputs = mushroom_predictor(im)
v = Visualizer(im[:, :, ::-1],
               metadata=mushroom_metadata, 
               scale=0.8, 
               instance_mode=ColorMode.IMAGE_BW   # remove the colors of unsegmented pixels
)

instances = mushroom_outputs["instances"].to("cpu")
mush_out = v.draw_instance_predictions(instances)
image = mush_out.get_image()[:, :, ::-1]

masks = np.asarray(instances.pred_masks)
print ("NP array shape", masks.shape)
print("Image array shape", image.shape)

print("Type before", type(image))
cv2_imshow(image) ## works fine

## ?? How to get the coordinates of the boundaries? And then take only some of them

## ??

## Assuming that (128, 128) is one of these coordinates for now
image2 = cv2.circle(image, (128, 128), 10, (255, 0, 0), 20)
print("Type after", type(image2))
cv2_imshow(image2) ## crashes

К вашему сведению, я также пытался найти и нарисовать контур, но это, похоже, не работает (см. Мой пост здесь https://github.com/facebookresearch/detectron2/issues/1702).

У тебя есть какие-нибудь подсказки?

Спасибо!

1 ответ

Мне удалось найти решение, которое работает, но частично не изящно:

Получите координаты XY:

masks = np.asarray(instances.pred_masks)
cnt, heirarchy = cv2.findContours(masks[0].astype("uint8"), cv2.RETR_CCOMP, cv2.CHAIN_APPROX_NONE)
border = cnt[0]
gap = 20 # take only every 20 point
for i in list(range(border.shape[0]))[0::gap]:
  y = int(border[i][0][1]*0.8)
  x = int(border[i][0][0]*0.8)
  print("New XY coordinates", (x,y))

Нарисуйте на картинке:

image_old = mush_out.get_image()[:, :, ::-1]
cv2.imwrite("img.png", image_old)
image = cv2.imread("img.png",cv2.IMREAD_COLOR) # Still no clue why this is needed but doesnt work if you dont save and re-read...
radius = 3
color = (255, 0, 0)
cv2.circle(image, (x, y), radius, color, -1) # my previous code was wrong; cv2.circle returns void and edits directly the image 
cv2_imshow(image) 
Другие вопросы по тегам