페이지 이동경로
  • 문서>
  • 포즈>
  • REST API

포즈

REST API

이 문서는 카카오 포즈(Pose) API 구현 방법을 안내합니다.

포즈 API는 SDK를 지원하지 않으며 REST API 방식으로 구현할 수 있습니다.

  • 요청 시 HTTP connection timeout은 5초, read timeout은 15초로 설정합니다.
  • 과도하게 많은 요청을 보내어 초당 요청 한도를 초과하는 경우 오류 응답을 받을 수 있습니다.
  • 응답 형식은 객체 인식 및 검출에 사용되는 COCO(Common Objects in Context) dataformat의 형식에 맞춰 제공합니다.
  • 응답 코드는 REST API 레퍼런스에서 확인할 수 있습니다.

이 문서에 포함된 기능 일부는 [도구] > [REST API 테스트]를 통해 사용해 볼 수 있습니다.

이미지 분석하기

기본 정보

POST /pose HTTP/1.1
Host: cv-api.kakaobrain.com 
Authorization: KakaoAK ${REST_API_KEY} 

이미지 분석하기 API는 하나의 이미지 내에서 사람들을 찾아 이미지에서 사람을 인식한 후, 사람의 코, 눈, 귀, 어깨, 팔꿈치, 손목, 골반, 무릎, 발목 총 17개의 키 포인트를 추출하여 사람의 자세(Pose)를 분석합니다.

요청 헤더에 REST API키를 담아 POST로 이미지 분석을 요청합니다. 이미지 요청 시 이미지 파일(file)을 업로드 하거나 또는 이미지 URL(image_url)을 지정할 수 있습니다.

요청이 성공하면 응답 바디에 검출된 각 키 포인트의 좌표와 신뢰도가 JSON 객체(Person[])로 반환됩니다. 이미지에 사람이 여러 명 있을 경우, 검출된 사람들의 키 포인트 정보 값은 Person 객체의 목록으로 반환됩니다.

키 포인트 추출 지점의 예시

Request

Header
Name Description Required
Authorization REST API 키
[내 애플리케이션] > [앱 키]에서 확인 가능
O
Parameter
Name Type Description Required
image_url String 이미지 URL O*
file Binary 처리할 이미지 파일 O*

* 조건부: image_url / file 중 하나 필수

주의: 이미지 분석 요청 시 유의사항

- file에 업로드되는 이미지와 image_url에 지정되는 이미지는 JPEG, PNG, HEIC, WebP 포맷만 지원합니다. - 업로드 할 수 있는 이미지의 최대 용량은 2MB 입니다. - 이미지의 가로와 세로 길이는 긴 변을 기준으로 최대 2048 pixel, 짧은 변을 기준으로 최소 320 pixel 이어야 합니다. - 이미지의 권장 비율은 가로:세로 기준 16:9 ~ 9:16 입니다. - file을 업로드하는 경우, Content-Type을 multipart/form-data로 요청합니다. - image_url로 호출하는 경우, Content-Type을 application/x-www-form-urlencoded로 요청합니다.

Response

Person
Name Type Description
area Float 키 포인트를 모두 포함하는 바운딩 박스(bounding box)의 넓이
bbox Float[] 키 포인트 중 가장 위쪽에 있는 키 포인트의 좌표(x,y)와 바운딩 박스의 너비(w)와 높이(h)
[x, y, w, h]
category_id Int 1로 고정
1: Person
keypoints Float[] 이미지에서 검출된 17개의 키 포인트의 좌표(x, y)와 정확도(score)
[x_1, y_1, score_1, x_2, y_2, score_2, ..., x_17, y_17, score_17]
x, y, score 값 뒤에 표기한 1부터 17까지의 키 포인트 ID는 사람의 각 신체 부위를 나타냄 (아래 keypoints 항목 참고)
예: [코의 x 좌표, 코의 y 좌표, 코의 키 포인트에 대한 신뢰도, 왼쪽 눈의 x 좌표, 왼쪽 눈의 y 좌표, 왼쪽 눈의 키 포인트에 대한 신뢰도, …, 오른쪽 발목의 x 좌표, 오른쪽 발목의 y 좌표, 오른쪽 발목의 키 포인트에 대한 신뢰도]
score Float 키 포인트 데이터에 대한 신뢰도, 0부터 1 사이 값
keypoints
키 포인트 ID 신체 부위
1 nose
2 left_eye
3 right_eye
4 left_ear
5 right_ear
6 left_shoulder
7 right_shoulder
8 left_elbow
9 right_elbow
10 left_wrist
11 right_wrist
12 left_hip
13 right_hip
14 left_knee
15 right_knee
16 left_ankle
17 right_ankle

