我需要开发一个应用程序,其中用户(物理治疗师)将在Kinect前面执行移动,我将在数据库中写入数据移动,然后患者将尝试模仿此动作。系统将计算记录和执行的运动之间的相似性。
我的第一个想法是,在录制过程中(每5秒,例如),存储点的位置(x,y,z),然后在执行时间(按患者)比较它们。
我知道这种方法太简单了,因为我想在不同大小的人中,骨架的识别方式不同,所以比较不可靠。
我的问题是将保存的动作与执行的动作(即时)进行比较的最佳方法。
答案 0 :(得分:7)
我已经这样做了,医生框架被投射到患者框架上,但由于骨骼高度不同,整个骨架不能很好地工作:/。代码可以找到here。 它是beta 2代码,可以找到更新的版本here,虽然它目前无法正常运行
至于比较,做这样的事情
for (int i = 0; i < patientList.Count; i++)
{
int diff = (int)Math.Abs(patientList[i] - doctorList[i]);
if (diff < 100) //or whatever number you want
{
Debug.WriteLine("Good Job");
}
}
由于Fixus提到的骨骼高度,我已经放弃了整个人物的想法,所以我当前的程序看起来像是:
修改强>
这是用kinect扼杀两个动作的概念,并计算我深入解释的两个动作之间的相似性。
假设我有以下2点,点A(0,0,0)和点B(1,1,1)。现在我想找到从A点到B点的差异,所以我会减去所有的X,Y和Z数,所以差值是1 X 1 Y 1 Z.这就是简单的东西。现在来实现它。我上面写的代码我会像这样实现。
//get patient hand coordinates
double patienthandX = Canvas.GetLeft(patienthand);
double patienthandY = Canvas.GetTop(patienthand);
//get doctor hand coordinates
double doctorhandX = Canvas.GetLeft(doctorhand);
double doctorhandY = Canvas.GetTop(doctorhand);
//compare difference for each x and y
//take Absolute value so that it is positive
double diffhandX = Math.Abs(patienthandX - doctorhandX);
double diffhandY = Math.Abs(patienthandY - doctorhandY);
现在又出现了另一个问题。医生的坐标总是一样的,但如果患者没有站在医生坐标记录的位置怎么办?现在我们实现更简单的数学。举个简单的例子吧。假设我想要点A(8,2)移动到B点(4,12)。你将A的x和y乘以得到B.所以我将X乘以.5,将Y乘以6.所以对于Kinect,我会在患者臀部放一个元素,然后将其与医生臀部进行比较。然后将医生关节的全部乘以该数字,以实现患者顶部的医生关节(或多或少)。例如
double whatToMultiplyX = (double) doctorhipX / patienthipX;
double whatToMultiplyY = (double) doctorhipY / patienthipY;
这一切都非常简单,但把它放在一起是更难的部分。到目前为止,我们1)在患者框架上绘制医生框架,2)计算差异。 3)比较整个代表的差异。 4)重置下一个代表。这似乎很简单,但事实并非如此。要计算代表的整个差异,请执行以下操作:
//get patient hand coordinates
double patienthandX = Canvas.GetLeft(patienthand);
double patienthandY = Canvas.GetTop(patienthand);
//get doctor hand coordinates
double doctorhandX = Canvas.GetLeft(doctorhand);
double doctorhandY = Canvas.GetTop(doctorhand);
//compare difference for each x and y
//take Absolute value so that it is positive
double diffhandX = Math.Abs(patienthandX - doctorhandX);
double diffhandY = Math.Abs(patienthandY - doctrorhandY);
//+= so that it keeps adding to it.
totaldiffhandX += diffhandX;
totaldiffhandY += diffhandY;
现在我们可以比较,并说:
if (totaldiffhandX < 1000 && totaldiffhandY < 1000) //keep numbers pretty high since it is an entire rep
{
//reset difference
totaldiffhandX = 0;
totaldiffhandY = 0;
//tell the patient good job
Debug.WriteLine("Good Job");
}
这很简单,但请记住,必须为每个关节的x和y 执行此操作。否则它将无法工作。希望这有助于。
答案 1 :(得分:4)
首先要记住人们不同。每个人都有不同的身高,宽度,体重,不同的骨骼长度等等。
你的代码可能永远不会起作用。
其次,您需要更多地考虑几何。不要只考虑点数,用向量来思考它们的方向。每个动作在某些方向上都是一些向量的移动。 然后比例。您需要为每个用户配置应用程序。
你有一些模式。模式是你的物理治疗师。你不仅要记住他的动作,还要记住他的身体。手臂长度,腿长,距离等。每个将使用您的应用程序的用户也需要我测量。拥有所有这些数据后,您可以通过缩放尺寸和比较移动方向来比较移动
当然记住,有一些非常简单的动作,例如。通过检查手的实际位置和检查运动方向,可以通过简单的数学识别它们。你需要这3个控制点而且你在家里:)
手势识别不是一件简单的事情