深度数据基础C#样本和读取值 [英] Depth data basics C# sample and reading values

查看:96
本文介绍了深度数据基础C#样本和读取值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我是一般的编程新手。我必须使用Kinect传感器并获取机器人的深度数据。我知道程序运行时,屏幕上的位图会显示强度。但是,我可以获得以毫米为单位的深度,用于
,了解某人与传感器的距离。基本上像超声波传感器,所以我可以说,如果深度小于2000毫米,机器人就会停止。我可以很好地控制机器人,但是如何读取for循环内部的变量深度,即
短?感谢任何试图提供帮助的人。以下是SDK v1.8的深度基本代码:


命名空间Microsoft.Samples.Kinect.DepthBasics 
{
使用系统;
使用System.Globalization;
使用System.IO;使用System.Windows
;
使用System.Windows.Media;
使用System.Windows.Media.Imaging;
使用Microsoft.Kinect;

///< summary>
/// MainWindow.xaml的交互逻辑
///< / summary>
公共部分类MainWindow:Window
{
///< summary>
///有源Kinect传感器
///< / summary>
私人KinectSensor传感器;

///< summary>
///将包含颜色信息的位图
///< / summary>
private WriteableBitmap colorBitmap;

///< summary>
///从相机收到的深度数据的中间存储空间
///< / summary>
private DepthImagePixel [] depthPixels;

///< summary>
///转换为颜色的深度数据的中间存储空间
///< / summary>
private byte [] colorPixels;

///< summary>
///初始化MainWindow类的新实例。
///< / summary>
public MainWindow()
{
InitializeComponent();
}

///< summary>
///执行启动任务
///< / summary>
///< param name =" sender">发送事件的对象< / param>
///< param name =" e">事件参数< / param>
private void WindowLoaded(object sender,RoutedEventArgs e)
{
//查看所有传感器并启动第一个连接的传感器。
//这要求在应用启动时连接Kinect。
//为了使你的应用程序能够强插拔/插拔,
//建议使用Microsoft.Kinect.Toolkit中提供的KinectSensorChooser(参见Toolkit Browser中的组件)。
foreach(kinectSensor.KinectSensors中的var potentialSensor)
{
if(potentialSensor.Status == KinectStatus.Connected)
{
this.sensor = potentialSensor;
休息;
}
}

if(null!= this.sensor)
{
//启用深度流以接收深度帧
this.sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);

//分配空间以放置我们将收到的深度像素
this.depthPixels = new DepthImagePixel [this.sensor.DepthStream.FramePixelDataLength];

//分配空间以放置我们将创建的颜色像素
this.colorPixels = new byte [this.sensor.DepthStream.FramePixelDataLength * sizeof(int)];

//这是我们将在屏幕上显示的位图
this.colorBitmap = new WriteableBitmap(this.sensor.DepthStream.FrameWidth,this.sensor.DepthStream.FrameHeight,96.0, 96.0,PixelFormats.Bgr32,null);

//将我们显示的图像设置为指向我们将图像数据放入的位图
this.Image.Source = this.colorBitmap;

//添加一个事件处理程序,只要有新的深度帧数据就被调用
this.sensor.DepthFrameReady + = this.SensorDepthFrameReady;

//启动传感器!
尝试
{
this.sensor.Start();
}
catch(IOException)
{
this.sensor = null;
}
}

if(null == this.sensor)
{
this.statusBarText.Text = Properties.Resources.NoKinectReady;
}
}

///< summary>
///执行关机任务
///< / summary>
///< param name =" sender">发送事件的对象< / param>
///< param name =" e">事件参数< / param>
private void WindowClosing(object sender,System.ComponentModel.CancelEventArgs e)
{
if(null!= this.sensor)
{
this.sensor.Stop ();
}
}

///< summary>
/// Kinect传感器的DepthFrameReady事件的事件处理程序
///< / summary>
///< param name =" sender">发送事件的对象< / param>
///< param name =" e">事件参数< / param>
private void SensorDepthFrameReady(object sender,DepthImageFrameReadyEventArgs e)
{
using(DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if(depthFrame!= null)
{
//将像素数据从图像复制到临时数组
depthFrame.CopyDepthImagePixelDataTo(this.depthPixels);

//获取当前帧的最小和最大可靠深度
int minDepth = depthFrame.MinDepth;
int maxDepth = depthFrame.MaxDepth;

//将深度转换为RGB
int colorPixelIndex = 0;
for(int i = 0; i< this.depthPixels.Length; ++ i)
{
//获取此像素的深度
short depth = depthPixels [ I] .Depth;

//要转换为字节,我们将丢弃最重要的
//而不是最低有效位。
//我们保留细节,尽管强度将"包裹"。
//可靠深度范围之外的值映射到0(黑色)。

//注意:在此循环中使用条件可能会降低性能。
//在编写生产代码时,请考虑使用查找表。
//有关查找表示例,请参阅KinectExplorer示例
//使用的KinectDepthViewer类。
字节强度=(字节)(深度> = minDepth&& depth< = maxDepth?depth:0);

//写出蓝色字节
this.colorPixels [colorPixelIndex ++] = intensity;

//写出绿色字节
this.colorPixels [colorPixelIndex ++] = intensity;

//写出红色字节
this.colorPixels [colorPixelIndex ++] = intensity;

//我们正在输出BGR,32位的最后一个字节未被使用所以跳过它
//如果我们输出BGRA,我们会在这里写alpha。
++ colorPixelIndex;
}

//将像素数据写入我们的位图
this.colorBitmap.WritePixels(
new Int32Rect(0,0,this.colorBitmap.PixelWidth,this .colorBitmap.PixelHeight),
this.colorPixels,
this.colorBitmap.PixelWidth * sizeof(int),
0);
}
}
}

///< summary>
///处理用户点击屏幕截图按钮
///< / summary>
///< param name =" sender">发送事件的对象< / param>
///< param name =" e">事件参数< / param>
private void ButtonScreenshotClick(object sender,RoutedEventArgs e)
{
if(null == this.sensor)
{
this.statusBarText.Text = Properties.Resources .ConnectDeviceFirst;
返回;
}

//创建一个知道如何保存.png文件的png位图编码器
BitmapEncoder encoder = new PngBitmapEncoder();

//从可写位图创建帧并添加到编码器
encoder.Frames.Add(BitmapFrame.Create(this.colorBitmap));

string time = System.DateTime.Now.ToString(" hh' - 'mm' - 'ss",CultureInfo.CurrentUICulture.DateTimeFormat);

string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);

string path = Path.Combine(myPhotos," KinectSnapshot-" + time +" .png");

//将新文件写入磁盘
try
{
using(FileStream fs = new FileStream(path,FileMode.Create))
{
encoder.Save(fs);
}

this.statusBarText.Text = string.Format(CultureInfo.InvariantCulture," {0} {1}",Properties.Resources.ScreenshotWriteSuccess,path);
}
catch(IOException)
{
this.statusBarText.Text = string.Format(CultureInfo.InvariantCulture," {0} {1}",Properties.Resources .ScreenshotWriteFailed,path);
}
}