Sample

Request: 이미지 URL로 요청
curl -v -X  POST "https://cv-api.kakaobrain.com/pose" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -H "Authorization: KakaoAK ${REST_API_KEY}" \
  --data-urlencode "image_url=https://example.com/example.jpg" 
Request: 파일로 요청
curl -v -X POST "https://cv-api.kakaobrain.com/pose" \
  -H "Content-Type: multipart/form-data" \
  -H "Authorization: KakaoAK ${REST_API_KEY}" \
  -F "file=@example_pose.jpg" 
Response
[
    {
        "area": 101090.2833,
        "bbox": [719.4526, 244.1255, 182.7314, 553.2178],
        "category_id": 1,
        "keypoints": [
            805.4897, 256.4165, 0.8422, 819.5366, 245.0034, 0.8773, 795.8325, 244.1255, 0.8664, 845.8745, 254.6606, 0.8105, 788.8091, 251.1489, 0.0631, 885.3813, 320.5054, 0.7525, 749.3022, 331.9185, 0.7706, 898.5503, 377.5708, 0.7825, 719.4526, 414.4438, 0.7897, 901.1841, 435.5142, 0.7782, 749.3022, 443.4155, 0.8086, 852.02, 504.8706, 0.6854, 785.2974, 511.894, 0.6738, 833.5835, 644.4614, 0.7899, 800.2222, 659.3862, 0.7655, 833.5835, 796.3433, 0.7055, 824.8042, 743.6675, 0.5165
        ],
        "score": 0.7185
    }
]

영상 분석하기

기본 정보

POST /pose/job HTTP/1.1
Host: cv-api.kakaobrain.com 
Authorization: KakaoAK ${REST_API_KEY} 

영상 분석하기 API는 영상을 다중 이미지로 처리하여 포즈를 분석하는 API입니다. 이 API는 영상을 분석하는 API로 작업 결과를 확인하려면 응답에서 전달 받은 job_id를 담아 영상 분석 결과 확인하기 API를 호출해야 합니다.

콜백(callback_url) 기능을 사용하여 영상 분석이 완료되었음을 확인한 후, 영상 분석 결과 확인하기 API를 호출하는 것을 권장합니다.

요청 헤더에 REST API키를 담아 분석할 POST로 영상 분석을 요청합니다. 영상 요청 시 영상 파일(file)을 업로드 하거나 또는 영상 URL(video_url)을 지정할 수 있습니다. 요청이 성공하면 작업물에 대한 ID(job_id)를 반환합니다.

Request

Header
Name Description Required
Authorization REST API 키
[내 애플리케이션] > [앱 키]에서 확인 가능
O
Parameter
Name Type Description Required
video_url String 처리할 영상의 URL
HTTP(80포트)와 HTTPS(443 포트) 지원
O*
file Binary 처리할 영상 파일 O*
smoothing Boolean 검출된 프레임 사이의 키 포인트 위치를 smoothing 처리할 것인지 여부, true 또는 false (기본값: true) X
callback_url String 요청 처리 결과를 받을 콜백(callback) URL
HTTPS(443 포트) 사용 권장
아래 Sample: Callback과 같은 형태로 한 번 호출되며, 실패할 경우 재시도는 하지 않습니다.
X

