/// <summary> /// Initializes a new instance of the <see cref="DepthImage"/> class. /// </summary> /// <param name="bitmapData">Locked bitmap data.</param> /// <param name="depthValueSemantics">Optional depth value semantics.</param> /// <param name="depthValueToMetersScaleFactor">Optional scale factor to convert from depth values to meters.</param> /// <param name="makeCopy">Indicates whether a copy is made (default is false).</param> /// <remarks> /// <para>When the <paramref name="makeCopy"/> parameter is false (default), the depth image simply wraps /// the bitmap data. As such, the bitmap data must stay locked for the duration of using the <see cref="DepthImage"/> object. /// </para> /// <para>If the <paramref name="makeCopy"/> parameter is set to true, a copy of the bitmap /// data is made, and the bitmap data can be released right after the <see cref="DepthImage"/> has been constructed. /// </para> /// </remarks> public DepthImage(BitmapData bitmapData, DepthValueSemantics depthValueSemantics = DepthValueSemantics.DistanceToPlane, double depthValueToMetersScaleFactor = 0.001, bool makeCopy = false) : base(bitmapData, makeCopy) { CheckPixelFormat(bitmapData.PixelFormat); this.depthValueSemantics = depthValueSemantics; this.depthValueToMetersScaleFactor = depthValueToMetersScaleFactor; }
/// <inheritdoc/> public Point3D[,] GetPixelToCameraSpaceMapping(DepthValueSemantics depthValueSemantics, bool undistort) { var result = new Point3D[this.ImageWidth, this.ImageHeight]; for (int i = 0; i < this.ImageWidth; i++) { for (int j = 0; j < this.ImageHeight; j++) { // Convert from pixel coordinates to NDC var tmp = new Point3D(i, j, 1.0); tmp = tmp.TransformBy(this.InvTransform); // Distort the pixel var pixelPoint2D = new Point2D(tmp.X, tmp.Y); if (undistort) { this.TryUndistortPoint(pixelPoint2D, out pixelPoint2D); } if (depthValueSemantics == DepthValueSemantics.DistanceToPoint) { double norm = Math.Sqrt(pixelPoint2D.X * pixelPoint2D.X + pixelPoint2D.Y * pixelPoint2D.Y + 1); result[i, j] = new Point3D(1 / norm, -pixelPoint2D.X / norm, -pixelPoint2D.Y / norm); } else { result[i, j] = new Point3D(1, -pixelPoint2D.X, -pixelPoint2D.Y); } } } return(result); }
/// <summary> /// Initializes a new instance of the <see cref="EncodedDepthImage"/> class. /// </summary> /// <param name="width">Width of encoded depth image in pixels.</param> /// <param name="height">Height of encoded depth image in pixels.</param> /// <param name="depthValueSemantics">Optional depth value semantics.</param> /// <param name="depthValueToMetersScaleFactor">Optional scale factor to convert from depth values to meters.</param> public EncodedDepthImage(int width, int height, DepthValueSemantics depthValueSemantics = DepthValueSemantics.DistanceToPlane, double depthValueToMetersScaleFactor = 0.001) { this.Width = width; this.Height = height; this.depthValueSemantics = depthValueSemantics; this.depthValueToMetersScaleFactor = depthValueToMetersScaleFactor; this.PixelFormat = PixelFormat.Gray_16bpp; this.stream = new MemoryStream(); }
/// <summary> /// Initializes a new instance of the <see cref="EncodedDepthImage"/> class. /// </summary> /// <param name="width">Width of image in pixels.</param> /// <param name="height">Height of image in pixels.</param> /// <param name="contents">Byte array used to initialize the image data.</param> /// <param name="depthValueSemantics">Optional depth value semantics.</param> /// <param name="depthValueToMetersScaleFactor">Optional scale factor to convert from depth values to meters.</param> public EncodedDepthImage(int width, int height, byte[] contents, DepthValueSemantics depthValueSemantics = DepthValueSemantics.DistanceToPlane, double depthValueToMetersScaleFactor = 0.001) { this.Width = width; this.Height = height; this.depthValueSemantics = depthValueSemantics; this.depthValueToMetersScaleFactor = depthValueToMetersScaleFactor; this.PixelFormat = PixelFormat.Gray_16bpp; this.stream = new MemoryStream(); this.stream.Write(contents, 0, contents.Length); this.stream.Position = 0; }
/// <summary> /// Create a new <see cref="DepthImage"/> from a specified bitmap. /// </summary> /// <param name="bitmap">A bitmap to create the depth image from.</param> /// <param name="depthValueSemantics">Optional depth value semantics.</param> /// <param name="depthValueToMetersScaleFactor">Optional scale factor to convert from depth values to meters.</param> /// <returns>A new depth image, which contains a copy of the specified bitmap.</returns> public static DepthImage CreateFrom(Bitmap bitmap, DepthValueSemantics depthValueSemantics = DepthValueSemantics.DistanceToPlane, double depthValueToMetersScaleFactor = 0.001) { CheckPixelFormat(bitmap.PixelFormat); DepthImage depthImage = null; BitmapData sourceData = bitmap.LockBits( new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat); try { depthImage = new DepthImage(sourceData, depthValueSemantics, depthValueToMetersScaleFactor, true); } finally { bitmap.UnlockBits(sourceData); } return(depthImage); }
/// <inheritdoc/> public Point3D GetCameraSpacePosition(Point2D point2D, double depth, DepthValueSemantics depthValueSemantics, bool undistort) { // Convert from pixel coordinates to NDC var tmp = new Point3D(point2D.X, point2D.Y, 1.0); tmp = tmp.TransformBy(this.InvTransform); // Distort the pixel var pixelPoint2D = new Point2D(tmp.X, tmp.Y); if (undistort) { this.TryUndistortPoint(pixelPoint2D, out pixelPoint2D); } if (depthValueSemantics == DepthValueSemantics.DistanceToPoint) { double norm = Math.Sqrt(pixelPoint2D.X * pixelPoint2D.X + pixelPoint2D.Y * pixelPoint2D.Y + 1); depth /= norm; } // X points in the depth dimension. Y points to the left, and Z points up. return(new Point3D(depth, -pixelPoint2D.X * depth, -pixelPoint2D.Y * depth)); }
/// <summary> /// Initializes a new instance of the <see cref="DepthImage"/> class. /// </summary> /// <param name="width">Depth image width in pixels.</param> /// <param name="height">Depth image height in pixels.</param> /// <param name="stride">Depth image stride (line size in bytes).</param> /// <param name="depthValueSemantics">Optional depth value semantics.</param> /// <param name="depthValueToMetersScaleFactor">Optional scale factor to convert from depth values to meters.</param> /// <remarks><para><note>Using this constructor, make sure all specified image attributes are correct /// and correspond to unmanaged memory buffer. If some attributes are specified incorrectly, /// this may lead to exceptions working with the unmanaged memory.</note></para></remarks> public DepthImage(int width, int height, int stride, DepthValueSemantics depthValueSemantics = DepthValueSemantics.DistanceToPlane, double depthValueToMetersScaleFactor = 0.001) : base(width, height, stride, PixelFormat.Gray_16bpp) { this.depthValueSemantics = depthValueSemantics; this.depthValueToMetersScaleFactor = depthValueToMetersScaleFactor; }