我已经使用Microsoft Kinect设备获得了人的肩膀,肘部和手腕的坐标(数据是针对Kinect设备获取的)。
在获取坐标时,我上下移动了手臂。样本数据集可以显示如下。

7/7/2015 12:02:49 AM shoulder X -0.06475954 shoulder Y 0.266225 shoulder Z 1.414332 elbow X 0.002287441 elbow Y 0.03676218 elbow Z 1.424792 wrist X 0.1791002 wrist Y -0.06900118 wrist Z 1.455758

7/7/2015 12:02:49 AM shoulder X -0.06655618 shoulder Y 0.2654685 shoulder Z 1.413007 elbow X 0.001183244 elbow Y 0.0374795 elbow Z 1.424512 wrist X 0.1779053 wrist Y -0.06793896 wrist Z 1.4554

7/7/2015 12:02:49 AM shoulder X -0.0703955 shoulder Y 0.264899 shoulder Z 1.408783 elbow X -0.001478138 elbow Y 0.03802216 elbow Z 1.422277 wrist X 0.1769906 wrist Y -0.06481737 wrist Z 1.4514


然后,我尝试在两种情况下计算手臂的角度。


假设Z坐标是固定的(实际上是在数据集之上,采用这种假设是正确的)
假设Z坐标不固定。


我使用Java代码在以上两个条件下计算角度。
Java代码如下。

import java.io.*;

class main {

    public static void main(String args[]){
        try{
            FileInputStream fstream = new FileInputStream("C:\\Users\\Chathu\\Desktop\\project code\\src\\output.txt");
            DataInputStream in = new DataInputStream(fstream);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String strLine;
            while ((strLine = br.readLine()) != null)   {
                String[] tokens = strLine.split(" ");

                //time

                //shoulder cordinates
                double ShoulderX= Double.parseDouble(tokens[5]);
                double ShoulderY= Double.parseDouble(tokens[8]);
                double ShoulderZ= Double.parseDouble(tokens[11]);


                //elbow cordinates
                double ElbowX= Double.parseDouble(tokens[14]);
                double ElbowY= Double.parseDouble(tokens[17]);
                double ElbowZ= Double.parseDouble(tokens[20]);


                //wrist cordinates
                double WristX= Double.parseDouble(tokens[23]);
                double WristY= Double.parseDouble(tokens[26]);
                double WristZ= Double.parseDouble(tokens[29]);



                //calculate angle if Z is fixed

                double M1=((ShoulderY-ElbowY)/(ShoulderX-ElbowX));
                double M2=((WristY-ElbowY)/(WristX-ElbowX));

                double tanAlfa=Math.abs((M1-M2)/(1+(M1*M2)));

                System.out.println("Time : "+getTimeinInt(tokens[1]));
                System.out.println("2D angle: "+Math.toDegrees(Math.atan(tanAlfa)));



                //calculate andgle when Z is not fixed

                //Create 2 vectors
                double[] u={ShoulderX-ElbowX,ShoulderY-ElbowY,ShoulderZ-ElbowZ };
                double[] v={WristX-ElbowX,WristY-ElbowY,WristZ-ElbowZ };

                double absu=Math.sqrt(Math.pow(u[0],2)+Math.pow(u[1],2)+Math.pow(u[2],2));
                double absv=Math.sqrt(Math.pow(v[0],2)+Math.pow(v[1],2)+Math.pow(v[2],2));

                double cosTheata=((dotProd(u,v))/(absu*absv));

                System.out.println("3D angle: "+Math.acos(cosTheata));


            }
            in.close();
        }catch (Exception e){
            System.err.println("Error: " + e.getMessage());
        }
    }



    public static int getTimeinInt(String time){

        String[] tokens = time.split(":");
        int hours = Integer.parseInt(tokens[0]);
        int minutes = Integer.parseInt(tokens[1]);
        int seconds = Integer.parseInt(tokens[2]);
        int duration = 3600 * hours + 60 * minutes + seconds;

        return duration;
    }

    public static double dotProd(double[] a, double[] b){
        if(a.length != b.length){
            throw new IllegalArgumentException("The dimensions have to be equal!");
        }
        double sum = 0;
        for(int i = 0; i < a.length; i++){
            sum += a[i] * b[i];
        }
        return sum;
    }
}


但是,当我运行此代码并检查计算出的角度值时,在上述两个假设下,我得到的值完全不同。

前三个答案如下(答案对应于上述样本数据集)

Time : 43369
2D angle: 42.82568606638748
3D angle: 2.3907040436551847
Time : 43369
2D angle: 42.63544266854971
3D angle: 2.3947689168198463
Time : 43369
2D angle: 43.151072486090776
3D angle: 2.387883634441205


谁能帮我找到问题所在?

最佳答案

您可以使用余弦找到2条线之间的角度。


wrist = point1
elbo = point2
soulder = point3

vector1 = point1 - point2
vector2 = point1 - point3


现在,您有了从肘部分别指向手腕和肩膀的向量1和2,可以通过以下方法找到角度:

这两个向量的点积与其大小乘积之比的arccos。

有关数学的更多信息,请参见This page on Wikipedia

您拥有“ 3d角度...”的功能

您不能使用atan方法,因为您的肘部角度不是90度。
如果您知道那是为什么要寻找它?

我真的不确定“二维角度...”到底要做什么。

08-07 14:37
查看更多