* 조건부: video_url / file 중 하나 필수

영상 분석 요청 시 유의사항

- 무료 쿼터 사용 시, 영상은 최대 50MB 영상까지 업로드 할 수 있습니다. 최대 용량을 넘는 영상을 업로드할 경우, 에러가 발생하며, 더 큰 용량의 영상 처리를 위해서는 제휴 신청이 필요합니다. - 무료 쿼터 사용 시, 영상은 최대 30초까지만 처리됩니다. 최대 프레임 수를 넘는 영상을 업로드 할 경우, 앞 쪽 30초까지의 영상만 처리됩니다. 더 긴 영상 처리를 위해서는 제휴 신청이 필요합니다. - 영상의 가로와 세로 길이는 긴 변을 기준으로 최대 2048 pixel, 짧은 변을 기준으로 최소 320 pixel 이어야 합니다. - 영상의 권장 비율은 가로:세로 기준 16:9 ~ 9:16 입니다. - file을 업로드하는 경우, Content-Type을 multipart/form-data로 요청합니다. - video_url로 호출하는 경우, Content-Type을 application/x-www-form-urlencoded로 요청합니다.

callback_url 권장 사항

카카오 브레인 서버에서 영상 분석이 완료되면 성공 여부와 상관없이 지정한 callback_url로 분석한 작업물의 ID와 함께 작업이 완료되었음을 알립니다. callback_url을 통해 영상 분석이 완료되었음을 확인한 후, 영상 분석 결과 확인하기 API를 통해 분석한 결과를 확인할 것을 권장합니다.

Response

Name Type Description
job_id String 포즈 분석을 요청한 영상의 Job ID

Sample

Request: 영상 URL로 요청
curl -v -X POST "https://cv-api.kakaobrain.com/pose/job" \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -H "Authorization: KakaoAK ${REST_API_KEY}" \
    --data-urlencode "video_url=http://example.com/example.mp4" 
Request: 파일로 요청
curl -v -X POST "https://cv-api.kakaobrain.com/pose/job" \
    -H "Content-Type: multipart/form-data" \
    -H "Authorization: KakaoAK ${REST_API_KEY}" \ 
    -F "file=@example.mp4" 
Response
{
    "job_id":"bb91c265-341d-4661-813b-870cff0de1d3"
}
Sample: Callback
curl -v -X GET "https://api.example.com/pose/callback?job_id=bb91c265-341d-4661-813b-870cff0de1d3"

영상 분석 결과 확인하기

기본 정보

GET /pose/job/${job_id} HTTP/1.1
Host: cv-api.kakaobrain.com 
Authorization: KakaoAK ${REST_API_KEY} 

영상 분석하기 API를 통해 요청한 작업물의 처리 상태와 결과를 반환하는 API입니다. 영상 분석하기 API 요청을 통해 전달 받은 job_id를 URL에 담고, 요청 헤더에 REST API키를 담아 GET으로 이미지 포즈 분석 결과를 확인합니다.

영상 분석이 성공적으로 완료되면 각 프레임 별로 사람들의 키 포인트에 대한 정보를 JSON 객체로 반환합니다.

Request

Header
Name Description Required
Authorization REST API 키
[내 애플리케이션] > [앱 키]에서 확인 가능
O
Parameter
Name Type Description Require
job_id String 영상 분석하기 API 응답으로 받은 Job ID O

Response

