Kinect SDK 初探(下)

  • 3170
  • 0
  • 2012-07-31

摘要:Kinect SDK 初探(下)

(接上篇)

這裏 DependencyProperty.Register

使用了第4個參數 PropertyMetadata typeMetadata以前從來沒有看過/用過

new UIPropertyMetadata(
                null, 
                (o, args) =>
                ((TexturedFaceMeshViewer)o).OnKinectChanged((KinectSensor)args.OldValue, (KinectSensor)args.NewValue)));

因為 public class KinectSensorChooser : INotifyPropertyChanged

所以

            var kinectSensorBinding = new Binding("Kinect") { Source = this.sensorChooser };
            this.faceTrackingVisualizer.SetBinding(TexturedFaceMeshViewer.KinectProperty, kinectSensorBinding);

當Kinect 屬性改變的時候, KinectProperty Chaged Handler也跟著會被喚起(我猜的, 這個動作太高級, 我沒有時間去一一的測試)

不管怎麼樣 TexturedFaceMeshViewer.xaml.cs會在測到Kinect的時候喚起

        private void OnKinectChanged(KinectSensor oldSensor, KinectSensor newSensor)
        {
            if (oldSensor != null)
            {
                oldSensor.AllFramesReady -= this.AllFramesReady;

                this.DestroyFaceTracker();
            }

            if (newSensor != null)
            {
                this.faceTracker = new FaceTracker(this.Kinect);

                newSensor.AllFramesReady += this.AllFramesReady;
            }
        }

當TexturedFaceMeshViewer.xaml.cs中AllFramesReady的時候, FaceTracker物件會去Track, 然後UpdateMesh

                        FaceTrackFrame faceTrackFrame = this.faceTracker.Track(
                            this.colorImageFormat,
                            this.colorImage,
                            this.depthImageFormat,
                            this.depthImage,
                            skeletonOfInterest);

                        if (faceTrackFrame.TrackSuccessful)
                        {
                            this.UpdateMesh(faceTrackFrame);

                            // Only display the face mesh if there was a successful track.
                            displayFaceMesh = true;
                        }

這邊FaceTracker.Track最重要的臉部辦識程式碼, 應該是看不到了它藉由FtInterOP.cs和FaceTrackLib.dll溝通, 實作出ContinueTracking和StartTracking兩個函式, 最後把結果塞到IFTResult (this.frame.ResultPtr)

            if (this.trackSucceeded)
            {
                hr = this.faceTrackerInteropPtr.ContinueTracking(ref faceTrackSensorData, headPointsObj, this.frame.ResultPtr);
            }
            else
            {
                hr = this.faceTrackerInteropPtr.StartTracking(
                    ref faceTrackSensorData, ref regionOfInterest, headPointsObj, this.frame.ResultPtr);
            }

 

TexturedFaceMeshViewer.xaml.cs的UpdateMesh把結果轉成 WPF 3D的臉部模型 (那模型的貼圖材質是在那裏設的呢?)

找到了

在TexturedFaceMeshViewer.xaml.cs的AllFramesReady 其中一段

                if (this.colorImageWritableBitmap == null)
                {
                    this.colorImageWritableBitmap = new WriteableBitmap(
                        colorImageFrame.Width, colorImageFrame.Height, 96, 96, PixelFormats.Bgr32, null);
                    this.ColorImage.Source = this.colorImageWritableBitmap;
                    this.theMaterial.Brush = new ImageBrush(this.colorImageWritableBitmap)
                        {
                           ViewportUnits = BrushMappingMode.Absolute 
                        };
                }

這裏把theMeterial從本來的GradientBrush改成ImageBrush 所以模型上就有從ColorStream來的臉部的貼圖

(待續)

 

Rz

 

 

 

  Rz     should work (hard)