# 人体姿态估计接口 本文档描述了人体姿态估计(Human Pose Estimation, HPE)服务的 HTTP API 接口规范。 ## 目录 - [人体姿态估计接口](#人体姿态估计接口) - [目录](#目录) - [服务概述](#服务概述) - [接口说明](#接口说明) - [请求](#请求) - [请求头](#请求头) - [响应](#响应) - [成功响应](#成功响应) - [响应体示例](#响应体示例) - [错误码](#错误码) - [错误响应示例](#错误响应示例) - [响应数据结构](#响应数据结构) - [关键点定义](#关键点定义) - [骨骼连接定义](#骨骼连接定义) - [可视化示例](#可视化示例) - [使用示例](#使用示例) - [Python 示例](#python-示例) - [Bash/cURL 示例](#bashcurl-示例) - [cURL 快速示例](#curl-快速示例) - [注意事项](#注意事项) --- ## 服务概述 HPE 服务提供基于深度学习的人体姿态估计能力,可从输入图像中检测人体并识别 133 个关键点(全身姿态,包含身体、手部及面部关键点)。 - **服务端点**:`https://api.pose.weihua-iot.cn/hpe` --- ## 接口说明 ### 请求 | 属性 | 说明 | | ------------------ | --------------------------- | | **URL** | `/hpe` | | **方法** | `POST` | | **Content-Type** | `image/jpeg` 或 `image/png` | | **请求体** | 原始图像二进制数据 | | **最大请求体大小** | 10 MB | | **超时时间** | 30 秒 | #### 请求头 | 名称 | 必填 | 说明 | | ---------------- | ---- | ---------------------------------- | | `Content-Type` | 是 | 必须为 `image/jpeg` 或 `image/png` | | `Content-Length` | 否 | 请求体字节数(推荐提供) | ### 响应 #### 成功响应 | HTTP 状态码 | Content-Type | 说明 | | ----------- | ------------------ | ------------------------------ | | `200` | `application/json` | 检测到姿态,返回 JSON 数据 | | `200` | 无内容 | 未检测到人体姿态,返回空响应体 | #### 响应体示例 ```json { "frame_index": 0, "reference_size": [1920, 1080], "bbox": [[100, 150, 400, 800], [500, 200, 750, 850]], "bbox_confidence": [0.95, 0.87], "keypoints": [ [[x1, y1], [x2, y2], ...], [[x1, y1], [x2, y2], ...] ], "keypoints_confidence": [ [0.9, 0.85, ...], [0.88, 0.92, ...] ] } ``` ### 错误码 | HTTP 状态码 | 错误类型 | 说明 | | ----------- | ---------------------- | --------------------------------------------- | | `400` | Bad Request | 请求体为空或图像解码失败 | | `408` | Request Timeout | 推理超时(超过 30 秒) | | `413` | Payload Too Large | 请求体超过 10 MB 限制 | | `415` | Unsupported Media Type | Content-Type 不是 `image/jpeg` 或 `image/png` | | `503` | Service Unavailable | 服务过载,请求队列已满(最大 16 个请求) | #### 错误响应示例 ```json { "error": "Unsupported Media Type", "detail": "Expected Content-Type: image/jpeg or image/png, got: text/plain" } ``` --- ## 响应数据结构 | 字段 | 类型 | 说明 | | ---------------------- | ------------------------------- | -------------------------------------------------------------------------------- | | `frame_index` | `int` | 帧索引,HTTP 接口始终返回 `0` | | `reference_size` | `[int, int]` | 输入图像尺寸,格式为 `[宽度, 高度]` | | `bbox` | `[[x1, y1, x2, y2], ...]` | 检测到的人体边界框列表,每个边界框包含左上角 `(x1, y1)` 和右下角 `(x2, y2)` 坐标 | | `bbox_confidence` | `[float, ...]` 或 `null` | 每个边界框的置信度分数(0-1),可能为空 | | `keypoints` | `[[[x, y], ...], ...]` | 每个检测到的人体的 133 个关键点坐标列表 | | `keypoints_confidence` | `[[float, ...], ...]` 或 `null` | 每个关键点的置信度分数(0-1),可能为空 | --- ## 关键点定义 本服务使用 COCO WholeBody 格式,共包含 133 个关键点: | 索引范围 | 数量 | 描述 | | -------- | ---- | -------------------------------------------------------------------- | | 0-16 | 17 | 身体关键点(鼻子、眼睛、耳朵、肩膀、肘部、手腕、髋部、膝盖、脚踝等) | | 17-22 | 6 | 脚部关键点 | | 23-90 | 68 | 面部关键点 | | 91-111 | 21 | 左手关键点 | | 112-132 | 21 | 右手关键点 | ![关键点示意图](figures/Fig2_anno.webp) ### 骨骼连接定义 关键点之间通过骨骼(Bone)连接形成人体骨架结构。主要骨骼连接如下: | 部位 | 连接关系(0-based 索引) | | ---- | ------------------------------------------------ | | 腿部 | (15, 13), (13, 11), (16, 14), (14, 12), (11, 12) | | 躯干 | (5, 11), (6, 12), (5, 6) | | 手臂 | (5, 7), (7, 9), (6, 8), (8, 10) | | 头部 | (1, 2), (0, 1), (0, 2), (1, 3), (2, 4) | | 左脚 | (15, 17), (15, 18), (15, 19) | | 右脚 | (16, 20), (16, 21), (16, 22) | | 左手 | 手腕(91)连接至各指根,每指4个关节依次连接 | | 右手 | 手腕(112)连接至各指根,每指4个关节依次连接 | ### 可视化示例 项目提供了完整的可视化脚本 [scripts/vis_whole_body.py](scripts/vis_whole_body.py),包含: - **关键点定义**:`body_landmarks`、`foot_landmarks`、`face_landmarks`、`hand_landmarks` 字典,包含每个关键点的索引、名称和颜色 - **骨骼定义**:`body_bones`、`hand_bones` 列表,定义了关键点之间的连接关系 - **可视化函数**: - `visualize_whole_body()` - 可视化单人 133 个关键点 - `visualize_17_keypoints()` - 仅可视化 17 个身体关键点 --- ## 使用示例 完整的客户端示例代码位于 [scripts](scripts/) 目录下。 ### Python 示例 参见 [scripts/client_example.py](scripts/client_example.py)。 该脚本使用 [PEP 723](https://peps.python.org/pep-0723/) 内联脚本元数据,可通过 [uv](https://docs.astral.sh/uv/) 直接运行,无需手动安装依赖: ```bash # 使用 uv 直接运行(自动安装依赖) uv run scripts/client_example.py photo.jpg # 指定自定义 URL uv run scripts/client_example.py photo.png --url https://api.pose.weihua-iot.cn/hpe # 或使用传统方式(需先安装 httpx) pip install httpx python scripts/client_example.py photo.jpg ``` ### Bash/cURL 示例 参见 [scripts/client_example.sh](scripts/client_example.sh)。 ```bash # 赋予执行权限 chmod +x scripts/client_example.sh # 发送图像 ./scripts/client_example.sh figures/sample.jpg # 指定自定义 URL ./scripts/client_example.sh figures/sample.jpg https://api.pose.weihua-iot.cn/hpe ``` ### cURL 快速示例 ```bash # 发送 JPEG 图像 curl -X POST \ -H "Content-Type: image/jpeg" \ --data-binary @figures/sample.jpg \ https://api.pose.weihua-iot.cn/hpe # 发送 PNG 图像并使用 jq 格式化输出 curl -s -X POST \ -H "Content-Type: image/png" \ --data-binary @figures/sample.png \ https://api.pose.weihua-iot.cn/hpe | jq . # 将结果保存到文件 curl -X POST \ -H "Content-Type: image/jpeg" \ --data-binary @figures/sample.jpg \ -o result.json \ https://api.pose.weihua-iot.cn/hpe ``` --- ## 注意事项 1. **图像格式**:仅支持 JPEG 和 PNG 格式,其他格式将返回 415 错误。 2. **图像大小**:请确保图像文件不超过 10 MB,否则将返回 413 错误。 3. **并发限制**:服务最多同时处理 16 个请求,超出后将返回 503 错误。 4. **超时处理**:单次推理最长等待 30 秒,超时将返回 408 错误。 5. **空结果处理**:当未检测到人体时,服务返回 HTTP 200 但响应体为空,请在客户端代码中正确处理此情况。