Name Type Description
job_id String 포즈 분석을 요청한 영상의 Job ID
status String 요청에 대한 응답 상태: waiting, processing, success, failed, not found 중 하나
- waiting: 내부에서 대기 중
- processing: 처리 중
- success: 정상
- failed: 처리 실패
- not found: 해당 Job ID로 찾을 수 없는 경우나 결과 보관 기간이 7일을 지난 경우
annotations Annotation[] 프레임 수만큼의 크기를 가진 배열로 각 프레임(Frame) 별로 검출한 키 포인트의 좌표와 신뢰도를 담은 객체들의 목록
아래 Annotations 항목 참고
"status: success"인 경우에만 반환
categories Category[] 키 포인트가 의미하는 정보를 담은 객체
아래 Categories 항목 참고
"status: success"인 경우에만 반환
info Info 생성된 작업물에 대한 정보(버전, 생성 날짜, URL, 설명 등)를 담은 객체
"status: success"인 경우에만 반환
video Video 요청한 영상의 프레임에 대한 정보(초당 진행되는 프레임의 수, 영상의 전체 프레임 수, 프레임의 가로/세로 길이)를 담은 객체
"status: success"인 경우에만 반환
description String 요청 처리 실패 사유
"status: failed"인 경우에만 반환
예: "Failed to get video"
Annotation
Name Type Description
frame_num Int 프레임의 번호, 0에서 n-1(n=프레임 수)
objects Person[] 검출한 키 포인트의 좌표와 신뢰도를 담은 객체
객체에 대한 세부 파라미터는 이미지 분석하기 API의 Person 참고
Category
Name Type Description
id Int 1로 고정
1: person
keypoints String[] 17개의 키 포인트에 해당하는 신체 부위의 영문명을 담은 배열
["nose", "left_eye", "right_eye", "left_ear", "right_ear", "left_shoulder", "right_shoulder", "left_elbow", "right_elbow", "left_wrist", "right_wrist", "left_hip", "right_hip", "left_knee", "right_knee", "left_ankle", "right_ankle"]
name String person으로 고정
skeleton List<Int[]> 연결된 두 키 포인트 ID들을 담은 목록
예:[1, 2]는 코와 왼쪽 귀를 연결한 선을 의미
supercategory String person으로 고정

Sample

Request
curl -v -X GET "https://cv-api.kakaobrain.com/pose/job/bb91c265-341d-4661-813b870cff0de1d3" \
  -H "Authorization: KakaoAK ${REST_API_KEY}" 
Response: 성공
{
    "annotations": [
       {
        "frame_num": 0,
        "objects": [
            {
            "area": 211350.1765,
            "bbox": [340.11, 22.28, 302.92, 697.72],
            "category_id": 1,
            "keypoints": [517.0, 185.81, 1.0, 524.27, 171.27, 1.0, 517.0, 171.27, 0.86, 560.61, 200.35, 1.0, 0.0, 0.0, 0.0, 582.41, 265.76, 1.0, 473.4, 243.95, 0.97, 596.95, 345.7, 1.0, 407.99, 164.01, 1.0, 524.27, 309.36, 1.0, 371.65, 84.06, 1.0, 546.08, 447.45, 0.87, 480.66, 432.92, 0.88, 531.54, 600.08, 1.0, 480.66, 541.94, 1.0, 524.27, 701.83, 1.0, 473.4, 607.35, 1.0],
            "score": 0.9563
            }
          ]
       } 
           ... // 첫 프레임 이후 결과는 생략
       ],
    "categories": [
        {
        "id": 1,
        "keypoints": ["nose", "left_eye", "right_eye", "left_ear", "right_ear", "left_shoulder", "right_shoulder", "left_elbow", "right_elbow", "left_wrist", "right_wrist", "left_hip", "right_hip", "left_knee", "right_knee", "left_ankle", "right_ankle"],
        "name": "person",
        "skeleton": [[1, 2], [1, 3], [2, 3], [2, 4], [3, 5], [4, 6], [5, 7], [6, 7], [6, 8], [6, 12], [7, 9], [7, 13], [8, 10], [9, 11], [12, 13], [14, 12], [15, 13], [16, 14], [17, 15]],
        "supercategory": "person"
        }
    ],
    "info": {
        "contributor": "Kakao Brain Corp.",
        "date_created": "2020/05/26",
        "description": "Human pose estimation result from Kakao Brain",
        "url": "https://www.kakaobrain.com",
        "version": "191227",
        "year": 2020
    },
    "job_id": "bb91c265-341d-4661-813b-870cff0de1d3",
    "status": "success",
    "video": {
        "fps": 29.97,
        "frames": 30,
        "height": 720,
        "width": 1280
    }
}
Response: 실패
{
    "description": "Failed to get video",
    "job_id": "32b1dc9e-16c6-426b-9b06-d1c3e2abdfb4",
    "status": "failed"
}

