/// <summary> /// returns arbNumber many 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, int arbNumber) { double xmin = pc.getxMin(); double xmax = pc.getxMax(); double zmin = pc.getzMin(); double zmax = pc.getzMax(); double[] limits = { xmin, zmin, xmax, zmax }; double ymin = pc.getyMin(); double ymax = pc.getyMax(); double increment = (ymax - ymin) / arbNumber; List<List<Point3D>> output = new List<List<Point3D>>(); for (double i = ymin + (increment / 2); i <= ymax - (increment / 2); i = i + increment) { List<Point3D> plane = pc.getKDTree().getAllPointsAt(i, increment / 2, limits); plane = SubSampler.averageSubSample(plane, sampleNumber); plane = PointSorter.clockSort(plane); output.Add(plane); } return Tuple.Create(output,increment); }
/// <summary> /// Returns the height of a point cloud in real world measurements, aka metres /// </summary> /// <param name="pc">PointCloud</param> /// <returns>double</returns> public static double getHeight(PointCloud pc) { double ymin = pc.getyMin(); double ymax = pc.getyMax(); double height = ymax - ymin; height = UnitConvertor.convertPCM(height,1); return height; }
public GroupVisualiser(PointCloud pc) { //Constructor 1: construct point cloud as a single entity. mesh = new MeshGeometry3D(); textureCoordinates = new Point[depthFrameHeight * depthFrameWidth]; //get all points from the point cloud prgbs = pc.getAllPoints(); //resize the depthframe array (for efficiency) depthFramePoints = new Point3D[prgbs.Length]; }
public List<Tuple<double, double, List<List<Point3D>>>> determineLimb(PointCloud pcdexisting, double weight) { //pull in skeleton measures from a temporary file for corbett.parse for now. kinectInterp = new KinectInterpreter(skeloutline); Dictionary<String, double[]> jointDepthsStr = new Dictionary<String, double[]>(); //temporary tuple for results Tuple<double, double, List<List<Point3D>>> T = new Tuple<double, double, List<List<Point3D>>>(0,0,null); //permanent list of tuples for passing back to coreLoader List<Tuple<double, double, List<List<Point3D>>>> limbMeasures = new List<Tuple<double,double,List<List<Point3D>>>>(); //Test if we have a kinect otherwise we cannot use coordinate mapper. if (KinectSensor.KinectSensors.Count > 0) { //test if we have already enumerated joint depths, if so, this has followed a recent scan. if (jointDepths.Count == 0) { StreamReader sr = new StreamReader("SKEL.ptemp"); String line; while ((line = sr.ReadLine()) != null) { String[] joint = Regex.Split(line, ":"); String[] positions = Regex.Split(joint[1], ","); double[] jointPos = { Convert.ToDouble(positions[0]), Convert.ToDouble(positions[1]), Convert.ToDouble(Regex.Split(positions[2], "\n")[0]) }; //convert to depth co-ordinate space SkeletonPoint sp = new SkeletonPoint(); sp.X = (float)Convert.ToDouble(jointPos[1]); sp.Y = (float)Convert.ToDouble(jointPos[2]); sp.Z = (float)Convert.ToDouble(jointPos[0]); CoordinateMapper cm = new CoordinateMapper(kinectInterp.kinectSensor); DepthImagePoint dm = cm.MapSkeletonPointToDepthPoint(sp, DepthImageFormat.Resolution640x480Fps30); //convert x and y co-ords to arbitrary point cloud space Tuple<double, double, double> convertedPoints = LimbCalculator.convertToPCCoords(dm.X, dm.Y, sp.Z); double[] jointPos2 = { convertedPoints.Item3, convertedPoints.Item1, convertedPoints.Item2 }; //place back into jointDepths array in terms of depth space. jointDepthsStr.Add(joint[0], jointPos2); } } else { //we have some live skeleton depths, enumerate into strings foreach(JointType j in jointDepths.Keys) { jointDepthsStr = new Dictionary<String, double[]>(); jointDepthsStr.Add(j.ToString(),jointDepths[j]); } } for (int limbArea = 1; limbArea <= 8; limbArea++) { //pass point cloud and correct bounds to Limb Calculator //shoulders is first option in list so pass first. limbMeasures.Add(LimbCalculator.calculateLimbBounds(pcdexisting, jointDepthsStr, limbArea, weight)); } } else { MessageBoxResult result = System.Windows.MessageBox.Show(this, "You need a Kinect to perform this action.", "Kinect Sensor Missing", MessageBoxButton.OK, MessageBoxImage.Stop); } //change colour of point cloud for limb selection mode gv.setMaterial(); this.DataContext = gv; return limbMeasures; }
public ScanLoader(PointCloud gcloud) { InitializeComponent(); System.Diagnostics.Debug.WriteLine("* * GLCLOUD SCANLOADER CALLED"); //wantKinect = false; // nathan changed this //hide buttons from form gv = new GroupVisualiser(gcloud); this.Loaded += new RoutedEventHandler(ScanLoader_Loaded); //Threading of data context population to speed up model generation. System.Diagnostics.Debug.WriteLine("Loading model"); this.Dispatcher.Invoke((Action)(() => { gv.preprocess(null); })); //Assigned threaded object result to the data context. this.DataContext = gv; gCloud = gcloud; this.hvpcanvas.MouseDown += new MouseButtonEventHandler(hvpcanvas_MouseDown); System.Diagnostics.Debug.WriteLine("Model loaded"); hitState = 0; }
/// <summary> /// Colours all the points in the point cloud based on specified RGB. Sets overall texture colour. /// </summary> /// <param name="r">r value</param> /// <param name="g">g value</param> /// <param name="g">b value</param> /// public PointCloud setColour(PointCloud pc, int r, int g, int b) { pc.setPoints(pc.rawDepth, r, g, b); return pc; }
//method for bernard public PointCloud getSubRegion(double[] points) { //check subregion is actually a sub region if (points[0] < this.minx) { throw new SubRegionOutOfBoundsException("xmin"); } if (points[1] < this.miny) { throw new SubRegionOutOfBoundsException("ymin"); } if (points[2] < this.minz) { throw new SubRegionOutOfBoundsException("zmin"); } if (points[3] > this.maxx) { throw new SubRegionOutOfBoundsException("xmax"); } if (points[4] > this.maxy) { throw new SubRegionOutOfBoundsException("ymax"); } if (points[5] > this.maxz) { throw new SubRegionOutOfBoundsException("zmax"); } double[] pointMin = { points[0], points[1], points[2] }; double[] pointMax = { points[3], points[4], points[5] }; System.Diagnostics.Debug.WriteLine("Limb Min: " + points[0] + " " + points[1] + " " + points[2]); System.Diagnostics.Debug.WriteLine("PC Min: " + this.minx + " " + this.miny + " " + this.minz); System.Diagnostics.Debug.WriteLine("Limb Max: " + points[3] + " " + points[4] + " " + points[5]); System.Diagnostics.Debug.WriteLine("PC Max: " + this.maxx + " " + this.maxy + " " + this.maxz); Object[] temp = this.points.range(pointMin, pointMax); List<Point3D> output = new List<Point3D>(); for (int i = 0; i < temp.Length; i++) { output.Add(((PointRGB)(temp[i])).point); } PointCloud pc = new PointCloud(output); System.Diagnostics.Debug.WriteLine(pc.getAllPoints().Length); return pc; }
/// <summary> /// Adds an existing point cloud into this point cloud /// </summary> /// <param name="pc">The point cloud to add</param> public void addPointCloud(PointCloud pc) { //retrieve the kd tree KdTree.KDTree kd = pc.getKDTree(); //define a max and min point //TODO: set these to proper max+min vals from the point cloud object double[] minPoint = new double[3] { -100, -100, -100 }; double[] maxPoint = new double[3] { 100, 100, 100 }; //retrieve a list of all item in the tree Object[] points2 = kd.range(minPoint, maxPoint); //iterate over every point and jam it in this point cloud foreach (Object element in points2) { //create k,v pair from data extracted PARSE.ICP.PointRGB value = (PARSE.ICP.PointRGB)element; double[] key = new double[3] {value.point.X, value.point.Y, value.point.Z}; //jam the data into the existing kd-tree int duplicates = 0; try { this.points.insert(key, value); } catch (KeyDuplicateException) { //ignore duplicates duplicates++; } //Console.WriteLine("There were " + duplicates + " duplicate keys in the tree"); } }
public GLLoader(PointCloud pcdl) { this.pcdl = pcdl; InitializeComponent(); this.Loaded += new RoutedEventHandler(GLLoader_Loaded); }
/// <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> /// 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)); }
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); }
/// <summary> /// sets values for pointcloud (stitching) and point cloud list (visualisation) /// </summary> /// <param name="pc">a point cloud</param> /// <param name="pcl">a list of point clouds</param> public void setPC(PointCloud pc, List <PointCloud> pcl) { this.pcd = pc; this.pcdl = pcl; filename = null; }
public List <Tuple <double, double, List <List <Point3D> > > > determineLimb(PointCloud pcdexisting, double weight) { //pull in skeleton measures from a temporary file for corbett.parse for now. kinectInterp = new KinectInterpreter(skeloutline); Dictionary <String, double[]> jointDepthsStr = new Dictionary <String, double[]>(); //temporary tuple for results Tuple <double, double, List <List <Point3D> > > T = new Tuple <double, double, List <List <Point3D> > >(0, 0, null); //permanent list of tuples for passing back to coreLoader List <Tuple <double, double, List <List <Point3D> > > > limbMeasures = new List <Tuple <double, double, List <List <Point3D> > > >(); //Test if we have a kinect otherwise we cannot use coordinate mapper. if (KinectSensor.KinectSensors.Count > 0) { //test if we have already enumerated joint depths, if so, this has followed a recent scan. if (jointDepths.Count == 0) { StreamReader sr = new StreamReader("SKEL.ptemp"); String line; while ((line = sr.ReadLine()) != null) { String[] joint = Regex.Split(line, ":"); String[] positions = Regex.Split(joint[1], ","); double[] jointPos = { Convert.ToDouble(positions[0]), Convert.ToDouble(positions[1]), Convert.ToDouble(Regex.Split(positions[2], "\n")[0]) }; //convert to depth co-ordinate space SkeletonPoint sp = new SkeletonPoint(); sp.X = (float)Convert.ToDouble(jointPos[1]); sp.Y = (float)Convert.ToDouble(jointPos[2]); sp.Z = (float)Convert.ToDouble(jointPos[0]); CoordinateMapper cm = new CoordinateMapper(kinectInterp.kinectSensor); DepthImagePoint dm = cm.MapSkeletonPointToDepthPoint(sp, DepthImageFormat.Resolution640x480Fps30); //convert x and y co-ords to arbitrary point cloud space Tuple <double, double, double> convertedPoints = LimbCalculator.convertToPCCoords(dm.X, dm.Y, sp.Z); double[] jointPos2 = { convertedPoints.Item3, convertedPoints.Item1, convertedPoints.Item2 }; //place back into jointDepths array in terms of depth space. jointDepthsStr.Add(joint[0], jointPos2); } } else { //we have some live skeleton depths, enumerate into strings foreach (JointType j in jointDepths.Keys) { jointDepthsStr = new Dictionary <String, double[]>(); jointDepthsStr.Add(j.ToString(), jointDepths[j]); } } for (int limbArea = 1; limbArea <= 8; limbArea++) { //pass point cloud and correct bounds to Limb Calculator //shoulders is first option in list so pass first. limbMeasures.Add(LimbCalculator.calculateLimbBounds(pcdexisting, jointDepthsStr, limbArea, weight)); } } else { MessageBoxResult result = System.Windows.MessageBox.Show(this, "You need a Kinect to perform this action.", "Kinect Sensor Missing", MessageBoxButton.OK, MessageBoxImage.Stop); } //change colour of point cloud for limb selection mode gv.setMaterial(); this.DataContext = gv; return(limbMeasures); }
private void pcTimer_tick(Object sender, EventArgs e) { if (countdown == 3) { //get current skeleton tracking state Skeleton skeleton = this.kinectInterp.getSkeletons(); jointDepths = enumerateSkeletonDepths(skeleton); //PointCloud structure methods PointCloud frontCloud = new PointCloud(this.kinectInterp.getRGBTexture(), this.kinectInterp.getDepthArray()); //frontCloud.deleteFloor(); fincloud.Add(frontCloud); sandra.Speak("Scan Added."); //freeze skelL skelDepth and skelR this.kinectInterp.kinectSensor.SkeletonStream.Disable(); tmpCanvas = skeloutline; skeloutline = tmpCanvas; skeloutline.Visibility = Visibility.Collapsed; sandra.Speak("Please turn left."); this.instructionblock.Text = "Please turn left"; countdown--; } else if (countdown == 2) { //PointCloud structure methods PointCloud rightCloud = new PointCloud(this.kinectInterp.getRGBTexture(), this.kinectInterp.getDepthArray()); //rightCloud.deleteFloor(); fincloud.Add(rightCloud); sandra.Speak("Scan Added."); sandra.Speak("Please turn left with your back to the camera."); this.instructionblock.Text = "Turn left with your back to the camera"; countdown--; } else if (countdown == 1) { //PointCloud structure methods PointCloud backCloud = new PointCloud(this.kinectInterp.getRGBTexture(), this.kinectInterp.getDepthArray()); //backCloud.deleteFloor(); fincloud.Add(backCloud); sandra.Speak("Scan Added."); sandra.Speak("Please turn left once more."); this.instructionblock.Text = "Please turn left once more."; countdown--; } else if (countdown == 0) { //PointCloud structure methods PointCloud leftCloud = new PointCloud(this.kinectInterp.getRGBTexture(), this.kinectInterp.getDepthArray()); //leftCloud.deleteFloor(); fincloud.Add(leftCloud); this.instructionblock.Text = "You have now been captured. Thank you for your time."; sandra.Speak("Scan Added."); sandra.Speak("You have now been captured. Thank you for your time."); //stop streams kinectInterp.stopStreams(); if ((((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).windowPatient.nameText.Text.CompareTo("Greg Corbett")) == 0) { CloudVisualisation fudge = ScanSerializer.deserialize("./Corbett.PARSE"); ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).setPC(null, ScanSerializer.depthPc); ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).LoadPointCloud(); //((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).fudge(); } else if (this.Owner is CoreLoader) { ((CoreLoader)(this.Owner)).setPC(pcd, fincloud); ((CoreLoader)(this.Owner)).LoadPointCloud(); ((CoreLoader)(this.Owner)).export1.IsEnabled = true; ((CoreLoader)(this.Owner)).export2.IsEnabled = true; ((CoreLoader)(this.Owner)).removefloor.IsEnabled = true; } else if (this.Owner is OptionLoader) { ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).setPC(pcd, fincloud); ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).LoadPointCloud(); ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).export1.IsEnabled = true; ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).export2.IsEnabled = true; ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).removefloor.IsEnabled = true; } /* * double height = Math.Round(HeightCalculator.getHeight(pcd), 3); * ((CoreLoader)(this.Owner)).windowHistory.heightoutput.Content = height + "m"; * * GroupVisualiser gg = new GroupVisualiser(fincloud); * gg.preprocess(null); * this.DataContext = gg; * * //Visualisation instantiation based on KDTree array clouds * this.instructionblock.Text = "Scanning complete."; * this.instructionblock.Visibility = Visibility.Collapsed; * * */ pcTimer.Stop(); this.Close(); //TODO: write all these results to the database; sql insertion clauses. } }
private void pcTimer_tick(Object sender, EventArgs e) { if (countdown == 3) { //get current skeleton tracking state Skeleton skeleton = this.kinectInterp.getSkeletons(); jointDepths = enumerateSkeletonDepths(skeleton); //PointCloud structure methods PointCloud frontCloud = new PointCloud(this.kinectInterp.getRGBTexture(), this.kinectInterp.getDepthArray()); //frontCloud.deleteFloor(); fincloud.Add(frontCloud); sandra.Speak("Scan Added."); //freeze skelL skelDepth and skelR this.kinectInterp.kinectSensor.SkeletonStream.Disable(); tmpCanvas = skeloutline; skeloutline = tmpCanvas; skeloutline.Visibility = Visibility.Collapsed; sandra.Speak("Please turn left."); this.instructionblock.Text = "Please turn left"; countdown--; } else if (countdown == 2) { //PointCloud structure methods PointCloud rightCloud = new PointCloud(this.kinectInterp.getRGBTexture(), this.kinectInterp.getDepthArray()); //rightCloud.deleteFloor(); fincloud.Add(rightCloud); sandra.Speak("Scan Added."); sandra.Speak("Please turn left with your back to the camera."); this.instructionblock.Text = "Turn left with your back to the camera"; countdown--; } else if (countdown == 1) { //PointCloud structure methods PointCloud backCloud = new PointCloud(this.kinectInterp.getRGBTexture(), this.kinectInterp.getDepthArray()); //backCloud.deleteFloor(); fincloud.Add(backCloud); sandra.Speak("Scan Added."); sandra.Speak("Please turn left once more."); this.instructionblock.Text = "Please turn left once more."; countdown--; } else if (countdown == 0) { //PointCloud structure methods PointCloud leftCloud = new PointCloud(this.kinectInterp.getRGBTexture(), this.kinectInterp.getDepthArray()); //leftCloud.deleteFloor(); fincloud.Add(leftCloud); this.instructionblock.Text = "You have now been captured. Thank you for your time."; sandra.Speak("Scan Added."); sandra.Speak("You have now been captured. Thank you for your time."); //stop streams kinectInterp.stopStreams(); if ((((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).windowPatient.nameText.Text.CompareTo("Greg Corbett")) == 0) { CloudVisualisation fudge = ScanSerializer.deserialize("./Corbett.PARSE"); ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).setPC(null, ScanSerializer.depthPc); ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).LoadPointCloud(); //((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).fudge(); } else if(this.Owner is CoreLoader) { ((CoreLoader)(this.Owner)).setPC(pcd, fincloud); ((CoreLoader)(this.Owner)).LoadPointCloud(); ((CoreLoader)(this.Owner)).export1.IsEnabled = true; ((CoreLoader)(this.Owner)).export2.IsEnabled = true; ((CoreLoader)(this.Owner)).removefloor.IsEnabled = true; } else if(this.Owner is OptionLoader) { ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).setPC(pcd, fincloud); ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).LoadPointCloud(); ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).export1.IsEnabled = true; ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).export2.IsEnabled = true; ((CoreLoader)((PatientLoader)((OptionLoader)(this.Owner)).Owner).Owner).removefloor.IsEnabled = true; } /* double height = Math.Round(HeightCalculator.getHeight(pcd), 3); ((CoreLoader)(this.Owner)).windowHistory.heightoutput.Content = height + "m"; GroupVisualiser gg = new GroupVisualiser(fincloud); gg.preprocess(null); this.DataContext = gg; //Visualisation instantiation based on KDTree array clouds this.instructionblock.Text = "Scanning complete."; this.instructionblock.Visibility = Visibility.Collapsed; */ pcTimer.Stop(); this.Close(); //TODO: write all these results to the database; sql insertion clauses. } }
/// <summary> /// Colours all the points in the point cloud based on specified RGB. Sets overall texture colour. /// </summary> /// <param name="r">r value</param> /// <param name="g">g value</param> /// <param name="g">b value</param> /// public PointCloud setColour(PointCloud pc, int r, int g, int b) { pc.setPoints(pc.rawDepth, r, g, b); return(pc); }
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)); }