///< summary>
///处理近模式组合框的检查或取消选中
///< / summary>
///< param name =" sender">发送事件的对象< / param>
///< param name =" e">事件参数< / param>
private void CheckBoxNearModeChanged(object sender,RoutedEventArgs e)
{
if(this.sensor!= null)
{
//将无法在非Kinect上运行对于Windows设备
尝试
{
if(this.checkBoxNearMode.IsChecked.GetValueOrDefault())
{
this.sensor.DepthStream.Range = DepthRange.Near;
}
else
{
this.sensor.DepthStream.Range = DepthRange.Default;
}
}
catch(InvalidOperationException)
{
}
}
}
}
}

解决方案

深度值为:

 //获取此像素的深度
short depth = depthPixels [i] .Depth;

该像素的可变深度以毫米为单位。如果你想知道图像中心像素的深度(x:320,y:240),你必须找到深度像素数组中的偏移量。

 int index = x + y * 640; 



Hello I am new to programming in general. I have to use the Kinect sensor and get the depth data for a robot. I know that the intensity is shown on the bitmap on our screen when the program runs. However, can I get the depth in millimeters to be used to find out how far someone is from the sensor. Basically like an ultrasonic sensor so that I can say that If depth is less than 2000mm then the robot stops. I can control the robot well but how can I read the variable depth that is inside the for loop that is a short? Thanks to anyone who tries to help. Here is the depth basic code from SDK v1.8:

namespace Microsoft.Samples.Kinect.DepthBasics
{
    using System;
    using System.Globalization;
    using System.IO;
    using System.Windows;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using Microsoft.Kinect;

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        /// <summary>
        /// Active Kinect sensor
        /// </summary>
        private KinectSensor sensor;

        /// <summary>
        /// Bitmap that will hold color information
        /// </summary>
        private WriteableBitmap colorBitmap;

        /// <summary>
        /// Intermediate storage for the depth data received from the camera
        /// </summary>
        private DepthImagePixel[] depthPixels;

        /// <summary>
        /// Intermediate storage for the depth data converted to color
        /// </summary>
        private byte[] colorPixels;

        /// <summary>
        /// Initializes a new instance of the MainWindow class.
        /// </summary>
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Execute startup tasks
        /// </summary>
        /// <param name="sender">object sending the event</param>
        /// <param name="e">event arguments</param>
        private void WindowLoaded(object sender, RoutedEventArgs e)
        {
            // Look through all sensors and start the first connected one.
            // This requires that a Kinect is connected at the time of app startup.
            // To make your app robust against plug/unplug, 
            // it is recommended to use KinectSensorChooser provided in Microsoft.Kinect.Toolkit (See components in Toolkit Browser).
            foreach (var potentialSensor in KinectSensor.KinectSensors)
            {
                if (potentialSensor.Status == KinectStatus.Connected)
                {
                    this.sensor = potentialSensor;
                    break;
                }
            }

            if (null != this.sensor)
            {
                // Turn on the depth stream to receive depth frames
                this.sensor.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
                
                // Allocate space to put the depth pixels we'll receive
                this.depthPixels = new DepthImagePixel[this.sensor.DepthStream.FramePixelDataLength];

                // Allocate space to put the color pixels we'll create
                this.colorPixels = new byte[this.sensor.DepthStream.FramePixelDataLength * sizeof(int)];

                // This is the bitmap we'll display on-screen
                this.colorBitmap = new WriteableBitmap(this.sensor.DepthStream.FrameWidth, this.sensor.DepthStream.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.Image.Source = this.colorBitmap;

                // Add an event handler to be called whenever there is new depth frame data
                this.sensor.DepthFrameReady += this.SensorDepthFrameReady;

                // Start the sensor!
                try
                {
                    this.sensor.Start();
                }
                catch (IOException)
                {
                    this.sensor = null;
                }
            }

            if (null == this.sensor)
            {
                this.statusBarText.Text = Properties.Resources.NoKinectReady;
            }
        }

        /// <summary>
        /// Execute shutdown tasks
        /// </summary>
        /// <param name="sender">object sending the event</param>
        /// <param name="e">event arguments</param>
        private void WindowClosing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (null != this.sensor)
            {
                this.sensor.Stop();
            }
        }

        /// <summary>
        /// Event handler for Kinect sensor's DepthFrameReady event
        /// </summary>
        /// <param name="sender">object sending the event</param>
        /// <param name="e">event arguments</param>
        private void SensorDepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
        {
            using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
            {
                if (depthFrame != null)
                {
                    // Copy the pixel data from the image to a temporary array
                    depthFrame.CopyDepthImagePixelDataTo(this.depthPixels);

                    // Get the min and max reliable depth for the current frame
                    int minDepth = depthFrame.MinDepth;
                    int maxDepth = depthFrame.MaxDepth;

                    // Convert the depth to RGB
                    int colorPixelIndex = 0;
                    for (int i = 0; i < this.depthPixels.Length; ++i)
                    {
                        // Get the depth for this pixel
                        short depth = depthPixels[i].Depth;

                        // 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).

                        // Note: Using conditionals in this loop could degrade performance.
                        // Consider using a lookup table instead when writing production code.
                        // See the KinectDepthViewer class used by the KinectExplorer sample
                        // for a lookup table example.
                        byte intensity = (byte)(depth >= minDepth && depth <= maxDepth ? depth : 0);

                        // Write out blue byte
                        this.colorPixels[colorPixelIndex++] = intensity;

                        // Write out green byte
                        this.colorPixels[colorPixelIndex++] = intensity;

                        // Write out red byte                        
                        this.colorPixels[colorPixelIndex++] = intensity;
                                                
                        // We're outputting BGR, the last byte in the 32 bits is unused so skip it
                        // If we were outputting BGRA, we would write alpha here.
                        ++colorPixelIndex;
                    }

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

        /// <summary>
        /// Handles the user clicking on the screenshot button
        /// </summary>
        /// <param name="sender">object sending the event</param>
        /// <param name="e">event arguments</param>
        private void ButtonScreenshotClick(object sender, RoutedEventArgs e)
        {
            if (null == this.sensor)
            {
                this.statusBarText.Text = Properties.Resources.ConnectDeviceFirst;
                return;
            }

            // create a png bitmap encoder which knows how to save a .png file
            BitmapEncoder encoder = new PngBitmapEncoder();

            // create frame from the writable bitmap and add to encoder
            encoder.Frames.Add(BitmapFrame.Create(this.colorBitmap));

            string time = System.DateTime.Now.ToString("hh'-'mm'-'ss", CultureInfo.CurrentUICulture.DateTimeFormat);

            string myPhotos = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);

            string path = Path.Combine(myPhotos, "KinectSnapshot-" + time + ".png");

            // write the new file to disk
            try
            {
                using (FileStream fs = new FileStream(path, FileMode.Create))
                {
                    encoder.Save(fs);
                }

                this.statusBarText.Text = string.Format(CultureInfo.InvariantCulture, "{0} {1}", Properties.Resources.ScreenshotWriteSuccess, path);
            }
            catch (IOException)
            {
                this.statusBarText.Text = string.Format(CultureInfo.InvariantCulture, "{0} {1}", Properties.Resources.ScreenshotWriteFailed, path);
            }
        }
        
        /// <summary>
        /// Handles the checking or unchecking of the near mode combo box
        /// </summary>
        /// <param name="sender">object sending the event</param>
        /// <param name="e">event arguments</param>
        private void CheckBoxNearModeChanged(object sender, RoutedEventArgs e)
        {
            if (this.sensor != null)
            {
                // will not function on non-Kinect for Windows devices
                try
                {
                    if (this.checkBoxNearMode.IsChecked.GetValueOrDefault())
                    {
                        this.sensor.DepthStream.Range = DepthRange.Near;
                    }
                    else
                    {
                        this.sensor.DepthStream.Range = DepthRange.Default;
                    }
                }
                catch (InvalidOperationException)
                {
                }
            }
        }
    }
}

解决方案

The depth value is :

// Get the depth for this pixel
short depth = depthPixels[i].Depth;

the variable depth is in millimeters for that pixel. If you want to know the depth at a pixel in the center of the image(x:320,y:240), you have to have to find that offset into the array of depthPixels.

int index = x + y * 640;


这篇关于深度数据基础C#样本和读取值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