c# - Kinect 字节流太大

标签 c# wpf networking kinect

我正在尝试流式传输 Kinect 视频数据(只是图像,不是深度/红外),但我发现图像上的默认缓冲区大小非常大 (1228800) 并且无法通过网络发送。我想知道是否有任何方法可以访问较小的数组而不必走编解码器压缩的路线。以下是我声明 Kinect 的方式,我从 Microsoft 示例中获取了该 Kinect;

// Turn on the color stream to receive color frames
this.sensor.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);

// Allocate space to put the pixels we'll receive
this.colorPixels = new byte[this.sensor.ColorStream.FramePixelDataLength];

// This is the bitmap we'll display on-screen
this.colorBitmap = new WriteableBitmap(this.sensor.ColorStream.FrameWidth, 
this.sensor.ColorStream.FrameHeight, 96.0, 96.0, PixelFormats.Bgr32, null);

// Set the image we display to point to the bitmap where we'll put the image data
this.kinectVideo.Source = this.colorBitmap;

// Add an event handler to be called whenever there is new color frame data
this.sensor.ColorFrameReady += this.SensorColorFrameReady;

// Start the sensor!
this.sensor.Start();

这是我尝试发送每一帧的新帧事件;

    private void SensorColorFrameReady(object sender, 
ColorImageFrameReadyEventArgs e)
    {
        using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
        {
            if (colorFrame != null)
            {
                // Copy the pixel data from the image to a temporary array
                colorFrame.CopyPixelDataTo(this.colorPixels);

                // Write the pixel data into our bitmap
                this.colorBitmap.WritePixels(
                    new Int32Rect(0, 0, this.colorBitmap.PixelWidth, 
this.colorBitmap.PixelHeight),
                    this.colorPixels,
                    this.colorBitmap.PixelWidth * sizeof(int),
                    0);

                if (NetworkStreamEnabled)
                {
                networkStream.Write(this.colorPixels, 0, 
                             this.colorPixels.GetLength(0));
                }
            }
        }
    }

更新

我使用以下两种方法将 ImageFrame 转换为 Bitmap,然后将 Bitmap 转换为 Byte[ ]。这使缓冲区大小下降到 ~730600。还不够,但进步了。 (来源:Convert Kinect ColorImageFrame to Bitmap)

public static byte[] ImageToByte(Image img)
    {
        ImageConverter converter = new ImageConverter();
        return (byte[])converter.ConvertTo(img, typeof(byte[]));
    }

    Bitmap ImageToBitmap(ColorImageFrame Image)
    {
        byte[] pixeldata = new byte[Image.PixelDataLength];
        Image.CopyPixelDataTo(pixeldata);
        Bitmap bmap = new Bitmap(Image.Width, Image.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb);
        BitmapData bmapdata = bmap.LockBits(
            new Rectangle(0, 0, Image.Width, Image.Height),
            ImageLockMode.WriteOnly,
            bmap.PixelFormat);
        IntPtr ptr = bmapdata.Scan0;
        Marshal.Copy(pixeldata, 0, ptr, Image.PixelDataLength);
        bmap.UnlockBits(bmapdata);
        return bmap;
    }

最佳答案

我的建议是将色框存储在位图中,然后通过网络发送这些文件并在视频程序中重新组合它们。我一直在用 Kinect 做的一个项目就是这样做的:

//Save to file
                if (skeletonFrame != null)
                {
                    RenderTargetBitmap bmp = new RenderTargetBitmap(800, 600, 96, 96, PixelFormats.Pbgra32);
                    bmp.Render(window.image);

                    JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                    // create frame from the writable bitmap and add to encoder
                    if (skeletonFrame.Timestamp - lastTime > 90)
                    {
                        encoder.Frames.Add(BitmapFrame.Create(bmp));
                        string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
                        string path = "C:your\\directory\\here" + skeletonFrame.Timestamp + ".jpg";
                        using (FileStream fs = new FileStream(path, FileMode.Create))
                        {
                            encoder.Save(fs);
                        }
                        lastTime = skeletonFrame.Timestamp;
                    }
                }

当然,如果您需要它是实时的,您将不会喜欢这个解决方案,而且我认为我的“评论”按钮在赏金之后消失了。

关于c# - Kinect 字节流太大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16947812/

相关文章:

android - 是否可以通过 Wifi 或 TMobile 网络强制网络流量?

c# - 密码保护数据库

c# - 如何判断三角形的三个顶点是循环顺序还是反循环顺序?

c# - 列表列表的组合,使每个组合都有唯一的元素

wpf - 使用附加命令为 ListView 触发双击事件-MVVM

c# - 如何将 wpf 组合框绑定(bind)到所有系统字体大小

c# - 添加自定义控件mvvm caliburn

c# - Visual Studio 2017 社区、Xamarin、WatchOS。无法构建最简单的 watch 应用程序

java - TCP - 如何在本地主机服务器上的两个玩家之间玩 java 游戏

c++ - Qt 和 Boost 套接字库之间的兼容性