구현 예제

다음은 포즈 API 구현 예제입니다.

Python 예제

Python을 이용하여 포즈 API를 구현한 예제입니다. Python 버전은 3.5 이상을 권장합니다.

이미지 분석하기
import requests
APP_KEY = '${REST_API_KEY}'
IMAGE_URL = 'http://example.com/example.jpg'
IMAGE_FILE_PATH = 'example.jpg'
session = requests.Session()
session.headers.update({'Authorization': 'KakaoAK ' + APP_KEY})

# URL로 이미지 입력시
response = session.post('https://cv-api.kakaobrain.com/pose', data={'image_url': IMAGE_URL})
print(response.status_code, response.json())

# 파일로 이미지 입력시
with open(IMAGE_FILE_PATH, 'rb') as f:
    response = session.post('https://cv-api.kakaobrain.com/pose', files=[('file', f)])
    print(response.status_code, response.json())
영상 분석하기
import os
import requests

APP_KEY = '${REST_API_KEY}'
VIDEO_URL = 'http://example.com/example.mp4'
VIDEO_FILE_PATH = 'example.mp4'

session = requests.Session()
session.headers.update({'Authorization': 'KakaoAK ' + APP_KEY})

# URL로 영상 입력시
response = session.post('https://cv-api.kakaobrain.com/pose/job', data={'video_url': VIDEO_URL})
print(response.status_code, response.json())
job_id = response.json()['job_id']

# 파일로 영상 입력시
assert os.path.getsize(VIDEO_FILE_PATH) < 5e7
with open(VIDEO_FILE_PATH, 'rb') as f:
    response = session.post('https://cv-api.kakaobrain.com/pose/job', files=[('file', f)])
    print(response.status_code, response.json())
    job_id = response.json()['job_id']
영상 분석하기 결과 확인하기
import requests
APP_KEY = '${REST_API_KEY}'
session = requests.Session()
session.headers.update({'Authorization': 'KakaoAK ' + APP_KEY})
response = session.get('https://cv-api.kakaobrain.com/pose/job/' + job_id)
print(response.status_code, response.json())

COCO 포맷 활용 예제

COCO API를 활용하여 결과를 시각화하는 예제입니다. 이미지 분석하기 API를 이용한 이미지 결과 시각화와 영상 분석하기 API와 영상 분석 결과 확인하기 API를 활용한 영상 결과 시각화 예제를 소개합니다.

COCO API를 활용하려면 pycocotools 패키지가 필요합니다. 원활한 의존성 설치를 위해 pycocotools 설치 전 반드시 CythonNumPy를 먼저 설치합니다.

pip install Cython numpy
pip install matplotlib pycocotools requests pillow opencv-python
Sample: 이미지 결과 시각화
import cv2
import numpy as np
from matplotlib import pyplot as plt
from pycocotools.coco import COCO
from requests import Session
 
APP_KEY = '${REST_API_KEY}'
session = Session()
session.headers.update({'Authorization': 'KakaoAK ' + APP_KEY})
 
 
def inference(filename):
    with open(filename, 'rb') as f:
        response = session.post('https://cv-api.kakaobrain.com/pose', files={'file': f})
        response.raise_for_status()
        return response.json()
 
 
def visualize(filename, annotations, threshold=0.2):
    # 낮은 신뢰도를 가진 keypoint들은 무시
    for annotation in annotations:
        keypoints = np.asarray(annotation['keypoints']).reshape(-1, 3)
        low_confidence = keypoints[:, -1] < threshold
        keypoints[low_confidence, :] = [0, 0, 0]
        annotation['keypoints'] = keypoints.reshape(-1).tolist()
 
    # COCO API를 활용한 시각화
    image = cv2.cvtColor(cv2.imread(filename, cv2.IMREAD_COLOR), cv2.COLOR_BGR2RGB)
    plt.imshow(image)
    plt.axis('off')
    coco = COCO()
    coco.dataset = {
        "categories": [
            {
                "supercategory": "person",
                "id": 1,
                "name": "person",
                "keypoints": ["nose", "left_eye", "right_eye", "left_ear", "right_ear", "left_shoulder",
                              "right_shoulder", "left_elbow", "right_elbow", "left_wrist", "right_wrist", "left_hip",
                              "right_hip", "left_knee", "right_knee", "left_ankle", "right_ankle"],
                "skeleton": [[1, 2], [1, 3], [2, 3], [2, 4], [3, 5], [4, 6], [5, 7], [6, 7], [6, 8], [6, 12], [7, 9],
                             [7, 13], [8, 10], [9, 11], [12, 13], [14, 12], [15, 13], [16, 14], [17, 15]]
            }
        ]
    }
    coco.createIndex()
    coco.showAnns(annotations)
    plt.show()
 
 
IMAGE_FILE_PATH = 'example_pose.jpg'
result = inference(IMAGE_FILE_PATH)
visualize(IMAGE_FILE_PATH, result)
Sample: 영상 결과 시각화
import os
import time
 
import numpy as np
from matplotlib import pyplot as plt
from pycocotools.coco import COCO
from requests import Session
 
APP_KEY = '${REST_API_KEY}'
 
session = Session()
session.headers.update({'Authorization': 'KakaoAK ' + APP_KEY})
 
 
def submit_job_by_url(video_url):
    response = session.post('https://cv-api.kakaobrain.com/pose/job', data={'video_url': video_url})
    response.raise_for_status()
    return response.json()


def submit_job_by_file(video_file_path):
    assert os.path.getsize(video_file_path) < 5e7
    with open(video_file_path, 'rb') as f:
        response = session.post('https://cv-api.kakaobrain.com/pose/job', files=[('file', f)])
        response.raise_for_status()
        return response.json()


 
# 실제 연동시엔 콜백을 이용한 방식으로 구현하시는 것을 권장합니다
def get_job_result(job_id):
    while True:
        response = session.get('https://cv-api.kakaobrain.com/pose/job/' + job_id)
        response.raise_for_status()
        response = response.json()
        if response['status'] in {'waiting', 'processing'}:
            time.sleep(10)
        else:
            return response
 
 
def visualize(resp, threshold=0.2):
    # COCO API를 활용한 시각화
    coco = COCO()
    coco.dataset = {'categories': resp['categories']}
    coco.createIndex()
    width, height = resp['video']['width'], resp['video']['height']
 
    # 낮은 신뢰도를 가진 keypoint들은 무시
    for frame in resp['annotations']:
        for annotation in frame['objects']:
            keypoints = np.asarray(annotation['keypoints']).reshape(-1, 3)
            low_confidence = keypoints[:, -1] < threshold
            keypoints[low_confidence, :] = [0, 0, 0]
            annotation['keypoints'] = keypoints.reshape(-1).tolist()
 
        plt.axis('off')
        plt.title("frame: " + str(frame['frame_num'] + 1))
        plt.xlim(0, width)
        plt.ylim(height, 0)
        coco.showAnns(frame['objects'])
        plt.show()
 

VIDEO_URL = 'http://example.com/example.mp4'
VIDEO_FILE_PATH = 'example.mp4'

# URL로 영상 지정 시
submit_result = submit_job_by_url(VIDEO_URL)
# 파일로 영상 업로드 시 
submit_result = submit_job_by_file(VIDEO_FILE_PATH)

job_id = submit_result['job_id']

job_result = get_job_result(job_id)
if job_result['status'] == 'success':
    visualize(job_result)
else:
    print(job_result)

더보기