我需要开发一个应用程序,用户(物理治疗师)将在Kinect前面进行动作,我将把该动作数据写入数据库,然后患者将尝试模仿这个动作。系统会计算记录的动作和执行的动作之间的相似度。
我的第一个想法是在记录时(例如每5秒),存储点的位置(x、y、z),然后在执行时间(由患者执行时)进行比较。
我知道这种方法过于简单,因为我想象中不同大小的人的骨架被识别的方式也不同,所以比较结果不可靠。
我的问题是如何最好地比较保存的动作和执行时的动作。
至于比较,请像这样操作
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乘以0.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");
}
whereItIs * (whereYouWantItToBe / whereItIs)
。 - Liam McInroy