
在生物力学中,会对运动员进行动作分析。由于比赛场地不允许带入分析设备,通常会使用两台(或多台)摄像机拍摄运动员的录像对运动员的动作进行三维解析。三维解析的过程比较繁琐,需要人工将人体的关节位置识别出。而在国内,分析运动员的动作是将少数的一两个运动员的解析数据进行比较,很少有多名运动员的数据进行统计分析和对比。原因是并没有统计三维解析的工具。但binyu的文章中有许多的测试对象,一方面是他们多年的积累,另一方面他们也更为脚踏实地。所以写一个对三维数据进行统计分析的程序,对于我国的运动员技术分析,应该有一定的作用;如果他们数据真实,并且脚踏实地分析的话。
> 我使用R语言处理分析解析三维坐标的代码
idea
- 从三维解析软件中提取各个帧的关节点三维坐标 → 生成txt → Encode=UTF-8
⬇️ - 读取路径下的所有txt格式数据,并根据各个文件名生成相同名称的dataframe
⬇️ - 计算速度
⬇️ - 计算角度
⬇️ - 人工进行每个运动员的阶段划分,铁饼为6个关键时刻T1-T6,5个时相F1-F5,保存为
phase.xlsx
⬇️ - 提取phase.xlsx中的阶段划分提取各个关键时刻的数据
⬇️ - 选取特定的数据进行作图,包括空间运动图和线图等
⬇️ - 使用运动员的关键数据进行统计分析,如T检验,建立回归方程等
function
定义拍摄频率
1
2#定义拍摄频率
fhz <- 60计算量点之间的距离 两点之间的距离通过空间坐标计算 公式为: \[ distansce=\sqrt{(x_2-x_1)^2+(y_2-y_1)^2+(z_2-z_1)^2} \] R语言实现
1
2
3
4
5# 求两点的距离
distance <- function(x,y){
l <- sqrt((y[1]-x[1])^2+(y[2]-x[2])^2+(y[3]-x[3])^2)
return(l)
}已知两个向量A,B,用distance(A,B)计算向量直线距离,返回距离值 例:
1
2> distance(c(1,3,2),c(3,4,6))
[1] 4.582576计算空间速度
提取运动员dataframe中的特定三个向量n,m,l; 每个向量包含每个时刻的三个坐标X,Y,Z; 行代表坐标,列代表不同的时刻。
\[
velocity=\sum_{i=2}^{i_{length}}\sqrt{(n_{[i-1]}-n_{[i+1]})^2+(m_{[i-1]}-m_{[i+1]})^2+(l_{[i-1]}-l_{[i+1]})^2} \bullet
fhz
\]
\(i\) 表示帧数,\(i_{length}\) 表示总共的帧数,\(fhz\) 表示拍摄频率 空间速度计算的是 \(i\) 帧前后两帧的平均速度,没有插值,从第二帧开始计算。没有第一帧的速度和最后一帧的速度。
R语言实现 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21vel <- function(n,m,l){
if (!is.numeric(n)&!is.numeric(m)&!is.numeric(l)){
stop("输入的n,m,l变量要数值型,大锅!")
}
# 验证变量是否为数值变量,如果不是报错
if ( !is.null(ncol(n)) && (ncol(n) > 1) ){
stop("需要连续的变量,大锅!")
}
# 验证变量是否有空变量,如果有报错
v <- c()
for (i in 2:length(n)-1)
{
v[i] <- c((sqrt((n[i-1]-n[i+1])^2+(m[i-1]-m[i+1])^2+(l[i-1]-l[i+1])^2))*fhz)
#acc <- diff(vel,differences = 2)
v[length(v)+1] <- 0
}
return(v)
rm(v)
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 > vel(no1tk57.91$discusX,no1tk57.91$discusY,no1tk57.91$discusZ)
[1] 0.0000000 6.9633613 6.7320428 6.4110218 6.1205882 5.8252554
[7] 5.5111886 5.0677806 4.4795535 3.8385935 3.2025615 2.6959970
[13] 2.2665392 1.9699746 1.7285832 1.4623269 1.0816654 0.7868926
[19] 0.9486833 1.5059880 2.1424285 2.6420447 2.9522195 3.2333265
[25] 3.5236912 3.8615023 4.4172390 5.0961162 5.8153590 6.4499302
[31] 6.8822380 7.1932468 7.4535361 7.6811718 7.8828675 8.0931082
[37] 8.1956574 8.3428053 8.5396253 8.8850661 9.2649015 9.5866783
[43] 9.9415492 10.2424411 10.4620457 10.5923369 10.7000374 10.8959075
[49] 11.3241159 11.8833329 12.1415156 12.0522363 11.8621077 11.7469826
[55] 12.0444676 12.7214150 13.3389055 13.5621237 13.2296939 12.4766823
[61] 11.5961545 11.1453129 11.3406349 11.8930232 12.3901090 12.6256881
[67] 12.6077119 12.4691780 12.2602773 12.1533699 12.1091536 12.1058829
[73] 12.1094509 11.9888949 11.9354765 12.0768539 12.5839898 13.3736756
[79] 14.2615848 14.9932785 15.3010588 15.2506262 15.0438559 14.7266697
[85] 14.4974205 14.4217336 14.5066054 14.7781596 15.2836383 15.9636086
[91] 16.4855937 16.5887793 16.2121066 15.5390733 14.9656406 14.8984966
[97] 15.3601172 16.2497015 17.3907907 18.8016489 20.5660011 22.3033809
[103] 23.6642008 24.8453617 26.5705175 29.4282721 33.3662584 37.9821326
[109] 42.0537941 44.6746237 45.5234357 44.7429056 43.0321322 41.1617930
[115] 39.6629500 38.6514114 38.0660636 37.3920366 35.9510167 33.1914447
[121] 29.2155643 24.6554010 20.8339147 0.0000000
- 计算空间夹角
运动员在空间中需要计算关节角度,或者环节与环节之间的夹角
用4个关节点形成两个空间向量,计算两个空间向量的夹角
已知,点\(A(x_a,y_a,z_a)B(x_b,y_b,z_b)\)和点\(C(x_c,y_c,z_c),D(x_d,y_d,z_d)\)
则:
\(\vec{ab}=(x_b-x_a,y_b-y_a,z_b-z_a)\)
\(\vec{cd}=(x_d-x_c,y_d-y_c,z_d-z_c)\)
向量的积:
\(\vec{ab}\bullet\vec{cd}=|ab|\bullet|cd|\bullet\cos\theta\)
\(\theta=\arccos\frac{\vec{ab}\bullet\vec{cd}}{|ab|\bullet|cd|}\)
向量的模:
\(|ab|=\sqrt{x_{ab}^2+y_{ab}^2+z_{ab}^2}\)
\(|cd|=\sqrt{x_{cd}^2+y_{cd}^2+z_{cd}^2}\)
向量的夹角
因为关节点数据是三维坐标数据,R中以dataframe的格式保存,所以每个点的数据在R中也是向量的数据结构(dataframe$point)
\[ \theta=\sum_{i=1}^{i_{length}}\arccos\frac{\vec{a_ib_i}\bullet\vec{c_id_i}}{|a_ib_i|\bullet|c_id_i|} \]
R语言实现
R中的求积与求模
1 | > a <- c(1,2,3) |
四个点,形成两个向量,通过向量计算角度
1
2
3
4
5
6
7angle <- function(a,b,c,d){
ab <- b-a
cd <- d-c
cj<-acos(sum(ab*cd)/sqrt(sum(ab^2)*sum(cd^2)))
cj <- rtod(cj)
return(cj)
}