摘要: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來的臉部的貼圖
(待續)
![]() |
|
