手把手教你用Python处理LSP人体姿态数据集(附可视化代码)
手把手教你用Python处理LSP人体姿态数据集(附可视化代码)
在计算机视觉领域,人体姿态估计是一个热门研究方向,而高质量的数据集是算法开发的基础。Leeds Sports Pose(LSP)数据集作为早期经典的人体姿态标注数据集,至今仍被广泛用于学术研究和算法验证。但对于刚接触该领域的新手来说,面对原始的 .mat 文件和一堆图片,往往会感到无从下手。本文将带你从零开始,用Python一步步解析LSP数据集,并实现关键点可视化。
1. 环境准备与数据加载
在开始处理LSP数据集前,我们需要搭建合适的Python环境。推荐使用Anaconda创建虚拟环境,避免包版本冲突:
conda create -n lsp_processing python=3.8
conda activate lsp_processing
安装必要的依赖库:
pip install numpy matplotlib opencv-python scipy
LSP数据集通常包含以下文件结构:
images/:原始运动图像(2000张)joints.mat:MATLAB格式的关节点标注文件visualized/:已标注的可视化图像(可选参考)
提示:下载数据集后,建议保持原始目录结构不变,方便后续处理。
2. 解析MATLAB格式的标注文件
LSP数据集的核心标注信息存储在 joints.mat 文件中,这是一个MATLAB格式的二进制文件。Python中可以使用 scipy.io 模块来加载:
import scipy.io
def load_lsp_mat(mat_path):
"""加载LSP标注的.mat文件"""
mat_data = scipy.io.loadmat(mat_path)
joints = mat_data['joints'] # 获取关节点数据
return joints
joints 是一个3×14×2000的numpy数组,其中:
- 第一维(3)表示:[x坐标, y坐标, 可见性]
- 第二维(14)对应14个关节点
- 第三维(2000)对应2000张图片
14个关节点的顺序如下:
| 索引 | 关节点名称 | 索引 | 关节点名称 |
|---|---|---|---|
| 0 | Right ankle | 7 | Right shoulder |
| 1 | Right knee | 8 | Left shoulder |
| 2 | Right hip | 9 | Left elbow |
| 3 | Left hip | 10 | Left wrist |
| 4 | Left knee | 11 | Neck |
| 5 | Left ankle | 12 | Head top |
| 6 | Right wrist |
3. 数据预处理与坐标转换
原始标注数据可能需要一些预处理才能用于实际应用。常见的处理包括:
- 坐标归一化 :将像素坐标转换为相对坐标
- 可见性过滤 :根据可见性标志过滤不可见关节点
- 镜像增强 :通过左右翻转生成更多训练样本
以下是坐标归一化的示例代码:
def normalize_joints(joints, img_width, img_height):
"""将关节点坐标归一化到[0,1]范围"""
normalized = joints.copy()
normalized[0, :, :] /= img_width # x坐标归一化
normalized[1, :, :] /= img_height # y坐标归一化
return normalized
注意:LSP数据集的图像尺寸不一,需要根据每张图片的实际尺寸分别处理。
4. 可视化关节点与骨架连接
可视化是理解数据集的关键步骤。我们可以使用OpenCV和Matplotlib来绘制关节点和骨架:
import cv2
import matplotlib.pyplot as plt
def visualize_pose(image_path, joints, save_path=None):
"""可视化单张图片的关节点"""
img = cv2.imread(image_path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
# 关节点连接关系(起点索引,终点索引)
skeleton = [
(0, 1), (1, 2), (2, 3), (3, 4), (4, 5), # 右腿到左腿
(6, 7), (7, 8), (8, 11), # 右手到颈部
(9, 10), (10, 11), # 左手到颈部
(11, 12) # 颈部到头顶
]
# 绘制骨架连接
for (i, j) in skeleton:
if joints[2, i] > 0 and joints[2, j] > 0: # 只绘制可见关节点
x1, y1 = joints[0, i], joints[1, i]
x2, y2 = joints[0, j], joints[1, j]
cv2.line(img, (int(x1), int(y1)), (int(x2), int(y2)), (255, 0, 0), 2)
# 绘制关节点
for i in range(joints.shape[1]):
if joints[2, i] > 0:
x, y = joints[0, i], joints[1, i]
cv2.circle(img, (int(x), int(y)), 3, (0, 0, 255), -1)
plt.figure(figsize=(10, 10))
plt.imshow(img)
plt.axis('off')
if save_path:
plt.savefig(save_path, bbox_inches='tight')
plt.show()
5. 批量处理与数据增强实战
实际项目中,我们通常需要批量处理整个数据集。下面是一个完整的处理流程示例:
import os
from tqdm import tqdm
def process_lsp_dataset(data_dir, output_dir):
"""批量处理LSP数据集"""
mat_path = os.path.join(data_dir, 'joints.mat')
images_dir = os.path.join(data_dir, 'images')
vis_dir = os.path.join(output_dir, 'visualizations')
os.makedirs(vis_dir, exist_ok=True)
joints = load_lsp_mat(mat_path)
image_files = sorted(os.listdir(images_dir))
for idx in tqdm(range(len(image_files))):
img_path = os.path.join(images_dir, image_files[idx])
img = cv2.imread(img_path)
h, w = img.shape[:2]
# 获取当前图片的关节点
current_joints = joints[:, :, idx]
# 可视化并保存
vis_path = os.path.join(vis_dir, f'vis_{image_files[idx]}')
visualize_pose(img_path, current_joints, vis_path)
为了提高数据利用率,可以考虑以下增强技术:
- 随机旋转 :小幅旋转图片和关节点
- 随机缩放 :改变图片尺寸
- 颜色抖动 :调整亮度、对比度
- 水平翻转 :交换左右关节点
def augment_pose(image, joints):
"""数据增强示例:水平翻转"""
flipped_img = cv2.flip(image, 1)
flipped_joints = joints.copy()
# 交换左右关节点
left_indices = [3, 4, 5, 8, 9, 10] # 左半身关节点索引
right_indices = [0, 1, 2, 7, 6] # 右半身关节点索引
# 更新x坐标(镜像)
flipped_joints[0, :] = image.shape[1] - joints[0, :]
# 交换左右关节点位置
for left, right in zip(left_indices, right_indices):
flipped_joints[:, [left, right]] = flipped_joints[:, [right, left]]
return flipped_img, flipped_joints
6. 实际应用中的注意事项
在使用LSP数据集进行模型训练时,有几个关键点需要注意:
- 数据分布 :LSP主要包含运动场景,可能不适用于其他姿态
- 标注质量 :部分标注可能存在误差,建议可视化检查
- 评估协议 :论文中常用的PCKh@0.5指标
- 与其他数据集的结合 :可以考虑与MPII等数据集联合训练
对于想进一步探索的开发者,可以尝试:
- 实现更复杂的数据增强策略
- 将LSP转换为COCO格式以便使用现有工具链
- 开发基于LSP的基准测试程序
- 研究跨数据集的迁移学习
def convert_to_coco_format(joints, image_info):
"""将LSP格式转换为COCO格式的示例"""
coco_keypoints = []
# COCO关键点顺序与LSP不同,需要重新映射
# 这里只是示例,实际转换需要更详细的处理
return coco_keypoints
处理这类数据集时,最常遇到的坑是坐标系的转换问题。特别是在结合不同库时(如OpenCV和Matplotlib的坐标系差异),需要格外小心。另一个常见问题是内存管理,当处理大量高分辨率图像时,合理的批处理策略至关重要。
更多推荐
所有评论(0)