Buenas,
After the first 2 posts
- [# KINECT] HowTo: Use Face Recognition with # KinectSdk (I)
http://elbruno.com/2012/07/31/kinect-HOWTO-Utilizar-face-recognition-con-kinectsdk-i/ - [# KINECT] HowTo: Use Face Recognition with # KinectSdk (II)
http://elbruno.com/2012/08/07/kinect-HOWTO-Utilizar-face-recognition-con-kinectsdk-II/
Today we will see how to modify the “network” that is drawn in our face using the example from the previous post. Reviewing a little how is it mounted, we see that the UserControl [FaceTracking.xaml] is showing the network with the face on an image which shows the output of the camera of the Kinect sensor.
To paint the network, the [SkeletonFaceTracker.cs] class uses the routine DrawFaceModel()which creates a collection of triangles and then paints them.
1: public void DrawFaceModel(DrawingContext drawingContext)
2: {
3: if (!LastFaceTrackSucceeded || _skeletonTrackingState != SkeletonTrackingState.Tracked)
4: {
5: _startFaceRecognition = DateTime.MinValue;
6: return;
7: }
8:
9: var faceModelPts = _facePoints.Select(t => new Point(t.X + 0.5f, t.Y + 0.5f)).ToList();
10:
11: var faceModel = _faceTriangles.Select(t => new FaceModelTriangle
12: {
13: P1 = faceModelPts[t.First],
14: P2 = faceModelPts[t.Second],
15: P3 = faceModelPts[t.Third]
16: }).ToList();
17:
18: var faceModelGroup = new GeometryGroup();
19: for (var i = 0; i < faceModel.Count; i++)
20: {
21: var faceTriangle = new GeometryGroup();
22: faceTriangle.Children.Add(new LineGeometry(faceModel[i].P1, faceModel[i].P2));
23: faceTriangle.Children.Add(new LineGeometry(faceModel[i].P2, faceModel[i].P3));
24: faceTriangle.Children.Add(new LineGeometry(faceModel[i].P3, faceModel[i].P1));
25: faceModelGroup.Children.Add(faceTriangle);
26: }
27:
28: drawingContext.DrawGeometry(Brushes.BlueViolet, new Pen(Brushes.Red, 1.0), faceModelGroup);
29: if (_startFaceRecognition == DateTime.MinValue)
30: {
31: _startFaceRecognition = DateTime.Now;
32: }
33: else
34: {
35: if (DateTime.Now.Subtract(_startFaceRecognition).TotalSeconds > 5)
36: {
37: Application.Current.Dispatcher.BeginInvoke(new Action(() =>
38: {
39: System.Threading.Thread.Sleep(300);
40: _startFaceRecognition = DateTime.MinValue;
41: }));
42: }
43: }
44: }
For the slightly improving of this example, rather than painting the network on the face, what we will do is paint points and also at every point put the number of the same. What we do is create a new function called with the following code.
1: public void DrawFaceFlat(DrawingContext drawingContext)
2: {
3: if (!LastFaceTrackSucceeded || _skeletonTrackingState != SkeletonTrackingState.Tracked)
4: {
5: _startFaceRecognition = DateTime.MinValue;
6: return;
7: }
8:
9: var faceModelPts = _facePoints.Select(t => new Point(t.X + 0.5f, t.Y + 0.5f)).ToList();
10:
11: var faceModelGroup = new GeometryGroup();
12: for (var i = 0; i < faceModelPts.Count; i++)
13: {
14: var geometryGroup = new GeometryGroup();
15: var ellipseGeometry = new EllipseGeometry(faceModelPts[i], 1, 1);
16:
17: var formattedText = new FormattedText(i.ToString(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
18: new Typeface("Verdana"), 12, Brushes.White);
19: geometryGroup.Children.Add(ellipseGeometry);
20: faceModelGroup.Children.Add(geometryGroup);
21: }
22:
23: drawingContext.DrawGeometry(Brushes.Yellow, new Pen(Brushes.Yellow, 1.0), faceModelGroup);
24:
25: for (var i = 0; i < faceModelPts.Count; i++)
26: {
27: var formattedText = new FormattedText(i.ToString(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface("Verdana"), 8, Brushes.White);
28: drawingContext.DrawText(formattedText, faceModelPts[i]);
29: }
30:
31: if (_startFaceRecognition == DateTime.MinValue)
32: {
33: _startFaceRecognition = DateTime.Now;
34: }
35: else
36: {
37: if (DateTime.Now.Subtract(_startFaceRecognition).TotalSeconds > 5)
38: {
39: Application.Current.Dispatcher.BeginInvoke(new Action(() =>
40: {
41: System.Threading.Thread.Sleep(300);
42: _startFaceRecognition = DateTime.MinValue;
43: }));
44: }
45: }
46: }
Then change the invocation in [FaceTracking.xaml] use this routine and the result is as follows.
Now however, as there are too many points to display in a space so small, will apply a filter to only keypad points
var pointFilter = new List < int > {4, 8, 39, 41, 42, 48, 54, 68, 86, 74, 80, 57, 51};
the result is a little more sympathetic…
Saludos @ La Finca
El Bruno
Hi there would
you mind sharing which blog platform you’re using? I’m looking to start my own blog soon but I’m having a
difficult time making a decision between
BlogEngine/Wordpress/B2evolution and Drupal. The reason I ask is because your
design seems different then most blogs and I’m looking for
something unique. P.S Sorry
for being off-topic but I had to ask!
This blog is using wordpress. Check http://www.wordpress.com.
Regards
Buenas Bruno,
Have you tried to perform face recognition using the KinectSdk?
I’ve tried a simple algorithm that calculates the euclidean distance of all face points tracked by Kinect, but I haven’t achieved very good results. Only about 60% successful user identification. I would be grateful if you could help me out.
Cheers and keep up the good work!
Hi Bruno,
if i try your example the drawn facemodel is displaced.
I am using the Kinect for XBox with the SDK 1.6
thanks for help
Him you can use the sample included in the Kinect Developer Toolkit. Is a much better upgrade from my original post
regards
/Bruno
Thanks Bruno.
It works perfect for me with the sample from the SDK.