Сохранение заданного процента координат контура формы
Я создаю проект на 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)