/// <summary> /// Generates the point cloud /// </summary> /// <param name="df">The Depth Frame from the Kinect sensor</param> /// <param name="bif">The Body Index Frame from the Kinect sensor</param> /// <returns>The PointCloud generated from the frames</returns> public PointCloud generate(DepthFrame df, BodyIndexFrame bif) { Log.Write("Creating point Cloud"); /* * used to calculate centroid, as well as lowest x value for later on -> * saves us looping later, though PointCloud methods do allow you to do that */ double xAccumulator = 0.0, yAccumulator = 0.0, zAccumulator = 0.0, xMean = 0.0, yMean = 0.0, zMean = 0.0, xMinimum = (1 / 0.0); int depthFrameWidth = df.FrameDescription.Width; int depthFrameHeight = df.FrameDescription.Height; this.depthFrameData = new ushort[depthFrameWidth * depthFrameHeight]; this.bodyIndexFrameData = new byte[depthFrameWidth * depthFrameHeight]; this.cameraPoints = new CameraSpacePoint[depthFrameWidth * depthFrameHeight]; df.CopyFrameDataToArray(depthFrameData); bif.CopyFrameDataToArray(bodyIndexFrameData); coordinateMapper.MapDepthFrameToCameraSpace(depthFrameData, cameraPoints); // Create new point cloud for storing points and operating on later PointCloud pointCloud = new PointCloud(); int numberOfPoints = 0; // loop over each row and column of the depth for (int y = 0; y < depthFrameHeight; y++) { for (int x = 0; x < depthFrameWidth; x++) { // calculate index into depth array int depthIndex = (y * depthFrameWidth) + x; byte humanPoint = bodyIndexFrameData[depthIndex]; if (humanPoint == 0xff) // Check if human point empty { continue; } CameraSpacePoint p = this.cameraPoints[depthIndex]; if (!(Double.IsInfinity(p.X)) && !(Double.IsInfinity(p.Y)) && !(Double.IsInfinity(p.Z))) { if (p.X < depthLimit && p.Y < depthLimit && p.Z < depthLimit) { Point3D scaledPoint = new Point3D(p.X * unitScale, p.Y * unitScale, p.Z * unitScale); pointCloud.addPoint(scaledPoint); xAccumulator += scaledPoint.X; yAccumulator += scaledPoint.Y; zAccumulator += scaledPoint.Z; numberOfPoints++; if (scaledPoint.X < xMinimum) { xMinimum = scaledPoint.X; } } } } // end of for(int x..) loop over points } // end of for(int y..) loop over points xMean = xAccumulator / numberOfPoints; yMean = yAccumulator / numberOfPoints; zMean = zAccumulator / numberOfPoints; // centroid calculated on the fly so we don't have to loop again unnecessarily Point3D centroid = new Point3D(xMean, yMean, zMean); pointCloud.subtractFromPointAxis(xMinimum, 0); pointCloud.rotateOnSpot(180, PointCloud.Axis.Y, centroid); Log.Write("Finished calculating point cloud"); return(pointCloud); }