3

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

这是 New Frame 事件,然后我尝试发送每一帧;

    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));
                }
            }
        }
    }

更新

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

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;
    }
4

1 回答 1

0

我的建议是将颜色帧存储在位图中,然后通过网络发送这些文件并在视频程序中重新组合它们。我一直在用 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;
                    }
                }

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

于 2013-06-05T19:21:53.777 回答