/// <summary> /// Converts a depth frame to the corresponding System.Windows.Media.Imaging.BitmapSource with the players highlighted. /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> /// <returns>The corresponding System.Windows.Media.Imaging.BitmapSource representation of the depth frame.</returns> public static BitmapSource ToBitmap(this DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { ushort minDepth = depthFrame.DepthMinReliableDistance; ushort maxDepth = depthFrame.DepthMaxReliableDistance; if (_bodyData == null) { _width = depthFrame.FrameDescription.Width; _height = depthFrame.FrameDescription.Height; _depthData = new ushort[_width * _height]; _bodyData = new byte[_width * _height]; _pixels = new byte[_width * _height * Constants.BYTES_PER_PIXEL]; _bitmap = new WriteableBitmap(_width, _height, Constants.DPI, Constants.DPI, Constants.FORMAT, null); } depthFrame.CopyFrameDataToArray(_depthData); bodyIndexFrame.CopyFrameDataToArray(_bodyData); // Convert the depth to RGB for (int depthIndex = 0, colorPixelIndex = 0; depthIndex < _depthData.Length && colorPixelIndex < _pixels.Length; depthIndex++, colorPixelIndex += 4) { // Get the depth for this pixel ushort depth = _depthData[depthIndex]; byte player = _bodyData[depthIndex]; // To convert to a byte, we're discarding the most-significant // rather than least-significant bits. // We're preserving detail, although the intensity will "wrap." // Values outside the reliable depth range are mapped to 0 (black). byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0); if (player != 0xff) { // Color player gold. _pixels[colorPixelIndex + 0] = Colors.Gold.B; // B _pixels[colorPixelIndex + 1] = Colors.Gold.G; // G _pixels[colorPixelIndex + 2] = Colors.Gold.R; // R } else { // Color the rest of the image in grayscale. _pixels[colorPixelIndex + 0] = intensity; // B _pixels[colorPixelIndex + 1] = intensity; // G _pixels[colorPixelIndex + 2] = intensity; // R } } _bitmap.Lock(); Marshal.Copy(_pixels, 0, _bitmap.BackBuffer, _pixels.Length); _bitmap.AddDirtyRect(new Int32Rect(0, 0, _width, _height)); _bitmap.Unlock(); return(_bitmap); }
/// <summary> /// Handles the body index frame data arriving from the sensor /// </summary> /// <param name="sender">object sending the event</param> /// <param name="e">event arguments</param> private void Reader_BodyIndexFrameArrived(object sender, BodyIndexFrameArrivedEventArgs e) { using (BodyIndexFrame bodyIndexFrame = e.FrameReference.AcquireFrame()) { if (bodyIndexFrame != null) { bodyIndexFrame.CopyFrameDataToArray(bodyIndexDataArray); } } }
//used for multiple video sources private void Reader_MultiSourceFrameArrived(MultiSourceFrameReader sender, MultiSourceFrameArrivedEventArgs e) { MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame(); // If the Frame has expired by the time we process this event, return. if (multiSourceFrame == null) { return; } //resets all frames DepthFrame depthFrame = null; ColorFrame colorFrame = null; InfraredFrame infraredFrame = null; BodyFrame bodyFrame = null; BodyIndexFrame bodyIndexFrame = null; IBuffer depthFrameData = null; IBuffer bodyIndexFrameData = null; // Com interface for unsafe byte manipulation IBufferByteAccess bodyIndexByteAccess = null; switch (currentDisplayFrameType) { case DisplayFrameType.Infrared: using (infraredFrame = multiSourceFrame.InfraredFrameReference.AcquireFrame()) { ShowInfraredFrame(infraredFrame); } break; case DisplayFrameType.Color: using (colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame()) { ShowColorFrame(colorFrame); } break; case DisplayFrameType.Depth: using (depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame()) { ShowDepthFrame(depthFrame); } break; case DisplayFrameType.BodyJoints: using (bodyFrame = multiSourceFrame.BodyFrameReference.AcquireFrame()) { ShowBodyJoints(bodyFrame); } break; default: break; } }
private void MultiFrameArrived(object sender, MultiSourceFrameArrivedEventArgs args) { bool dataReceived = false; MultiSourceFrame multiSourceFrame = args.FrameReference.AcquireFrame(); using (DepthFrame depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame()) { if (depthFrame != null) { var pDepthData = GCHandle.Alloc(pDepthBuffer, GCHandleType.Pinned); depthFrame.CopyFrameDataToIntPtr(pDepthData.AddrOfPinnedObject(), (uint)pDepthBuffer.Length * sizeof(ushort)); pDepthData.Free(); dataReceived = true; } } using (ColorFrame colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame()) { if (colorFrame != null) { var pColorData = GCHandle.Alloc(pColorBuffer, GCHandleType.Pinned); colorFrame.CopyConvertedFrameDataToIntPtr(pColorData.AddrOfPinnedObject(), (uint)pColorBuffer.Length, ColorImageFormat.Bgra); pColorData.Free(); dataReceived = true; } } using (BodyIndexFrame bodyIndexFrame = multiSourceFrame.BodyIndexFrameReference.AcquireFrame()) { if (bodyIndexFrame != null) { var pBodyIndexData = GCHandle.Alloc(pBodyIndexBuffer, GCHandleType.Pinned); bodyIndexFrame.CopyFrameDataToIntPtr(pBodyIndexData.AddrOfPinnedObject(), (uint)pBodyIndexBuffer.Length); pBodyIndexData.Free(); dataReceived = true; } } using (BodyFrame bodyFrame = multiSourceFrame.BodyFrameReference.AcquireFrame()) { if (bodyFrame != null) { if (pBodyData == null) { pBodyData = new Body[bodyFrame.BodyCount]; } bodyFrame.GetAndRefreshBodyData(pBodyData); dataReceived = true; } } if (dataReceived) { //////// FPS - BEGIN frameCount++; //////// FPS - END ProcessFrame(); } }
// ************************************************************************************************************************* bool RefreshFrame(MultiSourceFrame _frame) //updateframe to our array { if (_frame == null) { return(false); } try{ bodyframe = _frame.BodyFrameReference.AcquireFrame(); depthFrame = _frame.DepthFrameReference.AcquireFrame(); colorFrame = _frame.ColorFrameReference.AcquireFrame(); bodyIndexFrame = _frame.BodyIndexFrameReference.AcquireFrame(); // If any frame has expired by the time we process this event, return. // The "finally" statement will Dispose any that are not null. if ((depthFrame == null) || (colorFrame == null) || (bodyIndexFrame == null || bodyframe == null)) { return(false); } else { if (BodyData == null) { BodyData = new Body[_Sensor.BodyFrameSource.BodyCount]; } // update all the array and points bodyframe.GetAndRefreshBodyData(BodyData); colorFrame.CopyConvertedFrameDataToArray(colorData, ColorImageFormat.Rgba); depthFrame.CopyFrameDataToArray(depthData); bodyIndexFrame.CopyFrameDataToArray(bodyIndexData); // update all the array and points _frame = null; return(true); } } finally { if (bodyframe != null) { bodyframe.Dispose(); } if (depthFrame != null) { depthFrame.Dispose(); } if (colorFrame != null) { colorFrame.Dispose(); } if (bodyIndexFrame != null) { bodyIndexFrame.Dispose(); } } }
public ushort[,] depthFrameToPixelsData(DepthFrame depth_Frame, BodyIndexFrame bodyIndex_Frame) { ushort[,] darray = new ushort[424, 512]; if (depth_Frame != null && bodyIndex_Frame != null) { int width = depth_Frame.FrameDescription.Width; int height = depth_Frame.FrameDescription.Height; byte[] _bodyData = new byte[width * height]; bodyIndex_Frame.CopyFrameDataToArray(_bodyData); //Console.WriteLine("Width" + width); //Console.WriteLine("Height" + height); PixelFormat format = PixelFormats.Bgr32; stride = width * ((format.BitsPerPixel + 7) / 8); ushort minDepth = depth_Frame.DepthMinReliableDistance; ushort maxDepth = depth_Frame.DepthMaxReliableDistance; ushort[] pixelData = new ushort[width * height]; byte[] pixels = new byte[width * height * (format.BitsPerPixel + 7) / 8]; depth_Frame.CopyFrameDataToArray(pixelData); int j = 0, k = 0; for (int i = 0; i < (424 * 512) && j < 424; i++) { if (_bodyData[i] != 0xff) { darray[j, k] = pixelData[i]; } else { darray[j, k] = 0; } k++; if (k % 512 == 0) { k = 0; j++; } } } return(darray); }
public void Reader_FrameArrived(object sender, BodyIndexFrameArrivedEventArgs e) { using (BodyIndexFrame bodyindexFrame = e.FrameReference.AcquireFrame()) { if (bodyindexFrame != null) { byte[] bodyindexData = new byte[depthFrameWidth * depthFrameHeight]; bodyindexFrame.CopyFrameDataToArray(bodyindexData); bodyindexframes.Add(bodyindexData); } } }
/// <summary> /// Updates the bitmap with new frame data and highlights the players. /// </summary> /// <param name="depthFrame">The specified Kinect depth frame.</param> /// <param name="bodyIndexFrame">The specified Kinect body index frame.</param> public void Update(DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { ushort minDepth = depthFrame.DepthMinReliableDistance; ushort maxDepth = depthFrame.DepthMaxReliableDistance; if (BodyData == null) { Width = depthFrame.FrameDescription.Width; Height = depthFrame.FrameDescription.Height; DepthData = new ushort[Width * Height]; BodyData = new byte[Width * Height]; HighlightedPixels = new byte[Width * Height * Constants.BYTES_PER_PIXEL]; HighlightedBitmap = new WriteableBitmap(Width, Height); HighlightedStream = HighlightedBitmap.PixelBuffer.AsStream(); } depthFrame.CopyFrameDataToArray(DepthData); bodyIndexFrame.CopyFrameDataToArray(BodyData); // Convert the depth to RGB for (int depthIndex = 0, colorPixelIndex = 0; depthIndex < DepthData.Length && colorPixelIndex < HighlightedPixels.Length; depthIndex++, colorPixelIndex += 4) { // Get the depth for this pixel ushort depth = DepthData[depthIndex]; byte player = BodyData[depthIndex]; // To convert to a byte, we're discarding the most-significant // rather than least-significant bits. // We're preserving detail, although the intensity will "wrap." // Values outside the reliable depth range are mapped to 0 (black). byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0); if (player != 0xff) { // Color player gold. HighlightedPixels[colorPixelIndex + 0] = Colors.Gold.B; // B HighlightedPixels[colorPixelIndex + 1] = Colors.Gold.G; // G HighlightedPixels[colorPixelIndex + 2] = Colors.Gold.R; // R } else { // Color the rest of the image in grayscale. HighlightedPixels[colorPixelIndex + 0] = intensity; // B HighlightedPixels[colorPixelIndex + 1] = intensity; // G HighlightedPixels[colorPixelIndex + 2] = intensity; // R } } HighlightedStream.Seek(0, SeekOrigin.Begin); HighlightedStream.Write(HighlightedPixels, 0, HighlightedPixels.Length); HighlightedBitmap.Invalidate(); }
/// <summary> /// Store body index image /// </summary> /// <param name="bodyIndexFrame">body index frame to be stored</param> /// <param name="frameNumber">frame number</param> public static void Handle_BodyIndexFrame(BodyIndexFrame bodyIndexFrame, String frameNumber) { using (Microsoft.Kinect.KinectBuffer bodyIndexBuffer = bodyIndexFrame.LockImageBuffer()) { BitmapSource bitmapSource = BitmapSource.Create(bodyIndexWidth, bodyIndexHeight, 96.0, 96.0, PixelFormats.Gray8, null, bodyIndexBuffer.UnderlyingBuffer, (int)bodyIndexBuffer.Size, bodyIndexWidth * 1); String bodyIndexPath = FramesAndPaths.GetImageFilePath(FramesAndPaths.FileType.BodyIndexImage, frameNumber); bitmapSource.Save(bodyIndexPath + ".jpg", ImageFormat.Jpeg); } // Release bodyIndexFrame bodyIndexFrame.Dispose(); }
/// <summary> /// Updates the bitmap with new frame data and highlights the players. /// </summary> /// <param name="depthFrame">The specified Kinect depth frame.</param> /// <param name="bodyIndexFrame">The specified Kinect body index frame.</param> public void Update(DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { ushort minDepth = depthFrame.DepthMinReliableDistance; ushort maxDepth = depthFrame.DepthMaxReliableDistance; if (BodyData == null) { Width = depthFrame.FrameDescription.Width; Height = depthFrame.FrameDescription.Height; DepthData = new ushort[Width * Height]; BodyData = new byte[Width * Height]; HighlightedPixels = new byte[Width * Height * Constants.BYTES_PER_PIXEL]; HighlightedBitmap = new Bitmap(Width, Height, Constants.FORMAT); } depthFrame.CopyFrameDataToArray(DepthData); bodyIndexFrame.CopyFrameDataToArray(BodyData); // Convert the depth to RGB for (int depthIndex = 0, colorPixelIndex = 0; depthIndex < DepthData.Length && colorPixelIndex < HighlightedPixels.Length; depthIndex++, colorPixelIndex += 4) { // Get the depth for this pixel ushort depth = DepthData[depthIndex]; byte player = BodyData[depthIndex]; // To convert to a byte, we're discarding the most-significant // rather than least-significant bits. // We're preserving detail, although the intensity will "wrap." // Values outside the reliable depth range are mapped to 0 (black). byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0); if (player != 0xff) { // Color player gold. HighlightedPixels[colorPixelIndex + 0] = Color.Gold.B; // B HighlightedPixels[colorPixelIndex + 1] = Color.Gold.G; // G HighlightedPixels[colorPixelIndex + 2] = Color.Gold.R; // R } else { // Color the rest of the image in grayscale. HighlightedPixels[colorPixelIndex + 0] = intensity; // B HighlightedPixels[colorPixelIndex + 1] = intensity; // G HighlightedPixels[colorPixelIndex + 2] = intensity; // R } } BitmapData bitmapData = HighlightedBitmap.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, HighlightedBitmap.PixelFormat); Marshal.Copy(HighlightedPixels, 0, bitmapData.Scan0, HighlightedPixels.Length); HighlightedBitmap.UnlockBits(bitmapData); }
/// <summary> /// Handles the depth/color/body index frame data arriving from the sensor /// </summary> /// <param name="sender">object sending the event</param> /// <param name="e">event arguments</param> private void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e) { DepthFrame depthFrame = null; ColorFrame colorFrame = null; BodyIndexFrame bodyIndexFrame = null; BodyFrame bodyFrame = null; _isBitmapLocked = false; var multiSourceFrame = e.FrameReference.AcquireFrame(); // If the Frame has expired by the time we process this event, return. if (multiSourceFrame == null) { return; } // We use a try/finally to ensure that we clean up before we exit the function. // This includes calling Dispose on any Frame objects that we may have and unlocking the bitmap back buffer. try { depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame(); colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame(); bodyIndexFrame = multiSourceFrame.BodyIndexFrameReference.AcquireFrame(); bodyFrame = multiSourceFrame.BodyFrameReference.AcquireFrame(); // If any frame has expired by the time we process this event, return. // The "finally" statement will Dispose any that are not null. if ((depthFrame == null) || (colorFrame == null) || (bodyIndexFrame == null) || bodyFrame == null) { return; } ProcessBackgroundOld(depthFrame, colorFrame, bodyIndexFrame); ProcessBody(bodyFrame, false); } finally { if (_isBitmapLocked) { _bitmap.Unlock(); } depthFrame?.Dispose(); colorFrame?.Dispose(); bodyIndexFrame?.Dispose(); bodyFrame?.Dispose(); } }
/// <summary> /// Acquires the latest body index frame. /// It calles the OnBodyIndexFrameReceived only if the acquired frame is not null. /// </summary> protected void UpdateBodyIndexFrame() { if (bodyIndexFrameReader != null) { using (BodyIndexFrame frame = bodyIndexFrameReader.AcquireLatestFrame()) { if (frame != null) { OnBodyIndexFrameReceived(frame); } } } }
private void ProcessBodyFrame(MultiSourceFrame multiSourceFrame) { // Body using (var bodyIndexFrame = multiSourceFrame.BodyIndexFrameReference.AcquireFrame()) { BodyIndexFrame frameBodyIndex = bodyIndexFrame; if (bodyIndexFrame != null && this.DepthMetaData != null) { this.BodyMetaData = new BodyMetaData(frameBodyIndex); ProcessDepthColorIR(multiSourceFrame); } } }
public Tuple <BitmapSource, TimeSpan> CaptureBodyIndexFrameBitmap(LiveFrame frame, byte[] buffer) { BodyIndexFrame bodyIndexFrame = frame.NativeBodyIndexFrame; int width = bodyIndexFrame.FrameDescription.Width; int height = bodyIndexFrame.FrameDescription.Height; bodyIndexFrame.CopyFrameDataToArray(_teenyBuffer); BitmapSource result = BufferCaptureBitmapHelper(_teenyBuffer, width, height, 1, buffer); return(new Tuple <BitmapSource, TimeSpan>(result, bodyIndexFrame.RelativeTime)); }
/// <summary> /// This method is called to initialize values for the frame processor (executed only once, when the first frame arrives). /// </summary> private void initialization(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { colorFrameWidth = colorFrame.FrameDescription.Width; colorFrameHeight = colorFrame.FrameDescription.Height; depthFrameWidth = depthFrame.FrameDescription.Width; depthFrameHeight = depthFrame.FrameDescription.Height; bodyIndexFrameWidth = bodyIndexFrame.FrameDescription.Width; bodyIndexFrameHeight = bodyIndexFrame.FrameDescription.Height; initializationDone = true; Console.WriteLine("Frame Processor initialization is done."); }
//frame取得時のイベント public void BodyIndexFrame_Arrived(object sender, BodyIndexFrameArrivedEventArgs e) #region { BodyIndexFrame bodyIndexFrame = e.FrameReference.AcquireFrame(); if (bodyIndexFrame == null) { return; } bodyIndexFrame.CopyFrameDataToArray(bodyIndexBuffer); //人がいないところ0xff いるところ0-6? this.KinectImagetoMat(this.kinectImage, this.bodyIndexBuffer); //this._showImageEvent(); bodyIndexFrame.Dispose(); }
void reader_MultiSourceFrameArrived(MultiSourceFrameReader sender, MultiSourceFrameArrivedEventArgs args) { using (MultiSourceFrame frame = args.FrameReference.AcquireFrame()) { if (frame != null) { //Récupération des images using (BodyFrame bodyFrame = frame.BodyFrameReference.AcquireFrame()) //################# BODYFRAME using (BodyIndexFrame bodyIndexFrame = frame.BodyIndexFrameReference.AcquireFrame()) //################# BODY INDEX using (ColorFrame colorFrame = frame.ColorFrameReference.AcquireFrame()) //################# COLOR { if (bodyIndexFrame != null && bodyFrame != null && colorFrame != null) { //Initilisation et mise à jour du tableau de body if (this.bodies == null) { this.bodies = new Body[bodyFrame.BodyCount]; } bodyFrame.GetAndRefreshBodyData(this.bodies); //WriteableBitmap bitmap = (WriteableBitmap)this.kinectImage.Source; //Tableau contenant les données bodyIndex byte[] bodyIndexArray = new byte[bodyIndexFrame.FrameDescription.LengthInPixels * bodyIndexFrame.FrameDescription.BytesPerPixel]; bodyIndexFrame.CopyFrameDataToArray(bodyIndexArray); colorFrame.CopyConvertedFrameDataToBuffer(bitmap.PixelBuffer, ColorImageFormat.Bgra); foreach (Body b in this.bodies) { ColorSpacePoint[] colorPoint = new ColorSpacePoint[1]; kinect.CoordinateMapper.MapCameraPointsToColorSpace(new CameraSpacePoint[] { b.Joints[JointType.HandLeft].Position }, colorPoint); try { Canvas.SetLeft(ellipse, colorPoint[0].X); Canvas.SetTop(ellipse, colorPoint[0].Y); }catch (Exception e) { } } } } } } }
private bool ProcessBodyFrame(MultiSourceFrame multiSourceFrame) { // Body using (var bodyIndexFrame = multiSourceFrame.BodyIndexFrameReference.AcquireFrame()) { BodyIndexFrame frameBodyIndex = bodyIndexFrame; if (bodyIndexFrame != null && this.DepthMetaData != null) { this.BodyMetaData = new BodyMetaData(frameBodyIndex); ProcessColorDepthIR(multiSourceFrame); return(true); } } return(false); }
private void DepthFrameReady(object sender, BodyIndexFrameArrivedEventArgs e) { BodyIndexFrame frame = e.FrameReference.AcquireFrame(); if (frame != null) { this.FInvalidate = true; this.frameindex = frame.RelativeTime.Ticks; lock (m_lock) { frame.CopyFrameDataToArray(this.rawdepth); } frame.Dispose(); } }
internal static void CopyToFrameToPixelArray(this BodyIndexFrame bodyIndexFrame, ref byte[] frameData, ref byte[] pixels) { var pixelIndex = 0; bodyIndexFrame.CopyFrameDataToArray(frameData); for (int i = 0; i < frameData.Length; ++i) { var color = BodyIndexColor.GetColorFromBodyIndex(frameData[i]); pixels[pixelIndex++] = color.B; pixels[pixelIndex++] = color.G; pixels[pixelIndex++] = color.R; pixels[pixelIndex++] = color.A; } }
private void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e) { var reference = e.FrameReference.AcquireFrame(); using (BodyFrame frame = reference.BodyFrameReference.AcquireFrame()) { if (frame != null) { HandleBodyFrame(frame); } } using (ColorFrame frame = reference.ColorFrameReference.AcquireFrame()) { if (frame != null) { ColorToBitmap(frame); } } using (DepthFrame frame = reference.DepthFrameReference.AcquireFrame()) { if (frame != null) { DepthToBitmap(frame); } } using (InfraredFrame frame = reference.InfraredFrameReference.AcquireFrame()) { if (frame != null) { InfraredToBitmap(frame); } } using (BodyIndexFrame frame = reference.BodyIndexFrameReference.AcquireFrame()) { if (frame != null) { IndexToBitmap(frame); } } }
public void BodyIndexFrameArrival(BodyIndexFrame bif, ref bool frameProcessed, double fps, WriteableBitmap bodyIndexBitmap) { // the fastest way to process the body index data is to directly access // the underlying buffer using (Microsoft.Kinect.KinectBuffer bodyIndexBuffer = bif.LockImageBuffer()) { int width = bif.FrameDescription.Width; int height = bif.FrameDescription.Height; // verify data and write the color data to the display bitmap if (((width * height) == bodyIndexBuffer.Size) && (width == bodyIndexBitmap.PixelWidth) && (height == bodyIndexBitmap.PixelHeight)) { ProcessBodyIndexFrameData(bodyIndexBuffer.UnderlyingBuffer, bodyIndexBuffer.Size); frameProcessed = true; } if (bodyRecording) { Bitmap bitmapFrame; try { bitmapFrame = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); } catch (Exception e) { Console.WriteLine("Body Exception"); Console.WriteLine(e); System.GC.Collect(); bitmapFrame = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format8bppIndexed); } UtilityClass.ByteArrayToBitmap(ref bitmapFrame, bodyPixelBuffer, width, height); bBitmap = bitmapFrame; bodyBitmapBuffer.Enqueue(bBitmap); //System.GC.Collect(); frameCount++; if (fps < 16.0) { Console.WriteLine("fps drop yaşandı"); bodyBitmapBuffer.Enqueue(bBitmap); frameCount++; } } } }
/// <summary> /// Kinect が複数種類のフレームを取得したとき実行されるメソッド(イベントハンドラ)。 /// </summary> /// <param name="sender"> /// イベントを通知したオブジェクト。ここでは Kinect になる。 /// </param> /// <param name="e"> /// イベントの発生時に渡されるデータ。 /// </param> void MultiSourceFrameReader_MultiSourceFrameArrived (object sender, MultiSourceFrameArrivedEventArgs e) { MultiSourceFrame frames = this.multiSourceFrameReader.AcquireLatestFrame(); if (frames == null) { return; } ColorFrame colorFrame = frames.ColorFrameReference.AcquireFrame(); if (colorFrame == null) { return; } DepthFrame depthFrame = frames.DepthFrameReference.AcquireFrame(); if (depthFrame == null) { colorFrame.Dispose(); return; } BodyIndexFrame bodyIndexFrame = frames.BodyIndexFrameReference.AcquireFrame(); if (bodyIndexFrame == null) { colorFrame.Dispose(); depthFrame.Dispose(); return; } this.colorCanvas.Background = new ImageBrush(GetColorImage(colorFrame)); this.userMaskCanvas.Background = new ImageBrush (GetUserMaskImage(colorFrame, depthFrame, bodyIndexFrame)); colorFrame.Dispose(); depthFrame.Dispose(); bodyIndexFrame.Dispose(); }
//Captures Point Cloud private void capturePointCloud(DepthFrame df, BodyIndexFrame bif) { CoordinateMapper coordinateMapper = sensor.getCoordinateMapper(); if (df != null && bif != null && coordinateMapper != null) { //Generate pointCloud using the frames. PointCloudGenerator pcg = new PointCloudGenerator(coordinateMapper); PointCloud pointCloud = pcg.generate(df, bif); Log.Write(Log.Tag.INFO, pointCloud.getSize()); saveFile(pointCloud); startNextWindow(); } else { Log.Write(Log.Tag.ERROR, "There was problem capturing the frames. Arrays containg FrameData or/and the CoordinateMapper are NULL"); } }
private void StartBodyIndexStream() { // Get frame description for the infr output var description = Sensor.BodyIndexFrameSource.FrameDescription; // Init infr buffer BodyIndexFrame frame = BodyIndex = new BodyIndexFrame(); frame.Width = description.Width; frame.Height = description.Height; frame.Pixels = new byte[description.LengthInPixels]; frame.Stamp = new Timestamp(); AddOnManager.GetInstance().InitFrame(Name, frame); Log(frame.ToString()); // Start Watch BodyIndexWatch = new StopwatchAvg(); }
private void updateDisplayedBitmap(BodyIndexFrame bif) { using (Microsoft.Kinect.KinectBuffer bodyIndexBuffer = bif.LockImageBuffer()) { //Verify if the frame is of right size - not sure why but recommended in tutorials if (((sensor.getBodyIndexFrameDescription().Width *sensor.getBodyIndexFrameDescription().Height) == bodyIndexBuffer.Size) && (sensor.getBodyIndexFrameDescription().Width == this.displayedBitmap.PixelWidth) && (sensor.getBodyIndexFrameDescription().Height == this.displayedBitmap.PixelHeight)) { uint[] pixalData = processBIF(bodyIndexBuffer.UnderlyingBuffer, bodyIndexBuffer.Size); displayedBitmap.WritePixels( new Int32Rect(0, 0, displayedBitmap.PixelWidth, displayedBitmap.PixelHeight), pixalData, this.displayedBitmap.PixelWidth * BytesPerPixel, 0); bitmap_feed.Source = displayedBitmap; } } }
void Reader_MultiSourceFrameArrived(object sender, MultiSourceFrameArrivedEventArgs e) { // Get a reference to the multi-frame var reference = e.FrameReference.AcquireFrame(); ColorFrame colorFrame = null; BodyIndexFrame biFrame = null; DepthFrame depthFrame = null; try { rightImageFrameCount++; if (rightImageFrameCount == 1) { colorFrame = reference.ColorFrameReference.AcquireFrame(); if (colorFrame != null) { ColorSection(colorFrame); } depthFrame = reference.DepthFrameReference.AcquireFrame(); if (depthFrame != null) { //DepthSection(depthFrame); GetRightImage(depthFrame, colorFrame); } rightImageFrameCount = 0; } } finally { if (colorFrame != null) { colorFrame.Dispose(); } if (depthFrame != null) { depthFrame.Dispose(); } } }
/// <summary> /// 人体索引帧临帧事件 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> public void Reader_BodyIndexFrameArrived(Object sender, BodyIndexFrameArrivedEventArgs e) { using (BodyIndexFrame bodyIndexFrame = e.FrameReference.AcquireFrame()) { if (bodyIndexFrame != null) { // the fastest way to process the body index data is to directly access // the underlying buffer using (Microsoft.Kinect.KinectBuffer bodyIndexBuffer = bodyIndexFrame.LockImageBuffer()) { // verify data and write the color data to the display bitmap if (((this.bodyIndexFrameDescription.Width * this.bodyIndexFrameDescription.Height) == bodyIndexBuffer.Size)) { //this.BodyIndexToDepth(bodyIndexBuffer.UnderlyingBuffer, bodyIndexBuffer.Size); this.ProcessBodyIndexFrameData(bodyIndexBuffer.UnderlyingBuffer, bodyIndexBuffer.Size); } } } } }
private void ProcessBodyIndexFrame(BodyIndexFrame bodyIndexFrame) { if (bodyIndexFrame != null) { byte[] outBuffer = _displayableBuffers[SourceType.BODY_INDEX]; bodyIndexFrame.CopyFrameDataToArray(_rawBodyIndexPixels); bodyIndexFrame.Dispose(); int outIndex = 0; for (int inIndex = 0; inIndex < _rawBodyIndexPixels.Length; ++inIndex) { int bodyIndex = _rawBodyIndexPixels[inIndex]; UInt32 thisColor = 0; _bodyIndexToColorMap.TryGetValue(bodyIndex, out thisColor); outBuffer[outIndex++] = (byte)((thisColor & 0xFF000000) >> 32); // Blue channel outBuffer[outIndex++] = (byte)((thisColor & 0x00FF0000) >> 16); // Green channel outBuffer[outIndex++] = (byte)((thisColor & 0x0000FF00) >> 8); // Red channel outBuffer[outIndex++] = (byte)((thisColor & 0x000000FF)); // Alpha channel } } }
/// <summary> /// Handles the body index frame data arriving from the sensor /// </summary> /// <param name="sender">object sending the event</param> /// <param name="e">event arguments</param> private void Reader_BodyIndexFrameArrived(object sender, BodyIndexFrameArrivedEventArgs e) { bool bodyIndexFrameProcessed = false; using (BodyIndexFrame bodyIndexFrame = e.FrameReference.AcquireFrame()) { if (bodyIndexFrame != null) { bodyIHandler.BodyIndexFrameArrival(bodyIndexFrame, ref bodyIndexFrameProcessed, this.fps, bodyIndexBitmap); indexResolutionText.Content = string.Format("Resolution : {0} x {1}", bodyIndexFrame.FrameDescription.Width.ToString(), bodyIndexFrame.FrameDescription.Height.ToString()); } } if (bodyIndexFrameProcessed) { this.RenderBodyIndexPixels(); } }
/// <summary> /// Converts a depth frame to the corresponding System.Windows.Media.Imaging.BitmapSource and removes the background (green-screen effect). /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="colorFrame">The specified color frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> /// <returns>The corresponding System.Windows.Media.Imaging.BitmapSource representation of image.</returns> public BitmapSource GreenScreen(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { int colorWidth = colorFrame.FrameDescription.Width; int colorHeight = colorFrame.FrameDescription.Height; int depthWidth = depthFrame.FrameDescription.Width; int depthHeight = depthFrame.FrameDescription.Height; int bodyIndexWidth = bodyIndexFrame.FrameDescription.Width; int bodyIndexHeight = bodyIndexFrame.FrameDescription.Height; if (_displayPixels == null) { _depthData = new ushort[depthWidth * depthHeight]; _bodyData = new byte[depthWidth * depthHeight]; _colorData = new byte[colorWidth * colorHeight * BYTES_PER_PIXEL]; _displayPixels = new byte[depthWidth * depthHeight * BYTES_PER_PIXEL]; _colorPoints = new ColorSpacePoint[depthWidth * depthHeight]; _bitmap = new WriteableBitmap(depthWidth, depthHeight, DPI, DPI, FORMAT, null); } if (((depthWidth * depthHeight) == _depthData.Length) && ((colorWidth * colorHeight * BYTES_PER_PIXEL) == _colorData.Length) && ((bodyIndexWidth * bodyIndexHeight) == _bodyData.Length)) { depthFrame.CopyFrameDataToArray(_depthData); if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra) { colorFrame.CopyRawFrameDataToArray(_colorData); } else { colorFrame.CopyConvertedFrameDataToArray(_colorData, ColorImageFormat.Bgra); } bodyIndexFrame.CopyFrameDataToArray(_bodyData); _coordinateMapper.MapDepthFrameToColorSpace(_depthData, _colorPoints); Array.Clear(_displayPixels, 0, _displayPixels.Length); for (int y = 0; y < depthHeight; ++y) { for (int x = 0; x < depthWidth; ++x) { int depthIndex = (y * depthWidth) + x; byte player = _bodyData[depthIndex]; if (player != 0xff) { ColorSpacePoint colorPoint = _colorPoints[depthIndex]; int colorX = (int)Math.Floor(colorPoint.X + 0.5); int colorY = (int)Math.Floor(colorPoint.Y + 0.5); if ((colorX >= 0) && (colorX < colorWidth) && (colorY >= 0) && (colorY < colorHeight)) { int colorIndex = ((colorY * colorWidth) + colorX) * BYTES_PER_PIXEL; int displayIndex = depthIndex * BYTES_PER_PIXEL; _displayPixels[displayIndex + 0] = 255; _displayPixels[displayIndex + 1] = 255; _displayPixels[displayIndex + 2] = 255; _displayPixels[displayIndex + 3] = 127; // 79 195 247 } } } } _bitmap.Lock(); Marshal.Copy(_displayPixels, 0, _bitmap.BackBuffer, _displayPixels.Length); _bitmap.AddDirtyRect(new Int32Rect(0, 0, depthWidth, depthHeight)); _bitmap.Unlock(); } return _bitmap; }
/// <summary> /// Updates the bitmap with new frame data. /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="colorFrame">The specified color frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> override public void Update(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { int colorWidth = colorFrame.FrameDescription.Width; int colorHeight = colorFrame.FrameDescription.Height; int depthWidth = depthFrame.FrameDescription.Width; int depthHeight = depthFrame.FrameDescription.Height; int bodyIndexWidth = bodyIndexFrame.FrameDescription.Width; int bodyIndexHeight = bodyIndexFrame.FrameDescription.Height; if (Bitmap == null) { InitBuffers(colorFrame.FrameDescription, depthFrame.FrameDescription, bodyIndexFrame.FrameDescription); } if (((depthWidth * depthHeight) == _depthData.Length) && ((colorWidth * colorHeight * Constants.BYTES_PER_PIXEL) == Pixels.Length) && ((bodyIndexWidth * bodyIndexHeight) == _bodyData.Length)) { depthFrame.CopyFrameDataToArray(_depthData); if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra) { colorFrame.CopyRawFrameDataToArray(Pixels); } else { colorFrame.CopyConvertedFrameDataToArray(Pixels, ColorImageFormat.Bgra); } bodyIndexFrame.CopyFrameDataToArray(_bodyData); CoordinateMapper.MapColorFrameToDepthSpace(_depthData, _depthPoints); // Loop over each row and column of the color image // Zero out any pixels that don't correspond to a body index for (int i = 0, ci = 0; i < _depthPoints.Length; ++i, ci += Constants.BYTES_PER_PIXEL) { float colorToDepthX = _depthPoints[i].X; float colorToDepthY = _depthPoints[i].Y; // The sentinel value is -inf, -inf, meaning that no depth pixel corresponds to this color pixel. if (!float.IsNegativeInfinity(colorToDepthX) && !float.IsNegativeInfinity(colorToDepthY)) { // Make sure the depth pixel maps to a valid point in color space int depthX = (int)(colorToDepthX + 0.5f); int depthY = (int)(colorToDepthY + 0.5f); // If the point is not valid, there is no body index there. if ((depthX >= 0) && (depthX < depthWidth) && (depthY >= 0) && (depthY < depthHeight)) { int depthIndex = (depthY * depthWidth) + depthX; // If we are tracking a body for the current pixel, do not zero out the pixel if (_bodyData[depthIndex] != 0xff) { continue; } } } for (int b = 0; b < Constants.BYTES_PER_PIXEL; ++b) { Pixels[ci + b] = 0; } } UpdateBitmap(); } }
private void ProcessFrames(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame, BodyFrame bodyFrame, byte [] psBytes0, byte [] psBytes1) { // create multiframe to process long ticksCopyData = DateTime.Now.Ticks; MultiFrame multiFrame = new MultiFrame(); multiFrame.FrameNb = Interlocked.Increment(ref frameNb); // color long ticksCreateColorData = DateTime.Now.Ticks; byte[] colorData = new byte[colorByteSize]; Utils.UpdateTimer("CreateColorData", ticksCreateColorData); long ticksCopyColorData = DateTime.Now.Ticks; colorFrame.CopyConvertedFrameDataToArray(colorData, ColorImageFormat.Bgra); Utils.UpdateTimer("CopyColorData", ticksCopyColorData); // depth long ticksCreateDepthData = DateTime.Now.Ticks; ushort[] depthData = new ushort[depthPixelSize]; depthFrame.CopyFrameDataToArray(depthData); Utils.UpdateTimer("CreateDepthData", ticksCreateDepthData); // body index long ticksCreateBodyIndexData = DateTime.Now.Ticks; byte[] bodyIndexData = new byte[depthPixelSize]; bodyIndexFrame.CopyFrameDataToArray(bodyIndexData); Utils.UpdateTimer("CreateBodyIndexData", ticksCreateBodyIndexData); // bodies long ticksCreateBodiesData = DateTime.Now.Ticks; Body[] bodies = new Body[bodyFrame.BodyCount]; bodyFrame.GetAndRefreshBodyData(bodies); Utils.UpdateTimer("CreateBodiesData", ticksCreateBodiesData); // ps3eye byte[] psBytes = null; if (psBytes0 != null && psBytes1 != null) { long ticksCreatePS3EyeData = DateTime.Now.Ticks; psBytes = new byte[psByteSize * 2]; Utils.UpdateTimer("CreatePS3EyeData", ticksCreatePS3EyeData); long ticksCopyPS3EyeData = DateTime.Now.Ticks; CopyPS3EyeDataMirror(psBytes, psBytes0, psBytes1); Utils.UpdateTimer("CopyPS3EyeData", ticksCopyPS3EyeData); } // multiFrame long ticksMultiFrame = DateTime.Now.Ticks; multiFrame.DepthData = depthData; multiFrame.ColorData = colorData; multiFrame.BodyIndexData = bodyIndexData; multiFrame.Bodies = bodies; multiFrame.PS3EyeData = psBytes; multiFrame.HasKinectData = true; multiFrame.HasPS3EyeData = psBytes != null ? true : false; Utils.UpdateTimer("MultiFrame", ticksMultiFrame); long ticksEnqueue = DateTime.Now.Ticks; ProcessingManager.Instance.EnqueueMultiFrame(multiFrame); Utils.UpdateTimer("Enqueue", ticksEnqueue); Utils.UpdateTimer("CopyFramesData", ticksCopyData); // display timers & queues Context.GUI.DisplayPerformance(); }
private void maskBackground(BodyIndexFrame bodyIndexFrame, int depthWidth, int depthHeight) { // We'll access the body index data directly to avoid a copy using (KinectBuffer bodyIndexData = bodyIndexFrame.LockImageBuffer()) { unsafe { byte* bodyIndexDataPointer = (byte*)bodyIndexData.UnderlyingBuffer; int colorMappedToDepthPointCount = this.colorMappedToDepthPoints.Length; fixed (DepthSpacePoint* colorMappedToDepthPointsPointer = this.colorMappedToDepthPoints) { // Treat the color data as 4-byte pixels uint* bitmapPixelsPointer = (uint*)this.bitmap.BackBuffer; // Loop over each row and column of the color image // Zero out any pixels that don't correspond to a body index for (int colorIndex = 0; colorIndex < colorMappedToDepthPointCount; ++colorIndex) { float colorMappedToDepthX = colorMappedToDepthPointsPointer[colorIndex].X; float colorMappedToDepthY = colorMappedToDepthPointsPointer[colorIndex].Y; // The sentinel value is -inf, -inf, meaning that no depth pixel corresponds to this color pixel. if (!float.IsNegativeInfinity(colorMappedToDepthX) && !float.IsNegativeInfinity(colorMappedToDepthY)) { // Make sure the depth pixel maps to a valid point in color space int depthX = (int)(colorMappedToDepthX + 0.5f); int depthY = (int)(colorMappedToDepthY + 0.5f); // If the point is not valid, there is no body index there. if ((depthX >= 0) && (depthX < depthWidth) && (depthY >= 0) && (depthY < depthHeight)) { int depthIndex = (depthY * depthWidth) + depthX; // If we are tracking a body for the current pixel, do not zero out the pixel if (bodyIndexDataPointer[depthIndex] != 0xff) { continue; } } } bitmapPixelsPointer[colorIndex] = 0; } } this.bitmap.AddDirtyRect(new Int32Rect(0, 0, this.bitmap.PixelWidth, this.bitmap.PixelHeight)); } } }
private void ProcessFrames(DepthFrame depthFrame, ColorFrame colorFrame, BodyIndexFrame bodyIndexFrame, BodyFrame bodyFrame) { FrameDescription depthFrameDescription = depthFrame.FrameDescription; FrameDescription colorFrameDescription = colorFrame.FrameDescription; FrameDescription bodyIndexFrameDescription = bodyIndexFrame.FrameDescription; int bodyIndexWidth = bodyIndexFrameDescription.Width; int bodyIndexHeight = bodyIndexFrameDescription.Height; // The ImageModel object is used to transfer Kinect data into the DataFlow rotunies. ImageModel imageModel = new ImageModel() { DepthWidth = depthFrameDescription.Width, DepthHeight = depthFrameDescription.Height, ColorWidth = colorFrameDescription.Width, ColorHeight = colorFrameDescription.Height, ShowTrails = _vm.LeaveTrails, PersonFill = _vm.PersonFill, MaxDistance = _vm.BackgroundDistance }; imageModel.ColorFrameData = new byte[imageModel.ColorWidth * imageModel.ColorHeight * this.bytesPerPixel]; imageModel.DisplayPixels = new byte[_PreviousFrameDisplayPixels.Length]; imageModel.BodyIndexFrameData = new byte[imageModel.DepthWidth * imageModel.DepthHeight]; imageModel.ColorPoints = new ColorSpacePoint[imageModel.DepthWidth * imageModel.DepthHeight]; imageModel.BytesPerPixel = bytesPerPixel; imageModel.Bodies = new Body[this.kinectSensor.BodyFrameSource.BodyCount]; bodyFrame.GetAndRefreshBodyData(imageModel.Bodies); imageModel.DepthData = new ushort[imageModel.DepthWidth * imageModel.DepthHeight]; depthFrame.CopyFrameDataToArray(imageModel.DepthData); depthFrame.CopyFrameDataToArray(this.DepthFrameData); if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra) { colorFrame.CopyRawFrameDataToArray(imageModel.ColorFrameData); } else { colorFrame.CopyConvertedFrameDataToArray(imageModel.ColorFrameData, ColorImageFormat.Bgra); } imageModel.PixelFormat = PixelFormats.Bgra32; _ColorBitmap.WritePixels(new Int32Rect(0, 0, imageModel.ColorWidth, imageModel.ColorHeight), imageModel.ColorFrameData, imageModel.ColorWidth * imageModel.BytesPerPixel, 0); //RenderTargetBitmap renderBitmap = new RenderTargetBitmap((int)CompositeImage.ActualWidth, (int)CompositeImage.ActualHeight, 96.0, 96.0, PixelFormats.Pbgra32); //DrawingVisual dv = new DrawingVisual(); //VisualBrush brush = new VisualBrush(CompositeImage); //foreach(Body body in _bodies) //{ // if (body.IsTracked) // { // Joint joint = body.Joints[JointType.HandRight]; // using (DrawingContext dc = dv.RenderOpen()) // { // dc.DrawRectangle(brush, null, new Rect(new Point(), new Size(CompositeImage.ActualWidth, CompositeImage.ActualHeight))); // ImageBrush brush2 = new ImageBrush(_pointerBitmap); // brush2.Opacity = 1.0; // dc.DrawRectangle(brush2, null, new Rect(new Point(0, CompositeImage.ActualHeight - _Overlay.Height), new Size(_pointerBitmap.Width, _pointerBitmap.Height))); // } // } //} //ConvertIRDataToByte(); ImagePreview.Source = _ColorBitmap; bodyIndexFrame.CopyFrameDataToArray(imageModel.BodyIndexFrameData); this.coordinateMapper.MapDepthFrameToColorSpace(DepthFrameData, imageModel.ColorPoints); if (_vm.LeaveTrails) { Array.Copy(this._PreviousFrameDisplayPixels, imageModel.DisplayPixels, this._PreviousFrameDisplayPixels.Length); } try { //Send the imageModel to the DataFlow transformer _ImageTransformer.Post(imageModel); } catch (Exception ex) { #if DEBUG Console.WriteLine(ex); #endif } }
/// <summary> /// Converts a depth frame to the corresponding System.Windows.Media.Imaging.BitmapSource and removes the background (green-screen effect). /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="colorFrame">The specified color frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> /// <returns>The corresponding System.Windows.Media.Imaging.BitmapSource representation of image.</returns> public Bitmap GreenScreen(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { return GreenScreen(colorFrame, depthFrame, bodyIndexFrame, Color.Transparent); }
void GreenScreenMappingDepthToColorSplats(ref DepthFrame depthFrame, ref ColorFrame colorFrame, ref BodyIndexFrame bodyIndexFrame, int depthWidth, int depthHeight, int colorWidth, int colorHeight) { m_stopwatch.Restart(); using (KinectBuffer depthFrameData = depthFrame.LockImageBuffer()) { // Need to know the color space point for each depth space point, but this is much less data // and much faster to compute than mapping the other way m_coordinateMapper.MapDepthFrameToColorSpaceUsingIntPtr( depthFrameData.UnderlyingBuffer, depthFrameData.Size, m_depthToColorSpacePoints); } m_depthMapTimer.Update(m_stopwatch.ElapsedMilliseconds); m_stopwatch.Restart(); // We're done with the DepthFrame depthFrame.Dispose(); depthFrame = null; lock (m_displayPixels) { // [KinectThread] avoid racing display buffer refresh with render (can cause missing images) // have to clear the display pixels so we can copy only the BGRA image of the player(s) Array.Clear(m_displayPixels, 0, m_displayPixels.Length); unsafe { fixed (byte* colorFrameDataPtr = &m_colorFrameData[0]) { colorFrame.CopyConvertedFrameDataToIntPtr(new IntPtr(colorFrameDataPtr), (uint)m_colorFrameData.Length, ColorImageFormat.Bgra); } } // done with the colorFrame colorFrame.Dispose(); colorFrame = null; m_colorCopyTimer.Update(m_stopwatch.ElapsedMilliseconds); m_stopwatch.Restart(); // We'll access the body index data directly to avoid a copy using (KinectBuffer bodyIndexData = bodyIndexFrame.LockImageBuffer()) { unsafe { byte* bodyIndexDataPointer = (byte*)bodyIndexData.UnderlyingBuffer; uint bodyIndexDataLength = bodyIndexData.Size; int colorMappedToDepthPointCount = m_colorToDepthSpacePoints.Length; fixed (ColorSpacePoint* depthMappedToColorPointsPointer = m_depthToColorSpacePoints) { fixed (byte* bitmapPixelsBytePointer = &m_displayPixels[0]) { fixed (byte* sourcePixelsBytePointer = &m_colorFrameData[0]) { uint* bitmapPixelsPointer = (uint*)bitmapPixelsBytePointer; uint* sourcePixelsPointer = (uint*)sourcePixelsBytePointer; // We don't go all the way to the edge of the depth buffer, to eliminate a chance // that a splat will go outside the edge of the color buffer when mapped to color // space. In the x direction this will never happen anyway since the depth FOV // is so much narrower than the color FOV. const int Margin = 2; for (int y = Margin; y < depthHeight - Margin; y++) { for (int x = 0; x < depthWidth; x++) { // Scan forwards until we find a non-0xff value in the body index data. int depthIndex = y * depthWidth + x; if (bodyIndexDataPointer[depthIndex] != 0xff) { int depthIndex2 = depthIndex; // We found the beginning of a horizontal run of player pixels. // Scan to the end. int runWidth; for (runWidth = 1; runWidth + x < depthWidth; runWidth++) { depthIndex2++; if (bodyIndexDataPointer[depthIndex2] == 0xff) { break; } } // Now splat from (x, y) to (x + runWidth, y) float depthMappedToColorLeftX = depthMappedToColorPointsPointer[depthIndex].X; float depthMappedToColorLeftY = depthMappedToColorPointsPointer[depthIndex].Y; float depthMappedToColorRightX = depthMappedToColorPointsPointer[depthIndex2 - 1].X; float depthMappedToColorRightY = depthMappedToColorPointsPointer[depthIndex2 - 1].Y; // Now copy color pixels along that rectangle. const int splatHMargin = 2; // X margin of splat rectangle in color pixels const int splatVMargin = 3; // Y margin of splat rectangle in color pixels int minX = (int)Math.Min(depthMappedToColorLeftX, depthMappedToColorRightX) - splatHMargin; int minY = (int)Math.Min(depthMappedToColorLeftY, depthMappedToColorRightY) - splatVMargin; int maxX = (int)Math.Max(depthMappedToColorLeftX, depthMappedToColorRightX) + splatHMargin; int maxY = (int)Math.Max(depthMappedToColorLeftY, depthMappedToColorRightY) + splatVMargin; // Some edge of screen situations can result in color space points that are negative or otherwise // actually outside the color space coordinate range. Clamp(ref minX, colorWidth - 1); Clamp(ref minY, colorHeight - 1); Clamp(ref maxX, colorWidth - 1); Clamp(ref maxY, colorHeight - 1); for (int colorY = minY; colorY < maxY; colorY++) { int colorIndex = colorY * colorWidth + minX; for (int colorX = minX; colorX < maxX; colorX++) { bitmapPixelsPointer[colorIndex] = sourcePixelsPointer[colorIndex]; colorIndex++; } } x += runWidth; } } } } } } } } // Done with bodyIndexFrame bodyIndexFrame.Dispose(); bodyIndexFrame = null; } m_colorScanTimer.Update(m_stopwatch.ElapsedMilliseconds); m_stopwatch.Restart(); m_displayTexture.SetData(m_displayPixels); m_textureSetDataTimer.Update(m_stopwatch.ElapsedMilliseconds); m_stopwatch.Restart(); Spam.TopLine1 = string.Format("depth map: {0} msec; color copy: {1} msec; color scan: {2} msec; texture set: {3} msec", m_depthMapTimer.Average, m_colorCopyTimer.Average, m_colorScanTimer.Average, m_textureSetDataTimer.Average); }
/// <summary> /// Converts the specified depth and body index frames to a bitmap and saves it to the specified location. /// </summary> /// <param name="depthFrame">The source depth frame.</param> /// <param name="bodyIndexFrame">The source body index frame.</param> /// <param name="destination">The destination storage file for the image. JPEG, PNG, GIF, BMP and TIFF formats are supported.</param> /// <param name="width">The width of the image file.</param> /// <param name="height">The height of the image file.</param> /// <returns>True if the image was successfully saved. False otherwise.</returns> public static async Task<bool> Save(this DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame, StorageFile destination, int width, int height) { var bitmap = depthFrame.ToBitmap(bodyIndexFrame); return await _capture.Save(bitmap, destination, width, height); }
/// <summary> /// Converts the specified depth and body index frames to a bitmap and saves it to the specified location. /// </summary> /// <param name="depthFrame">The source depth frame.</param> /// <param name="bodyIndexFrame">The source body index frame.</param> /// <param name="path">The destination path for the new image. JPEG, PNG, GIF, BMP and TIFF formats are supported.</param> /// <returns>True if the image was successfully saved. False otherwise.</returns> public static bool Save(this DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame, string path) { var bitmap = depthFrame.ToBitmap(bodyIndexFrame); return _capture.Save(bitmap, path); }
/// <summary> /// Converts a depth frame to the corresponding System.Windows.Media.Imaging.BitmapSource and removes the background (green-screen effect). /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="colorFrame">The specified color frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> /// <returns>The corresponding System.Windows.Media.Imaging.BitmapSource representation of image.</returns> public WriteableBitmap GreenScreen(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { int colorWidth = colorFrame.FrameDescription.Width; int colorHeight = colorFrame.FrameDescription.Height; int depthWidth = depthFrame.FrameDescription.Width; int depthHeight = depthFrame.FrameDescription.Height; int bodyIndexWidth = bodyIndexFrame.FrameDescription.Width; int bodyIndexHeight = bodyIndexFrame.FrameDescription.Height; if (_displayPixels == null) { _depthData = new ushort[depthWidth * depthHeight]; _bodyData = new byte[depthWidth * depthHeight]; _colorData = new byte[colorWidth * colorHeight * Constants.BYTES_PER_PIXEL]; _displayPixels = new byte[depthWidth * depthHeight * Constants.BYTES_PER_PIXEL]; _colorPoints = new ColorSpacePoint[depthWidth * depthHeight]; _bitmap = new WriteableBitmap(depthWidth, depthHeight); _stream = _bitmap.PixelBuffer.AsStream(); } if (((depthWidth * depthHeight) == _depthData.Length) && ((colorWidth * colorHeight * Constants.BYTES_PER_PIXEL) == _colorData.Length) && ((bodyIndexWidth * bodyIndexHeight) == _bodyData.Length)) { depthFrame.CopyFrameDataToArray(_depthData); if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra) { colorFrame.CopyRawFrameDataToArray(_colorData); } else { colorFrame.CopyConvertedFrameDataToArray(_colorData, ColorImageFormat.Bgra); } bodyIndexFrame.CopyFrameDataToArray(_bodyData); CoordinateMapper.MapDepthFrameToColorSpace(_depthData, _colorPoints); Array.Clear(_displayPixels, 0, _displayPixels.Length); for (int y = 0; y < depthHeight; ++y) { for (int x = 0; x < depthWidth; ++x) { int depthIndex = (y * depthWidth) + x; byte player = _bodyData[depthIndex]; if (player != 0xff) { ColorSpacePoint colorPoint = _colorPoints[depthIndex]; int colorX = (int)Math.Floor(colorPoint.X + 0.5); int colorY = (int)Math.Floor(colorPoint.Y + 0.5); if ((colorX >= 0) && (colorX < colorWidth) && (colorY >= 0) && (colorY < colorHeight)) { int colorIndex = ((colorY * colorWidth) + colorX) * Constants.BYTES_PER_PIXEL; int displayIndex = depthIndex * Constants.BYTES_PER_PIXEL; _displayPixels[displayIndex + 0] = _colorData[colorIndex]; _displayPixels[displayIndex + 1] = _colorData[colorIndex + 1]; _displayPixels[displayIndex + 2] = _colorData[colorIndex + 2]; _displayPixels[displayIndex + 3] = 0xff; } } } } _stream.Seek(0, SeekOrigin.Begin); _stream.Write(_displayPixels, 0, _displayPixels.Length); _bitmap.Invalidate(); } return _bitmap; }
/// <summary> /// Updates the bitmap with new frame data. /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="colorFrame">The specified color frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> override public void Update(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { int colorWidth = colorFrame.FrameDescription.Width; int colorHeight = colorFrame.FrameDescription.Height; int depthWidth = depthFrame.FrameDescription.Width; int depthHeight = depthFrame.FrameDescription.Height; int bodyIndexWidth = bodyIndexFrame.FrameDescription.Width; int bodyIndexHeight = bodyIndexFrame.FrameDescription.Height; if (Bitmap == null) { InitBuffers(colorFrame.FrameDescription, depthFrame.FrameDescription, bodyIndexFrame.FrameDescription); } if (((depthWidth * depthHeight) == _depthData.Length) && ((colorWidth * colorHeight * Constants.BYTES_PER_PIXEL) == _colorData.Length) && ((bodyIndexWidth * bodyIndexHeight) == _bodyData.Length)) { depthFrame.CopyFrameDataToArray(_depthData); if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra) { colorFrame.CopyRawFrameDataToArray(_colorData); } else { colorFrame.CopyConvertedFrameDataToArray(_colorData, ColorImageFormat.Bgra); } bodyIndexFrame.CopyFrameDataToArray(_bodyData); CoordinateMapper.MapDepthFrameToColorSpace(_depthData, _colorPoints); Array.Clear(Pixels, 0, Pixels.Length); for (int y = 0; y < depthHeight; ++y) { for (int x = 0; x < depthWidth; ++x) { int depthIndex = (y * depthWidth) + x; if (_bodyData[depthIndex] != 0xff) { ColorSpacePoint colorPoint = _colorPoints[depthIndex]; int colorX = (int)(colorPoint.X + 0.5); int colorY = (int)(colorPoint.Y + 0.5); if ((colorX >= 0) && (colorX < colorWidth) && (colorY >= 0) && (colorY < colorHeight)) { int colorIndex = ((colorY * colorWidth) + colorX) * Constants.BYTES_PER_PIXEL; int displayIndex = depthIndex * Constants.BYTES_PER_PIXEL; for (int b = 0; b < Constants.BYTES_PER_PIXEL; ++b) { Pixels[displayIndex + b] = _colorData[colorIndex + b]; } } } } } UpdateBitmap(); } }
/// <summary> /// Converts the specified depth and infrared frames to a bitmap image with the players highlighted. /// </summary> /// <param name="depthFrame">The specified <see cref="DepthFrame"/>.</param> /// <param name="bodyIndexFrame">The specified <see cref="BodyIndexFrame"/>.</param> /// <returns>The bitmap representation of the current frame.</returns> public static WriteableBitmap ToBitmap(this DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { _depthBitmapGenerator.Update(depthFrame, bodyIndexFrame); return _depthBitmapGenerator.HighlightedBitmap; }
/// <summary> /// Converts a depth frame to the corresponding System.Windows.Media.Imaging.BitmapSource and removes the background (green-screen effect). /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="colorFrame">The specified color frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> /// <returns>The corresponding System.Windows.Media.Imaging.BitmapSource representation of image.</returns> public Bitmap GreenScreen(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { int colorWidth = colorFrame.FrameDescription.Width; int colorHeight = colorFrame.FrameDescription.Height; int depthWidth = depthFrame.FrameDescription.Width; int depthHeight = depthFrame.FrameDescription.Height; int bodyIndexWidth = bodyIndexFrame.FrameDescription.Width; int bodyIndexHeight = bodyIndexFrame.FrameDescription.Height; if (_displayPixels == null) { _depthData = new ushort[depthWidth * depthHeight]; _bodyData = new byte[depthWidth * depthHeight]; _colorData = new byte[colorWidth * colorHeight * Constants.BYTES_PER_PIXEL]; _displayPixels = new byte[depthWidth * depthHeight * Constants.BYTES_PER_PIXEL]; _colorPoints = new ColorSpacePoint[depthWidth * depthHeight]; _bitmap = new Bitmap(depthWidth, depthHeight, Constants.FORMAT); } if (((depthWidth * depthHeight) == _depthData.Length) && ((colorWidth * colorHeight * Constants.BYTES_PER_PIXEL) == _colorData.Length) && ((bodyIndexWidth * bodyIndexHeight) == _bodyData.Length)) { depthFrame.CopyFrameDataToArray(_depthData); if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra) { colorFrame.CopyRawFrameDataToArray(_colorData); } else { colorFrame.CopyConvertedFrameDataToArray(_colorData, ColorImageFormat.Bgra); } bodyIndexFrame.CopyFrameDataToArray(_bodyData); CoordinateMapper.MapDepthFrameToColorSpace(_depthData, _colorPoints); Array.Clear(_displayPixels, 0, _displayPixels.Length); for (int y = 0; y < depthHeight; ++y) { for (int x = 0; x < depthWidth; ++x) { int depthIndex = (y * depthWidth) + x; byte player = _bodyData[depthIndex]; if (player != 0xff) { ColorSpacePoint colorPoint = _colorPoints[depthIndex]; int colorX = (int)Math.Floor(colorPoint.X + 0.5); int colorY = (int)Math.Floor(colorPoint.Y + 0.5); if ((colorX >= 0) && (colorX < colorWidth) && (colorY >= 0) && (colorY < colorHeight)) { int colorIndex = ((colorY * colorWidth) + colorX) * Constants.BYTES_PER_PIXEL; int displayIndex = depthIndex * Constants.BYTES_PER_PIXEL; _displayPixels[displayIndex + 0] = _colorData[colorIndex]; _displayPixels[displayIndex + 1] = _colorData[colorIndex + 1]; _displayPixels[displayIndex + 2] = _colorData[colorIndex + 2]; _displayPixels[displayIndex + 3] = 0xff; } } } } BitmapData bitmapData = _bitmap.LockBits(new Rectangle(0, 0, depthWidth, depthHeight), ImageLockMode.ReadWrite, _bitmap.PixelFormat); Marshal.Copy(_displayPixels, 0, bitmapData.Scan0, _displayPixels.Length); _bitmap.UnlockBits(bitmapData); } return _bitmap; }
/// <summary> /// Removes the background of the specified frames and generates a new bitmap (green-screen effect). /// </summary> /// <param name="depthFrame">The specified <see cref="DepthFrame"/>.</param> /// <param name="colorFrame">The specified <see cref="ColorFrame"/>.</param> /// <param name="bodyIndexFrame">The specified <see cref="BodyIndexFrame"/>.</param> /// <returns>The bitmap representation of the generated frame.</returns> public static WriteableBitmap GreenScreen(this DepthFrame depthFrame, ColorFrame colorFrame, BodyIndexFrame bodyIndexFrame) { _greenScreenBitmapGenerator.Update(colorFrame, depthFrame, bodyIndexFrame); return _greenScreenBitmapGenerator.Bitmap; }
/// <summary> /// Converts a depth frame to the corresponding System.Windows.Media.Imaging.BitmapSource with the players highlighted. /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> /// <returns>The corresponding System.Windows.Media.Imaging.BitmapSource representation of the depth frame.</returns> public static BitmapSource ToBitmap(this DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { _bitmapGenerator.Update(depthFrame, bodyIndexFrame); return _bitmapGenerator.HighlightedBitmap; }
/// <summary> /// Converts a depth frame to the corresponding System.Windows.Media.Imaging.BitmapSource with the players highlighted. /// </summary> /// <param name="depthFrame">The specified depth frame.</param> /// <param name="bodyIndexFrame">The specified body index frame.</param> /// <returns>The corresponding System.Windows.Media.Imaging.BitmapSource representation of the depth frame.</returns> public static BitmapSource ToBitmap(this DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) { ushort minDepth = depthFrame.DepthMinReliableDistance; ushort maxDepth = depthFrame.DepthMaxReliableDistance; if (_bodyData == null) { _width = depthFrame.FrameDescription.Width; _height = depthFrame.FrameDescription.Height; _depthData = new ushort[_width * _height]; _bodyData = new byte[_width * _height]; _pixels = new byte[_width * _height * Constants.BYTES_PER_PIXEL]; _bitmap = new WriteableBitmap(_width, _height, Constants.DPI, Constants.DPI, Constants.FORMAT, null); } depthFrame.CopyFrameDataToArray(_depthData); bodyIndexFrame.CopyFrameDataToArray(_bodyData); // Convert the depth to RGB for (int depthIndex = 0, colorPixelIndex = 0; depthIndex < _depthData.Length && colorPixelIndex < _pixels.Length; depthIndex++, colorPixelIndex += 4) { // Get the depth for this pixel ushort depth = _depthData[depthIndex]; byte player = _bodyData[depthIndex]; // To convert to a byte, we're discarding the most-significant // rather than least-significant bits. // We're preserving detail, although the intensity will "wrap." // Values outside the reliable depth range are mapped to 0 (black). byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0); if (player != 0xff) { // Color player gold. _pixels[colorPixelIndex + 0] = Colors.Gold.B; // B _pixels[colorPixelIndex + 1] = Colors.Gold.G; // G _pixels[colorPixelIndex + 2] = Colors.Gold.R; // R } else { // Color the rest of the image in grayscale. _pixels[colorPixelIndex + 0] = intensity; // B _pixels[colorPixelIndex + 1] = intensity; // G _pixels[colorPixelIndex + 2] = intensity; // R } } _bitmap.Lock(); Marshal.Copy(_pixels, 0, _bitmap.BackBuffer, _pixels.Length); _bitmap.AddDirtyRect(new Int32Rect(0, 0, _width, _height)); _bitmap.Unlock(); return _bitmap; }
public void GreenScreen(ColorFrame colorFrame, DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame) //from https://github.com/Vangos/kinect-2-background-removal { var colorWidth = colorFrame.FrameDescription.Width; var colorHeight = colorFrame.FrameDescription.Height; var depthWidth = depthFrame.FrameDescription.Width; var depthHeight = depthFrame.FrameDescription.Height; var bodyIndexWidth = bodyIndexFrame.FrameDescription.Width; var bodyIndexHeight = bodyIndexFrame.FrameDescription.Height; if (_displayPixels == null) { _depthData = new ushort[depthWidth*depthHeight]; _bodyData = new byte[depthWidth*depthHeight]; _colorData = new byte[colorWidth*colorHeight*_bytesPerPixel]; _displayPixels = new byte[depthWidth*depthHeight*_bytesPerPixel]; _colorPoints = new ColorSpacePoint[depthWidth*depthHeight]; } if (((depthWidth*depthHeight) != _depthData.Length) || ((colorWidth*colorHeight*_bytesPerPixel) != _colorData.Length) || ((bodyIndexWidth*bodyIndexHeight) != _bodyData.Length)) return; depthFrame.CopyFrameDataToArray(_depthData); if (colorFrame.RawColorImageFormat == ColorImageFormat.Bgra) { colorFrame.CopyRawFrameDataToArray(_colorData); } else { colorFrame.CopyConvertedFrameDataToArray(_colorData, ColorImageFormat.Bgra); } bodyIndexFrame.CopyFrameDataToArray(_bodyData); _coordinateMapper.MapDepthFrameToColorSpace(_depthData, _colorPoints); Array.Clear(_displayPixels, 0, _displayPixels.Length); for (var y = 0; y < depthHeight; ++y) { for (var x = 0; x < depthWidth; ++x) { var depthIndex = (y*depthWidth) + x; var player = _bodyData[depthIndex]; if (player == 0xff) continue; var colorPoint = _colorPoints[depthIndex]; var colorX = (int) Math.Floor(colorPoint.X + 0.5); var colorY = (int) Math.Floor(colorPoint.Y + 0.5); if ((colorX < 0) || (colorX >= colorWidth) || (colorY < 0) || (colorY >= colorHeight)) continue; var colorIndex = ((colorY*colorWidth) + colorX)*_bytesPerPixel; var displayIndex = depthIndex*_bytesPerPixel; _displayPixels[displayIndex + 0] = _colorData[colorIndex]; _displayPixels[displayIndex + 1] = _colorData[colorIndex + 1]; _displayPixels[displayIndex + 2] = _colorData[colorIndex + 2]; _displayPixels[displayIndex + 3] = 0xff; } } Array.Clear(BufBytes, 0, BufBytes.Length); //Zerofill array for (var d = 0; d < _displayPixels.Count(); d++) { if (_displayPixels[d] != 0) { BufBytes[d] = MainWindow.InfraPixels[d]; } } }
/// <summary> /// Converts the specified depth and body index frames to a bitmap and saves it to the specified location. /// </summary> /// <param name="depthFrame">The source depth frame.</param> /// <param name="bodyIndexFrame">The source body index frame.</param> /// <param name="destination">The destination path for the image. JPEG, PNG, GIF, BMP and TIFF formats are supported.</param> /// <param name="width">The width of the image file.</param> /// <param name="height">The height of the image file.</param> /// <returns>True if the image was successfully saved. False otherwise.</returns> public static async Task<bool> Save(this DepthFrame depthFrame, BodyIndexFrame bodyIndexFrame, string path, int width, int height) { var bitmap = depthFrame.ToBitmap(bodyIndexFrame); return await _capture.Save(bitmap, path, width, height); }