# Определение ключевых точек

Детекция ключевых точек (Keypoint detection) позволяет находить и определять координаты конкретных точек интереса на изображении. Эти ключевые точки, также известные как контрольные точки (landmarks), представляют собой значимые признаки объектов, например, черты лица или части объектов. Эти модели принимают изображение на вход и возвращают следующие выходные данные:

- **Ключевые точки и оценки**: Точки интереса и их оценки уверенности.
- **Дескрипторы**: представление области изображения, окружающей каждую ключевую точку, с захватом её текстуры, градиента, ориентации и других свойств.

В этом руководстве мы покажем, как извлекать ключевые точки из изображений.

Для этого учебника мы будем использовать [SuperPoint](../model_doc/superpoint) — базовую модель для обнаружения ключевых точек.

```python
from transformers import AutoImageProcessor, SuperPointForKeypointDetection
processor = AutoImageProcessor.from_pretrained("magic-leap-community/superpoint")
model = SuperPointForKeypointDetection.from_pretrained("magic-leap-community/superpoint")
```

Проверим модель на изображениях ниже.

    <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg"
         alt="Bee"
         style="height: 200px; object-fit: contain; margin-right: 10px;">
    <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png"
         alt="Cats"
         style="height: 200px; object-fit: contain;">

```python
import torch
from PIL import Image
import requests
import cv2

url_image_1 = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg"
image_1 = Image.open(requests.get(url_image_1, stream=True).raw)
url_image_2 = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats.png"
image_2 = Image.open(requests.get(url_image_2, stream=True).raw)

images = [image_1, image_2]
```

Теперь мы можем обработать входные данные и выполнить инференс.

```python
inputs = processor(images,return_tensors="pt").to(model.device, model.dtype)
outputs = model(**inputs)
```

Вывод модели содержит относительные ключевые точки, дескрипторы, маски и оценки для каждого элемента в батче. Маска выделяет области изображения, в которых присутствуют ключевые точки.

```python
SuperPointKeypointDescriptionOutput(loss=None, keypoints=tensor([[[0.0437, 0.0167],
         [0.0688, 0.0167],
         [0.0172, 0.0188],
         ...,
         [0.5984, 0.9812],
         [0.6953, 0.9812]]]), 
         scores=tensor([[0.0056, 0.0053, 0.0079,  ..., 0.0125, 0.0539, 0.0377],
        [0.0206, 0.0058, 0.0065,  ..., 0.0000, 0.0000, 0.0000]],
       grad_fn=<CopySlices>), descriptors=tensor([[[-0.0807,  0.0114, -0.1210,  ..., -0.1122,  0.0899,  0.0357],
         [-0.0807,  0.0114, -0.1210,  ..., -0.1122,  0.0899,  0.0357],
         [-0.0807,  0.0114, -0.1210,  ..., -0.1122,  0.0899,  0.0357],
         ...],
       grad_fn=<CopySlices>), mask=tensor([[1, 1, 1,  ..., 1, 1, 1],
        [1, 1, 1,  ..., 0, 0, 0]], dtype=torch.int32), hidden_states=None)
```

Чтобы отобразить фактические ключевые точки на изображении, необходимо выполнить постобработку результата. Для этого нужно передать в `post_process_keypoint_detection` вместе с результатами фактические размеры изображения.

```python
image_sizes = [(image.size[1], image.size[0]) for image in images]
outputs = processor.post_process_keypoint_detection(outputs, image_sizes)
```

Теперь выходные данные представляют собой список словарей, где каждый словарь содержит обработанные ключевые точки, оценки и дескрипторы.

```python
[{'keypoints': tensor([[ 226,   57],
          [ 356,   57],
          [  89,   64],
          ...,
          [3604, 3391]], dtype=torch.int32),
  'scores': tensor([0.0056, 0.0053, ...], grad_fn=<IndexBackward0>),
  'descriptors': tensor([[-0.0807,  0.0114, -0.1210,  ..., -0.1122,  0.0899,  0.0357],
          [-0.0807,  0.0114, -0.1210,  ..., -0.1122,  0.0899,  0.0357]],
         grad_fn=<IndexBackward0>)},
    {'keypoints': tensor([[ 46,   6],
          [ 78,   6],
          [422,   6],
          [206, 404]], dtype=torch.int32),
  'scores': tensor([0.0206, 0.0058, 0.0065, 0.0053, 0.0070, ...,grad_fn=<IndexBackward0>),
  'descriptors': tensor([[-0.0525,  0.0726,  0.0270,  ...,  0.0389, -0.0189, -0.0211],
          [-0.0525,  0.0726,  0.0270,  ...,  0.0389, -0.0189, -0.0211]}]
```

Мы можем использовать их для построения графика ключевых точек.

```python
import matplotlib.pyplot as plt
import torch

for i in range(len(images)):
  keypoints = outputs[i]["keypoints"]
  scores = outputs[i]["scores"]
  descriptors = outputs[i]["descriptors"]
  keypoints = outputs[i]["keypoints"].detach().numpy()
  scores = outputs[i]["scores"].detach().numpy()
  image = images[i]
  image_width, image_height = image.size

  plt.axis('off')
  plt.imshow(image)
  plt.scatter(
      keypoints[:, 0],
      keypoints[:, 1],
      s=scores * 100,
      c='cyan',
      alpha=0.4
  )
  plt.show()
```

Ниже представлены результаты.

    <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee_keypoint.png"
         alt="Bee"
         style="height: 200px; object-fit: contain; margin-right: 10px;">
    <img src="https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/cats_keypoint.png"
         alt="Cats"
         style="height: 200px; object-fit: contain;">

