Kinect學習筆記(六)——深度數據測量技術及應用


一、Kinect視角場

1、43°垂直方向和57°水平方向可視范圍。

image

2、視角場常量值定義

屬性

描述

Format 獲取或設置深度圖像格式
MaxDepth 獲取最大深度值
MinDepth 獲取最小深度值
NominalDiagonalFieldOfView 獲取紅外攝像頭的標准場視角,單位是度
NominalFocalLengthInPixels 獲取紅外攝像頭的標准焦距,單位是像素點
NominalHorizontalFieldOfView 獲取紅外攝像頭的水平視角,單位是度
NominalInverseFocalLengthInPixels 獲取紅外攝像頭的標准焦距的倒數
NominalVerticalFieldOfView 獲取紅外攝像頭的垂直視角,單位為度
Range 設置紅外攝像頭采用“默認模式”還是“近景模式”
TooFarDepth 獲取紅外值有效范圍的最大值,即紅外攝像頭能看到的最遠距離
TooNearDepth 獲取紅外值有效范圍的最小值,即紅外攝像頭能看到的最近距離
UnknownDepth 未知紅外距離的數值

 

image

3、通過骨骼跟蹤對象Skeleton.ClippedEdges的屬性,判斷用戶是否處於Kinect的有效視野范圍內。

     將骨骼跟蹤調節到最佳位置的方法有:

    **用戶移動到有效視野的橫截面中:例如,再Kinect游戲中會提示玩家走近一些

    **通過KinectSensor.ElevationAngle屬性控制Kinect的垂直仰角,改善用戶的有效視角場橫截面。

二、深度值與實際距離的對比

1、深度圖像的每像素占用2字節,同常量DepthImage.BytesPerPiexl的定義,可以用short變量定義這個像素。其中,高13位表示從Kinect紅外攝像頭到最近物體對象的距離,以毫米為單位;低三位表示用戶索引編號,DepthImageFrame.PlayerIndexBitmaskWidth定義了此值。

                                                       image

2、Kinect深度會隨着目標物體的距離而發生偏差,距離越遠偏差越大。

                                                         image

三、深度圖像的直方圖

1、亮度直方圖屬於圖像處理的基本運算,通過它可以提取有效的“亮度”特征。亮度直方圖能體現每個亮度值在圖像中的占有率。利用“亮度”特征值,並基於一定的亮度閥值,可以從果盤中分辨出紅蘿卜和西紅柿。

2、直方圖統計信息的價值

using System;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Microsoft.Kinect;

using System.Windows.Shapes;

namespace KinectDepthHistogram
{
    public partial class MainWindow : Window
    {
        //簡化程序,未做預防性代碼
        KinectSensor sensor = KinectSensor.KinectSensors.First();
        short[] pixelData;

        public MainWindow()
        {
            InitializeComponent();
            
            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            this.Unloaded += new RoutedEventHandler(MainWindow_Unloaded);

            sensor.DepthStream.Enable();
            sensor.DepthFrameReady += new EventHandler<DepthImageFrameReadyEventArgs>(sensor_DepthFrameReady);
        }

        private Int32 depthFrameBehind = 0;

        void sensor_DepthFrameReady(object sender, DepthImageFrameReadyEventArgs e)
        {
            bool receivedData = false;

            using (DepthImageFrame DFrame = e.OpenDepthImageFrame())
            {
                if (DFrame == null)
                {
                    // The image processing took too long. More than 2 frames behind.
                    depthFrameBehind++;
                    labelDepthFrameBehind.Content = depthFrameBehind.ToString();
                }
                else
                {
                    pixelData = new short[DFrame.PixelDataLength];
                    DFrame.CopyPixelDataTo(pixelData);

                    //繪制深度直方圖
                    DrawDepthHistogram(DFrame, pixelData);

                    receivedData = true;
                }
            }

            if (receivedData)
            {
                BitmapSource source = BitmapSource.Create(640, 480, 96, 96,
                        PixelFormats.Gray16, null, pixelData, 640 * 2);

                depthImage.Source = source;
            }
        }

        void MainWindow_Unloaded(object sender, RoutedEventArgs e)
        {
            sensor.Stop();
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            sensor.Start();
        }

 #region DepthHistogram
        //有效視距范圍的閥值: 0.8米到3米
        private const int LowDepthThreshold = 800;
        private const int HighDepthThreshold = 4000;

        /// <summary>
        /// 繪制深度圖像的直方圖
        /// </summary>
        /// <param name="depthFrame"></param>
        /// <param name="pixelData"></param>
        private void DrawDepthHistogram(DepthImageFrame depthFrame, short[] pixelData)
        {
            int depth;
            int[] depths = new int[4096];
            double chartBarWidth = Math.Max(3, DepthHistogram.ActualWidth / depths.Length);
            
            
            //遍歷深度像素數組,並獲取深度值.並統計每一個深度值出現的次數
            for (int i = 0; i < pixelData.Length; i++)
            {
                //前13位為深度值,單位毫米
                depth = pixelData[i] >> DepthImageFrame.PlayerIndexBitmaskWidth;

                //有效視距內的統計
                if (depth >= LowDepthThreshold && depth <= HighDepthThreshold)
                {
                    depths[depth]++;
                }
            }

            int maxValue = 0;
            //查找depth數組中的最大深度值
            for (int i = LowDepthThreshold; i < HighDepthThreshold; i++)
            {
                maxValue = Math.Max(maxValue, depths[i]);
            }


            //繪制直方圖,統計各個深度段的像素個數
            DepthHistogram.Children.Clear();
            for (int i = LowDepthThreshold; i < HighDepthThreshold; i++)
            {
                //顯示有深度數值的
                if (depths[i] > 0)
                {
                    Rectangle r = new Rectangle();
                    r.Fill = Brushes.Green;
                    r.Width = chartBarWidth;
                    r.Height = DepthHistogram.ActualHeight * (depths[i] / (double)maxValue);
                    r.Margin = new Thickness(1, 0, 1, 0);
                    r.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
                    DepthHistogram.Children.Add(r);
                }
            }                        
        }

#endregion
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM