深度数据基础C#样本和读取值 [英] Depth data basics C# sample and reading values
问题描述
您好,我是一般的编程新手。我必须使用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屋!