/// <summary> /// calculates all limbs as defined by limb calculator /// </summary> /// <param name="sender">the object</param> /// <param name="e">the routed event</param> private void LimbOption_Click(object sender, RoutedEventArgs e) { /*Create an array of type tuple<double,double,List<List<Point3D>>> * as limbs will all be calculated before displaying history loader * results, not partic. efficient but fine given the restriction.*/ //gets all the planes by calling volume calculator //kinect sensor check is here, can't use coord mapper otherwise. if (KinectSensor.KinectSensors.Count > 0) { Tuple <List <List <Point3D> >, double> T = PlanePuller.pullAll(pcd); List <List <Point3D> > planes = T.Item1; /*Requires generated model, raw depth array and previous*/ List <Tuple <double, double, List <List <Point3D> > > > result = windowScanner.determineLimb(pcd, VolumeCalculator.calculateApproxWeight(volume)); if (windowHistory == null) { windowHistory = new HistoryLoader(); windowHistory.Owner = this; windowHistory.history.Visibility = Visibility.Collapsed; System.Diagnostics.Debug.WriteLine("History loader was null, now set."); } windowHistory.limbcircum.Visibility = Visibility.Visible; windowHistory.history.Visibility = Visibility.Visible; windowHistory.runtimeTab.SelectedIndex = 1; windowHistory.Show(); windowHistory.visualiseLimbs(result, 1, 1); } else { MessageBoxResult result = System.Windows.MessageBox.Show(this, "You need a Kinect to perform this action.", "Kinect Sensor Missing", MessageBoxButton.OK, MessageBoxImage.Stop); } }
/// <summary> /// returns an arbitary number (60) of planes, sliced height wise, which have been averaged, subsampled and clock sorted. /// </summary> /// <param name="pc">PointCloud</param> /// <param name="arbNumber">int</param> /// <returns>Tuple(List(List(Point3D)),double)</returns> public static Tuple <List <List <Point3D> >, double> pullAll(PointCloud pc) { return(PlanePuller.pullAll(pc, planeNumber)); }
/// <summary> /// runs the volume calculation subroutine on an open point cloud/patient /// </summary> /// <param name="sender">the object</param> /// <param name="e">the routed event</param> private void VolumeOption_Click(object sender, RoutedEventArgs e) { //Static call to volume calculation method, pass persistent point cloud object if (windowHistory == null) { windowHistory = new HistoryLoader(); windowHistory.Owner = this; windowHistory.history.Visibility = Visibility.Collapsed; System.Diagnostics.Debug.WriteLine("History loader was null, now set."); } windowHistory.limbcircum.Visibility = Visibility.Collapsed; Tuple <List <List <Point3D> >, double> T = PlanePuller.pullAll(pcd); List <List <Point3D> > planes = T.Item1; double increment = T.Item2; volume = VolumeCalculator.volume1stApprox(planes, increment); volume = Math.Round(volume, 4); List <double> areaList = AreaCalculator.getAllAreas(planes); windowHistory.areaList = areaList; windowHistory.runtimeTab.SelectedIndex = 0; windowHistory.visualisePlanes(planes, 1); windowHistory.voloutput.Content = volume + "m\u00B3"; windowHistory.heightoutput.Content = HeightCalculator.getHeight(pcd) + "m"; windowHistory.scantime.Content = "Weight (Est): " + VolumeCalculator.calculateApproxWeight(volume) + "kg"; windowHistory.scanfileref.Content = "BMI Measure: " + VolumeCalculator.calculateBMI(HeightCalculator.getHeight(pcd), VolumeCalculator.calculateApproxWeight(volume)); windowHistory.scanvoxel.Content = "Siri (%BF): " + VolumeCalculator.calculateSiri(volume, VolumeCalculator.calculateApproxWeight(volume), HeightCalculator.getHeight(pcd)) + "%"; //show Runtime viewer (aka results,history) windowHistory.Show(); List <Tuple <DateTime, double> > records = this.getTimeStampsAndVals((int)Convert.ToInt64(windowPatient.patientIDExisting.Content)); int historyLookBack = 5; if ((records != null) && (records.Count > 0)) { int size = Math.Min(records.Count, historyLookBack); KeyValuePair <DateTime, double>[] records2 = new KeyValuePair <DateTime, double> [size]; for (int i = 0; i < size; i++) { records2[i] = new KeyValuePair <DateTime, double>(records[i].Item1, records[i].Item2); } //set change in volume... may need refinement if (size != 0) { double change = 0; change = (volume - records[records.Count - 1].Item2) / records[records.Count - 1].Item2;//may need to become records[records.Count-2].Item2 later windowHistory.volchangeoutput.Content = Math.Round(100 * change, 2) + "%"; } else { windowHistory.volchangeoutput.Content = "Not Enough Data"; windowHistory.volchart.Visibility = Visibility.Collapsed; } //setData ((LineSeries)(windowHistory.volchart.Series[0])).ItemsSource = records2; } else { windowHistory.volchangeoutput.Content = "Not Enough Data"; windowHistory.volchart.Visibility = Visibility.Collapsed; } }
public static Tuple <double, double, List <List <Point3D> > > calculateLimbBounds(PointCloud pc, Dictionary <String, double[]> jointDepths, int limb, double weight) { //Calculate limb bounds based on limb choice double finalCircum = 0.0; double numPlanes = 0.0; Tuple <List <List <Point3D> >, double> T = new Tuple <List <List <Point3D> >, double>(null, 0); //premodify limb circum factors with discovered weight if (weight < 60) { ArmFactorL = 1.21; LegFactorL = 3.89; ArmFactorR = 1.02; LegFactorR = 2.96; ChestFactor = 1.62; ShoulderFactor = 1.43; WaistFactor = 6.63; } else if (weight >= 60 && weight < 90) { ArmFactorL = 1.07; LegFactorL = 3.10; ArmFactorR = 1.05; LegFactorR = 2.95; ChestFactor = 1.42; ShoulderFactor = 1.41; WaistFactor = 5.94; } else if (weight >= 90) { ArmFactorL = 0.91; LegFactorL = 3.39; ArmFactorR = 0.89; LegFactorR = 3.51; ChestFactor = 1.46; ShoulderFactor = 1.53; WaistFactor = 4.529; } switch (limb) { case 1: //SHOULDERS (1) xmin = jointDepths["ShoulderRight"][1]; xmax = jointDepths["ShoulderLeft"][1]; ymax = jointDepths["ShoulderCenter"][2]; ymin = jointDepths["Spine"][2]; zmin = pc.getzMin(); zmax = pc.getzMax(); bounds = new double[] { xmin, ymin, zmin, xmax, ymax, zmax }; premodifier = ShoulderFactor; //translate bounds according to pointcloud data points System.Diagnostics.Debug.WriteLine("Bounds:" + xmin + ", " + ymin + ", " + zmin + ", " + xmax + ", " + ymax + ", " + zmax); break; case 2: //ARM_LEFT (2) xmin = jointDepths["HipLeft"][1]; xmax = jointDepths["WristLeft"][1] + ((jointDepths["WristLeft"][1] - jointDepths["HipLeft"][1]) / 4); ymax = jointDepths["ShoulderLeft"][2]; ymin = jointDepths["WristLeft"][2]; zmin = pc.getzMin(); zmax = pc.getzMax(); bounds = new double[] { xmin, ymin, zmin, xmax, ymax, zmax }; //translate bounds according to pointcloud data points premodifier = ArmFactorL; System.Diagnostics.Debug.WriteLine("Bounds:" + xmin + ", " + ymin + ", " + zmin + ", " + xmax + ", " + ymax + ", " + zmax); break; case 3: //ARM_RIGHT (3) xmin = jointDepths["WristRight"][1] - ((jointDepths["HipRight"][1] - jointDepths["WristRight"][1]) / 4); xmax = jointDepths["HipRight"][1]; ymax = jointDepths["ShoulderRight"][2]; ymin = jointDepths["WristRight"][2]; zmin = pc.getzMin(); zmax = pc.getzMax(); bounds = new double[] { xmin, ymin, zmin, xmax, ymax, zmax }; //translate bounds according to pointcloud data points System.Diagnostics.Debug.WriteLine("Bounds:" + xmin + ", " + ymin + ", " + zmin + ", " + xmax + ", " + ymax + ", " + zmax); premodifier = ArmFactorR; break; case 4: //CHEST(4) xmin = jointDepths["ShoulderRight"][1]; xmax = jointDepths["ShoulderLeft"][1]; ymax = jointDepths["ShoulderCenter"][2]; ymin = jointDepths["Spine"][2]; zmin = pc.getzMin(); zmax = pc.getzMax(); bounds = new double[] { xmin, ymin, zmin, xmax, ymax, zmax }; //translate bounds according to pointcloud data points System.Diagnostics.Debug.WriteLine("Bounds:" + xmin + ", " + ymin + ", " + zmin + ", " + xmax + ", " + ymax + ", " + zmax); premodifier = ChestFactor; break; case 5: //WAIST(5) xmin = jointDepths["HipRight"][1]; xmax = jointDepths["HipLeft"][1]; ymax = jointDepths["HipCenter"][2]; ymin = jointDepths["HipLeft"][2]; zmin = pc.getzMin(); zmax = pc.getzMax(); bounds = new double[] { xmin, ymin, zmin, xmax, ymax, zmax }; //translate bounds according to pointcloud data points System.Diagnostics.Debug.WriteLine("Bounds:" + xmin + ", " + ymin + ", " + zmin + ", " + xmax + ", " + ymax + ", " + zmax); premodifier = WaistFactor; break; case 6: //LEFT_LEG(6) xmin = jointDepths["HipCenter"][1]; xmax = jointDepths["HipLeft"][1]; ymax = jointDepths["HipLeft"][2]; ymin = jointDepths["KneeLeft"][2]; zmin = pc.getzMin(); zmax = pc.getzMax(); bounds = new double[] { xmin, ymin, zmin, xmax, ymax, zmax }; //translate bounds according to pointcloud data points System.Diagnostics.Debug.WriteLine("Bounds:" + xmin + ", " + ymin + ", " + zmin + ", " + xmax + ", " + ymax + ", " + zmax); premodifier = LegFactorL; break; case 7: //RIGHT_LEG(7) xmin = jointDepths["HipRight"][1]; xmax = jointDepths["HipCenter"][1]; ymax = jointDepths["HipRight"][2]; ymin = jointDepths["KneeRight"][2]; zmin = pc.getzMin(); zmax = pc.getzMax(); bounds = new double[] { xmin, ymin, zmin, xmax, ymax, zmax }; //translate bounds according to pointcloud data points System.Diagnostics.Debug.WriteLine("Bounds:" + xmin + ", " + ymin + ", " + zmin + ", " + xmax + ", " + ymax + ", " + zmax); premodifier = LegFactorR; break; default: break; } try { //Calculate circumference segmentedPointcloud = pc.getSubRegion(bounds); T = PlanePuller.pullAll(segmentedPointcloud, 2); finalCircum = CircumferenceCalculator.calculate(T.Item1, 1); numPlanes = UnitConvertor.convertPCM(T.Item2, 1); //Premodify the circumference calculation with the fudge factors. Convert into CM from M. finalCircum = Math.Round(finalCircum * 100, 5); finalCircum = premodifier * finalCircum; } catch (Exception err) { System.Diagnostics.Debug.WriteLine("(Subregion): Subregion issue - " + err.ToString()); } //results printed out before historyloader so we can inspect all is well System.Diagnostics.Debug.WriteLine("***Limb Circumference Results***"); System.Diagnostics.Debug.WriteLine("Limb chosen: " + limb); System.Diagnostics.Debug.WriteLine("Circumference approx: " + finalCircum); System.Diagnostics.Debug.WriteLine("Number of planes: " + numPlanes); return(new Tuple <double, double, List <List <Point3D> > >(finalCircum, numPlanes, T.Item1)); }