키포인트 탐지
키포인트 탐지 (Keypoint Detection)
키포인트 탐지는 이미지 내에서 관심 있는 특정 지점을 식별하고 위치를 찾는 작업입니다. 랜드마크라고도 하는 이러한 키포인트는 얼굴 특징이나 객체 부위와 같은 객체의 의미 있는 특징을 나타냅니다. 이 모델들은 이미지 입력을 받아 다음 출력을 반환합니다.
출처: 문서
본문
- Keypoints and Scores: 관심 지점과 그 신뢰도 점수(confidence score).
- Descriptors: 각 키포인트 주변 이미지 영역을 나타내는 표현으로, 텍스처, 그래디언트, 방향 등의 속성을 포착합니다.
이 가이드에서는 이미지에서 키포인트를 추출하는 방법을 보여드리겠습니다.
이 튜토리얼에서는 키포인트 탐지용 파운데이션 모델인 SuperPoint를 사용하겠습니다.
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;">
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]
이제 입력을 처리하고 추론할 수 있습니다.
inputs = processor(images,return_tensors="pt").to(model.device, model.dtype)
outputs = model(**inputs)
모델 출력은 배치의 각 항목에 대한 상대적 키포인트, 디스크립터, 마스크, 점수를 가집니다. 마스크는 이미지에서 키포인트가 존재하는 영역을 강조합니다.
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에 전달해야 합니다.
image_sizes = [(image.size[1], image.size[0]) for image in images]
outputs = processor.post_process_keypoint_detection(outputs, image_sizes)
출력은 이제 딕셔너리 리스트이며, 각 딕셔너리는 키포인트, 점수, 디스크립터의 처리된 출력입니다.
[{'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]}]
이것들을 사용해 키포인트를 플롯할 수 있습니다.
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;">