pose-ai-core
v0.1.4
Published
Pose AI 核心引擎 - MediaPipe Pose 封装和 React UI 组件
Readme
@pose-ai/core
Pose AI 核心引擎包 - 基于 MediaPipe Pose 的姿态检测和 ROM 评估系统。
📦 安装
pnpm add @pose-ai/core🚀 快速开始
使用 ROMVisualizer 组件(推荐)
最简单的方式是使用 ROMVisualizer 组件,它包含了所有功能:
import { ROMVisualizer } from '@pose-ai/core'
function App() {
return (
<ROMVisualizer
width={640}
height={480}
showAnglePanel={true}
showROM={true}
/>
)
}使用 Hook 自定义 UI
如果需要自定义 UI,可以使用 usePoseEngine Hook:
import { usePoseEngine } from '@pose-ai/core'
import { useRef } from 'react'
function CustomPoseDetector() {
const videoRef = useRef<HTMLVideoElement>(null)
const { start, stop, isRunning, angles, romData, error } = usePoseEngine({
config: {
modelComplexity: 1,
minDetectionConfidence: 0.5,
},
onAngleUpdate: (angles) => {
console.log('角度更新:', angles)
},
})
const handleStart = async () => {
if (videoRef.current) {
await start(videoRef.current)
}
}
return (
<div>
<video ref={videoRef} autoPlay playsInline muted />
<button onClick={handleStart}>开始</button>
<button onClick={stop}>停止</button>
{angles.map((angle) => (
<div key={angle.name}>
{angle.name}: {angle.angle.toFixed(1)}°
</div>
))}
</div>
)
}使用底层引擎 API
对于更高级的用例,可以直接使用 PoseEngine:
import { PoseEngine } from '@pose-ai/core'
const engine = new PoseEngine(
{
modelComplexity: 1,
minDetectionConfidence: 0.5,
},
{
onAngleUpdate: (angles) => {
console.log('角度:', angles)
},
onROMUpdate: (romData) => {
console.log('ROM 数据:', romData)
},
}
)
await engine.initialize()
await engine.start(videoElement)
// 停止检测
engine.stop()
// 清理资源
engine.dispose()📖 API 文档
ROMVisualizer 组件
主可视化组件,包含视频预览、骨骼覆盖层和角度面板。
Props:
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| engineOptions | UsePoseEngineOptions | {} | 引擎配置选项 |
| width | number | 640 | 视频宽度 |
| height | number | 480 | 视频高度 |
| showAnglePanel | boolean | true | 是否显示角度面板 |
| showROM | boolean | true | 是否显示 ROM 数据 |
| drawingOptions | DrawingOptions | {} | 绘制选项 |
| className | string | '' | 自定义类名 |
| onStart | () => void | - | 开始检测回调 |
| onStop | () => void | - | 停止检测回调 |
AnglePanel 组件
角度数据展示面板。
Props:
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| angles | JointAngle[] | [] | 角度数据数组 |
| romData | ROMData[] | [] | ROM 数据数组 |
| showROM | boolean | false | 是否显示 ROM 信息 |
| className | string | '' | 自定义类名 |
SkeletonOverlay 组件
骨骼覆盖层,在视频上绘制姿态。
Props:
| 属性 | 类型 | 默认值 | 描述 |
|------|------|--------|------|
| results | Results \| null | null | MediaPipe 检测结果 |
| angles | JointAngle[] | [] | 角度数据 |
| width | number | 640 | Canvas 宽度 |
| height | number | 480 | Canvas 高度 |
| drawingOptions | DrawingOptions | {} | 绘制选项 |
| className | string | '' | 自定义类名 |
usePoseEngine Hook
React Hook,用于管理姿态检测引擎。
参数:
interface UsePoseEngineOptions {
config?: PoseEngineConfig
autoStart?: boolean
modelPath?: string
onResults?: (results: Results) => void
onAngleUpdate?: (angles: JointAngle[]) => void
onROMUpdate?: (romData: ROMData[]) => void
onError?: (error: Error) => void
}返回值:
interface UsePoseEngineReturn {
start: (videoElement: HTMLVideoElement) => Promise<void>
stop: () => void
processImage: (image: HTMLImageElement | HTMLCanvasElement) => Promise<void>
resetROM: (jointName?: string) => void
isRunning: boolean
angles: JointAngle[]
romData: ROMData[]
error: Error | null
engine: PoseEngine | null
}PoseEngine 类
底层姿态检测引擎。
方法:
initialize(modelPath?: string): Promise<void>- 初始化引擎start(videoElement: HTMLVideoElement): Promise<void>- 启动摄像头检测stop(): void- 停止检测processImage(image: HTMLImageElement | HTMLCanvasElement): Promise<void>- 处理单张图片setJointDefinitions(definitions: JointDefinition[]): void- 设置关节定义resetROM(jointName?: string): void- 重置 ROM 数据updateConfig(config: Partial<PoseEngineConfig>): void- 更新配置dispose(): void- 清理资源
配置选项
interface PoseEngineConfig {
modelComplexity?: 0 | 1 | 2 // 模型复杂度
smoothLandmarks?: boolean // 平滑关键点
enableSegmentation?: boolean // 启用分割
smoothSegmentation?: boolean // 平滑分割
minDetectionConfidence?: number // 最小检测置信度
minTrackingConfidence?: number // 最小追踪置信度
}绘制选项
interface DrawingOptions {
showLandmarks?: boolean // 显示关键点
showConnections?: boolean // 显示连接线
showAngles?: boolean // 显示角度
landmarkColor?: string // 关键点颜色
connectionColor?: string // 连接线颜色
angleColor?: string // 角度颜色
landmarkRadius?: number // 关键点半径
lineWidth?: number // 线宽
}🎯 预定义关节
系统预定义了 8 个常用关节:
left_elbow- 左肘关节right_elbow- 右肘关节left_shoulder- 左肩关节right_shoulder- 右肩关节left_hip- 左髋关节right_hip- 右髋关节left_knee- 左膝关节right_knee- 右膝关节
自定义关节
import { PoseLandmarkIndex } from '@pose-ai/core'
const customJoints = [
{
name: 'custom_joint',
points: [
PoseLandmarkIndex.LEFT_SHOULDER,
PoseLandmarkIndex.LEFT_ELBOW,
PoseLandmarkIndex.LEFT_WRIST,
],
description: '自定义关节',
},
]
engine.setJointDefinitions(customJoints)🎨 样式自定义
所有组件都支持通过 className 属性添加自定义样式:
<ROMVisualizer
className="my-custom-visualizer"
drawingOptions={{
landmarkColor: '#FF0000',
connectionColor: '#00FF00',
angleColor: '#0000FF',
lineWidth: 3,
}}
/>📊 数据类型
JointAngle
interface JointAngle {
name: string // 关节名称
angle: number // 角度值(度)
points: [number, number, number] // 三个关键点索引
timestamp: number // 时间戳
}ROMData
interface ROMData {
jointName: string // 关节名称
currentAngle: number // 当前角度
minAngle: number // 最小角度
maxAngle: number // 最大角度
range: number // 运动范围
timestamp: number // 时间戳
}🔧 高级用法
事件监听
const eventBus = engine.getEventBus()
// 监听角度更新
const unsubscribe = eventBus.on('angle-updated', (event) => {
console.log('角度更新:', event.data)
})
// 取消监听
unsubscribe()图片处理
const image = document.getElementById('myImage') as HTMLImageElement
await engine.processImage(image)重置 ROM 数据
// 重置所有关节的 ROM 数据
engine.resetROM()
// 重置特定关节
engine.resetROM('left_elbow')📝 注意事项
- 摄像头权限: 使用前需要用户授权摄像头权限
- HTTPS: 在生产环境中必须使用 HTTPS
- 性能:
modelComplexity越高,精度越高但性能越低 - 资源清理: 组件卸载时会自动清理资源
📄 License
MIT
