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

アップデート

次の 2 つの方法を使用して、 を に変換しImageFrameBitmap次にを に変換しBitmapていByte[]ます。これにより、バッファ サイズが ~730600 に減少しました。まだ十分ではありませんが、進歩しています。(出典: Kinect ColorImageFrame を 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;
    }
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 に答える