Archive for category Code Sample
[#VISUALSTUDIO2010] HowTo: Dar formato a los XAMLs con un atributo por línea
Publicado por elbruno en Code Sample, Visual Studio 2010 el 30 diciembre, 2011
Buenas,
me lo voy a apuntar ahora que me lo han mostrado 10 veces, porque si no me mareo. El tema es el siguiente, cuando te peleas con WPF, Silverlight, o alguna otra tecnología que haga un uso excesivo de formatos con etiquetas, pues el tema de la edición en modo texto puede ser bastante complicado. Una gran solución “visual” para estos casos es aprovechar el formateo que nos ofrece Visual Studio, donde se separa un atributo por línea. Esta opción se activa desde el menú [Tools // Options], en la sección [Text Editor // XAML // Formatting // Spacing] seleccionado la opción [Position each attribute on separate line]
Por ejemplo, volviendo al ejemplo que publiqué hace 2 días podemos ver parte del XAML con este formato
1: <TextBlock Text="Merry Christmas" Grid.Row="0" Grid.Column="1" FontSize="24" Foreground="White"
2: FontFamily="Segoe UI Semilight" FontWeight="Bold" Margin="0" HorizontalAlignment="Center" />
3: <Canvas x:Name="canvasContent" Margin="10,10,0,0" Grid.Row="0" Grid.Column="0" Grid.RowSpan="2">
4: <Grid Grid.Column="1" Grid.Row="1"><Border BorderThickness="3" BorderBrush="White" CornerRadius="10"
5: Padding="2" HorizontalAlignment="Center" VerticalAlignment="Center"> <Grid>
6: <Border x:Name="mask" Background="White" CornerRadius="7" /> <StackPanel><StackPanel.OpacityMask>
7: <VisualBrush Visual="{Binding ElementName=mask}" /></StackPanel.OpacityMask><Image x:Name="CameraViewer"
8: Stretch="UniformToFill" MaxWidth="640" MaxHeight="480" /></StackPanel></Grid></Border></Grid>
O después de un Ctrl+k, Ctrl+d, lo vemos de una forma más “natural”
1: <TextBlock Text="Merry Christmas"
2: Grid.Row="0"
3: Grid.Column="1"
4: FontSize="24"
5: Foreground="White"
6: FontFamily="Segoe UI Semilight"
7: FontWeight="Bold"
8: Margin="0"
9: HorizontalAlignment="Center" />
10: <Canvas x:Name="canvasContent"
11: Margin="10,10,0,0"
12: Grid.Row="0"
13: Grid.Column="0"
14: Grid.RowSpan="2">
15: <Grid Grid.Column="1"
16: Grid.Row="1">
17: <Border BorderThickness="3"
18: BorderBrush="White"
19: CornerRadius="10"
20: Padding="2"
21: HorizontalAlignment="Center"
22: VerticalAlignment="Center">
23: <Grid>
24: <Border x:Name="mask"
25: Background="White"
26: CornerRadius="7" />
27: <StackPanel>
28: <StackPanel.OpacityMask>
29: <VisualBrush Visual="{Binding ElementName=mask}" />
30: </StackPanel.OpacityMask>
31: <Image x:Name="CameraViewer"
32: Stretch="UniformToFill"
33: MaxWidth="640"
34: MaxHeight="480" />
35: </StackPanel>
36: </Grid>
37: </Border>
38: </Grid>
39: <ContentControl x:Name="contentControlHat1">
40: <Image x:Name="imageHat1"
41: Width="64"
42: Height="64"
43: Source="/ElBruno.KinectViewer;component/Images/santa-hat.png"
44: Visibility="Hidden" />
45: </ContentControl>
Ojo, que sobre gustos no hay nada escrito y tal vez esta opción a más de uno no le guste, pues bien … aquí hay una opción para probar y elegir.
Saludos @ Home
El Bruno
[#KINECT] Merry Christmas with Kinect and Visual Studio 2010 (gift of the Valentino)
Publicado por elbruno en Code Sample, CodePlex, Kinect, Visual Studio 2010 el 28 diciembre, 2011
Hi,
in these days of festivities, when you join the side 2 dwarves wanting to play, you got the kinect connected to the PC and the SDK that you strange, at the very least you get is something like the following:
An application for every person that appears on WebCam puts a Santa Claus Cap!!!!
Disclaimer: as they can be seen in the screenshot, in addition to the view of the WebCam I am showing the skeleton, but just as he gave a ray of sunshine to my dwarf in the arm, therefore not recognized him!
As well, after several post about Kinect, today the challenge was as follows
- identify the specific joint of the head of each skeleton
- calculate the relative coordinates of that joint before an image of the webcam
- paint a Santa Hat on webcam
The first point is easily solved once we iteramos by the skeletons recognized in mode Trackeable (lines 6 to 9), we can iterate between the Joints of the skeleton and verify that it is the head compared with [JointID.Head] (line 17).
Once identified the head Joint we come to the 2nd point which is a bit more complicated. Function GetDisplayPosition() (line 27) is in charge for the conversion of the position of the Joint to relative location in the image. The following capabilities of the SDK are used to this
- SkeletonEngine.SkeletonToDepthImage () using this function we can know the relative location in “depth” of a joint.
- NuiCamera.GetColorPixelCoordinatesFromDepthPixel () using this function, we can discover the position at coordinates x/Y from the depth we obtained earlier.
In both cases, it must make some adjustments on the one hand the webcam image is 640 * 480 resolution and depth capacity is only 320 * 240. But hey, with these few lines already we can define the specific location of our head and paint a SantaHat therein.
1: void KinectSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
2: {
3: canvasSkeleton.Children.Clear();
4: this.HideImageHats();
5: var skeletonId = 0;
6: foreach (var skeleton in e.SkeletonFrame.Skeletons.Where
7: (skeleton =>
8: SkeletonTrackingState.Tracked == skeleton.TrackingState))
9: {
10: skeletonId++;
11: this.DisplayImageHats(skeletonId);
12: PaintBones(skeleton);
13: PaintJoints(skeleton);
14:
15: foreach (Joint joint in skeleton.Joints)
16: {
17: if (joint.ID != JointID.Head)
18: {
19: continue;
20: }
21: var newPosition = this.GetDisplayPosition(joint);
22: this.MoveImageHats(newPosition, skeletonId);
23: }
24: }
25: }
26:
27: private Point GetDisplayPosition(Joint joint)
28: {
29: float depthX, depthY;
30: kinect.SkeletonEngine.SkeletonToDepthImage(joint.Position, out depthX, out depthY);
31: depthX = Math.Max(0, Math.Min(depthX * 320, 320));
32: depthY = Math.Max(0, Math.Min(depthY * 240, 240));
33: int colorX, colorY;
34: var iv = new ImageViewArea();
35: kinect.NuiCamera.GetColorPixelCoordinatesFromDepthPixel(ImageResolution.Resolution640x480, iv, (int)depthX, (int)depthY, (short)0, out colorX, out colorY);
36: var newX = (int)(CameraViewer.ActualWidth * colorX / 640.0) - 30;
37: var intY = (int)(CameraViewer.ActualHeight * colorY / 480) - 30;
38: return new Point(newX, intY);
39: }
This time I changed the mode of publication and if you want to download the code can do since CodePlex fromhttp://kinectmerrychristmas.codeplex.com/ .
If you already have a Kinect, SDK and wanted to test the application, you can install it directly fromhttp://kinectmerrychristmas.codeplex.com/releases/79524/clickOnce/ElBruno.MerryChristmas.application
Greetings @ Home and Merry Christmas
The Bruno
References:
- Kinect References
http://elbruno.com/category/MSN-Microsoft/kinect/ - CodePlext Project
http://kinectmerrychristmas.codeplex.com/ - CodePlex ClickOnce Publising
http://geeks.Ms/blogs/elbruno/archive/2010/12/06/vs2010-publicando-Aplicaciones-con-ClickOnce-en-CodePlex-sistema-de-distribuci-243-n-gratis-como-el-Aire.aspx
[#KINECT] Merry Christmas with Kinect and Visual Studio 2010 (regalo del Valentino)
Publicado por elbruno en Code Sample, CodePlex, Kinect, Visual Studio 2010 el 28 diciembre, 2011
Buenas,
en estos días de fiestas, cuando se te juntan al lado 2 enanos con ganas de jugar, tenes el kinect conectado al PC y el SDK que te extraña, pues lo menos que te sale es algo como lo siguiente:
¡¡¡ Una aplicación que para cada persona que aparece en la WebCam le pone un gorro de Santa Claus !!!
Disclaimer: como pueden ver en el screenshot, además de la vista de la WebCam estoy mostrando el skeleton, pero como justo le dió un rayo de sol a mi enana en el brazo, pues no lo reconoció !!!
Pues bien, después de varios post sobre Kinect, hoy el desafío consistía en lo siguiente
- identificar el joint específico de la cabeza de cada skeleton
- calcular las coordenadas relativas de ese joint frente a la imagen de la webcam
- pintar un Santa Hat en la webcam
El primer punto se soluciona fácilmente, ya que una vez que iteramos por los skeletons reconocidos en modo Trackeable (líneas 6 a 9), podemos iterar entre los Joints del skeleton y verificar que el mismo sea el de la cabeza comparando con [JointID.Head] (línea 17).
Una vez identificado el Joint de la cabeza pasamos al 2do punto que es un poco más complicado. La función GetDisplayPosition() (línea 27), es la encargada de realizar la conversión de la posición del Joint a la ubicación relativa en la imagen. Para esto se utilizan las siguientes capacidades del SDK
- SkeletonEngine.SkeletonToDepthImage() utilizando esta función podemos conocer la ubicación relativa en “depth” de un joint.
- NuiCamera.GetColorPixelCoordinatesFromDepthPixel() utilizando esta función, podemos descubrir la posición en coordenadas X/Y a partir del depth que obtuvimos antes.
En ambos casos, hay que hacer algunos ajustes ya que por un lado la imagen de la webcam está en resolución de 640*480 y la capacidad de depth es solo de 320*240. Pero bueno, con estas pocas líneas ya podemos definir la ubicación específica de nuestra cabeza y pintar un SantaHat en el mismo.
1: void KinectSkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
2: {
3: canvasSkeleton.Children.Clear();
4: this.HideImageHats();
5: var skeletonId = 0;
6: foreach (var skeleton in e.SkeletonFrame.Skeletons.Where
7: (skeleton =>
8: SkeletonTrackingState.Tracked == skeleton.TrackingState))
9: {
10: skeletonId++;
11: this.DisplayImageHats(skeletonId);
12: PaintBones(skeleton);
13: PaintJoints(skeleton);
14:
15: foreach (Joint joint in skeleton.Joints)
16: {
17: if (joint.ID != JointID.Head)
18: {
19: continue;
20: }
21: var newPosition = this.GetDisplayPosition(joint);
22: this.MoveImageHats(newPosition, skeletonId);
23: }
24: }
25: }
26:
27: private Point GetDisplayPosition(Joint joint)
28: {
29: float depthX, depthY;
30: kinect.SkeletonEngine.SkeletonToDepthImage(joint.Position, out depthX, out depthY);
31: depthX = Math.Max(0, Math.Min(depthX * 320, 320));
32: depthY = Math.Max(0, Math.Min(depthY * 240, 240));
33: int colorX, colorY;
34: var iv = new ImageViewArea();
35: kinect.NuiCamera.GetColorPixelCoordinatesFromDepthPixel(ImageResolution.Resolution640x480, iv, (int)depthX, (int)depthY, (short)0, out colorX, out colorY);
36: var newX = (int)(CameraViewer.ActualWidth * colorX / 640.0) - 30;
37: var intY = (int)(CameraViewer.ActualHeight * colorY / 480) - 30;
38: return new Point(newX, intY);
39: }
Saludos @ Home y Merry Christmas
El Bruno
Referencias:
- Kinect References
http://elbruno.com/category/msn-microsoft/kinect/ - CodePlext Project
http://kinectmerrychristmas.codeplex.com/ - CodePlex ClickOnce Publising
http://geeks.ms/blogs/elbruno/archive/2010/12/06/vs2010-publicando-aplicaciones-con-clickonce-en-codeplex-sistema-de-distribuci-243-n-gratis-como-el-aire.aspx
[UNITY] Working with Singleton using # UNITY
Publicado por elbruno en Code Sample, Patterns & Practices, Unity, Visual Studio 2010 el 5 diciembre, 2011
Good,
a few days ago, Jorge wrote an article gutting the functioning of a Singleton with.NET. Then came Joseph and also did a bit of light on the matter; and I thought to myself,
But they that speak? programming a Singleton by hand, are crazy or what?
We are going to from Edu defined to UNITY that makes the news"because I believe that I have not created an object with"new"for quite some time. For those who do not know UNITY, because in a nutshell is a dependency injector created by the team of Patterns & Practices by Microsoft which is now in its 2.0 version and, to the dark beer, you’re liking when hold you you the taste.
We see a very, very simple example in which we will use a class called "ClaseChorra" to validate instances that are created the same.
The Singleton model is based on the simple example which explains Jorge in his post.
1: class ClaseChorra
2: {
3: private static ClaseChorra claseChorra;
4: public System.Guid Id { get; set; }
5: public ClaseChorra()
6: {
7: Id = System.Guid.NewGuid();
8: }
9: public override string ToString()
10: {
11: return Id.ToString();
12: }
13: public static ClaseChorra GetSingletonInstance()
14: {
15: return claseChorra ?? (claseChorra = new ClaseChorra());
16: }
17: }
Before proceeding > > Disclaimer: is now in Spain Luernes (Monday + Friday) so either I am working much with examples, is what usually happens after a hard week of work.
Does not need to explain that if I think cholón objects, as explained Jorge in his post, because I have very mixed errors.
For example the following code let me a single instance with the same ID for each run of the same:
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: var c1 = ClaseChorra.GetSingletonInstance();
6: var c2 = ClaseChorra.GetSingletonInstance();
7: c2.Id = Guid.NewGuid();
8: Console.WriteLine("c1: {0}", c1);
9: Console.WriteLine("c2: {0}", c2);
10: Console.ReadLine();
11: }
12: }
The result is:
1: c1: 34baaf27-87de-42f7-b2ad-046e35ee65fa
2: c2: 34baaf27-87de-42f7-b2ad-046e35ee65fa
Well well, here the example of George. But how are we would with UNITY?. Ideally, read the article from MSDN "Using Lifetime Managers" where explains different options to work with record types and objects in Unity. I’ll leave a couple of examples.
For example, in the following piece of code, I’m defining a UnityContainer so that it is responsible for creating the objects I need for me (remember the words of the Edu > "UNITY is the news"). Using the container I think instances c1 and c2 and then show the same values.
1: static void Main(string[] args)
2: {
3: var myContainer = new UnityContainer();
4: myContainer.RegisterType<ClaseChorra>();
5: var c1 = myContainer.Resolve<ClaseChorra>();
6: var c2 = myContainer.Resolve<ClaseChorra>();
7: c2.Id = Guid.NewGuid();
8: Console.WriteLine("c1: {0}", c1);
9: Console.WriteLine("c2: {0}", c2);
10: Console.ReadLine();
11: }
The result are 2 different of the same class instances:
1: c1: dea932a8-7ce6-4f44-aa6c-89cb04bed186
2: c2: 011f211a-9a83-463d-81ea-566ef0dbbdab
Now, if I wanted that long to create an object of type ClaseChorra, it is the same instance for all, because simply I tell UnityContainer LifeTimeManager type should be used. There are several options, but for the next example will use a PerThread, which helps us to have a single instance of the object by thread.
1: static void Main(string[] args)
2: {
3: var myContainer = new UnityContainer();
4: myContainer.RegisterType<ClaseChorra>(new PerThreadLifetimeManager());
5: var c1 = myContainer.Resolve<ClaseChorra>();
6: var c2 = myContainer.Resolve<ClaseChorra>();
7: c2.Id = Guid.NewGuid();
8: Console.WriteLine("c1: {0}", c1);
9: Console.WriteLine("c2: {0}", c2);
10: Console.ReadLine();
11: }
As well you will be assuming, now the c1 and c2 classes are the same:
1: c1: 84b8087b-48f5-4519-9362-b5239603ac0a
2: c2: 84b8087b-48f5-4519-9362-b5239603ac0a
So now you know, or you get to encode all the Singleton pattern super sure in your code and leave that "UNITY makes the news por tí" ![]()
Greetings @ Home
The Bruno
Sources:
[UNITY] Trabajando con Singleton utilizando #UNITY
Publicado por elbruno en Code Sample, Patterns & Practices, Unity, Visual Studio 2010 el 5 diciembre, 2011
Buenas,
hace unos días, Jorge escribió un artículo destripando el funcionamiento de un Singleton con .Net. Luego llegó José y también aportó un poco de luz al respecto; y yo me dije a mi mismo,
¿Pero estos de que hablan? programar un Singleton a mano, están locos o qué?
Vamos que desde el Edu definió a UNITY como “ese que hace los news” pues creo que no he creado un objeto con “new” desde hace bastante tiempo. Para los que no conocen UNITY, pues en pocas palabras es un inyector de dependencias creado por el equipo de Patterns & Practices de Microsoft que ya va por su versión 2.0 y que, como a la cerveza negra, te termina gustando cuando le agarras el gustito.
Veamos un ejemplo muy pero muy simple en el que utilizaremos una clase llamada “ClaseChorra” para validar las instancias que se creen de la misma.
El modelo de Singleton está basado en el ejemplo simple que explica Jorge en su post.
1: class ClaseChorra
2: {
3: private static ClaseChorra claseChorra;
4: public System.Guid Id { get; set; }
5: public ClaseChorra()
6: {
7: Id = System.Guid.NewGuid();
8: }
9: public override string ToString()
10: {
11: return Id.ToString();
12: }
13: public static ClaseChorra GetSingletonInstance()
14: {
15: return claseChorra ?? (claseChorra = new ClaseChorra());
16: }
17: }
Antes de seguir >> Disclaimer: Hoy en España es Luernes (lunes + viernes) con lo que tampoco me estoy esforzando mucho con los ejemplos, es lo que suele suceder después de una semana ardua de trabajo.
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: var c1 = ClaseChorra.GetSingletonInstance();
6: var c2 = ClaseChorra.GetSingletonInstance();
7: c2.Id = Guid.NewGuid();
8: Console.WriteLine("c1: {0}", c1);
9: Console.WriteLine("c2: {0}", c2);
10: Console.ReadLine();
11: }
12: }
El resultado es:
1: c1: 34baaf27-87de-42f7-b2ad-046e35ee65fa
2: c2: 34baaf27-87de-42f7-b2ad-046e35ee65fa
Pues bien, hasta aquí el ejemplo de Jorge. Pero ¿cómo lo haríamos con UNITY?. Lo ideal es leer el artículo de MSDN “Using Lifetime Managers” donde se explican diferentes opciones para trabajar con el registro de tipos y de objetos en Unity. Yo dejaré un par de ejemplos.
Por ejemplo, en la siguiente porción de código, estoy definiendo un UnityContainer para que el mismo se encargue de crear por mí los objetos que yo necesito (recuerden las palabras del Edu > “UNITY es el que hace los news"). Utilizando el container creo las instancias c1 y c2 y luego muestro los valores de la misma.
1: static void Main(string[] args)
2: {
3: var myContainer = new UnityContainer();
4: myContainer.RegisterType<ClaseChorra>();
5: var c1 = myContainer.Resolve<ClaseChorra>();
6: var c2 = myContainer.Resolve<ClaseChorra>();
7: c2.Id = Guid.NewGuid();
8: Console.WriteLine("c1: {0}", c1);
9: Console.WriteLine("c2: {0}", c2);
10: Console.ReadLine();
11: }
El resultado son 2 instancias diferentes de la misma clase:
1: c1: dea932a8-7ce6-4f44-aa6c-89cb04bed186
2: c2: 011f211a-9a83-463d-81ea-566ef0dbbdab
Ahora bien, si yo quisiese que siempre que se cree un objeto del tipo ClaseChorra, el mismo sea la misma instancia para todos, pues simplemente le digo a UnityContainer que tipo de LifeTimeManager debe utilizar. Existen varias opciones, pero para el siguiente ejemplo utilizaremos un PerThread, que nos ayuda a tener una única instancia del objeto por thread.
1: static void Main(string[] args)
2: {
3: var myContainer = new UnityContainer();
4: myContainer.RegisterType<ClaseChorra>(new PerThreadLifetimeManager());
5: var c1 = myContainer.Resolve<ClaseChorra>();
6: var c2 = myContainer.Resolve<ClaseChorra>();
7: c2.Id = Guid.NewGuid();
8: Console.WriteLine("c1: {0}", c1);
9: Console.WriteLine("c2: {0}", c2);
10: Console.ReadLine();
11: }
Como bien estarás suponiendo, ahora las clases c1 y c2 son la misma:
1: c1: 84b8087b-48f5-4519-9362-b5239603ac0a
2: c2: 84b8087b-48f5-4519-9362-b5239603ac0a
Así que ya sabes, o te pones a codificar todo el patrón Singleton super-sure en tu código y dejas que “UNITY haga los news por tí” ![]()
Saludos @ Home
El Bruno
Fuentes:
[# KINECT] Let’s look a little information about how the depth sensor works
Publicado por elbruno en Code Sample, Kinect, Visual Studio 2010 el 21 noviembre, 2011
Good,
After the small post I wrote 2 days ago [# KINECT] HowTo: display the contents of the depth sensor in our applications, today we will see a little more detail or the guts of this mechanism. As well as the camera viewfinder is simply map of RGB values that convert to an image and then we show with an IMAGE of WPF, the information that gives us the depth sensor is a collection of distances that then "we paint" in our application.
The distances that handles Kinect ranges from 0.85 m to 4 m; and the information that we provide the depth sensor in millimeters. If we look at the code from the example of the post, we see that during the processing of the event DepthFrameReady() of the sensor, we work with an object of type PlanarImage (line 3). In this case the array of pixels that we return the sensor contains 2 bytes for every pixel. Each of these bytes determined us the distance to each of the cameras used the sensor.
1: void KinectDepthFrameReady(object sender, ImageFrameReadyEventArgs e)
2: {
3: var planarImage = e.ImageFrame.Image;
4: var depthImageHelper = new DepthImageHelper();
5: byte[] convertedDepthBits =
6: depthImageHelper.ConvertDepthFrame(planarImage.Bits, RuntimeOptions);
7: if (this.imageHelper == null)
8: {
9: this.imageHelper = new InteropBitmapHelper(planarImage.Width,
10: planarImage.Height,
11: convertedDepthBits);
12: this.DepthSensorViewer.Source = this.imageHelper.InteropBitmap;
13: }
14: else
15: {
16: this.imageHelper.UpdateBits(convertedDepthBits);
17: }
18: }
In addition, if we initialized the sensor with the option [DepthAndPlayerIndex], the array of information will contain 3 bytes where the 3rd byte corresponds to a specific player recognized by the sensor.
To identify the real value of the depth of each element of the array, we need to check if the sensor has been initialized with the option to [Depth] or [DepthAndPlayerIndex]. In the example of the post, we do from a simple calculation taking into account if we work with 3 or 2 bytes. In this case depthFrame is an array of bytes that we then convert to an image using the InteropBitmapHelper class we saw in the previous post.
1: var hasPlayerData = runtimeOptions.HasFlag(RuntimeOptions.UseDepthAndPlayerIndex);
2: for (int i16 = 0, i32 = 0; i16 < depthFrame16.Length && i32 < depthFrame32.Length; i16 += 2, i32 += 4)
3: {
4: var player = hasPlayerData ? depthFrame16[i16] & 0x07 : -1;
5: int realDepth;
6:
7: if (hasPlayerData)
8: {
9: realDepth = (depthFrame16[i16 + 1] << 5) | (depthFrame16[i16] >> 3);
10: }
11: else
12: {
13: realDepth = (depthFrame16[i16 + 1] <<| (depthFrame16[i16]);
14: }
15:
16: // transform 13-bit depth information into an 8-bit intensity appropriate
17: // for display (we disregard information in most significant bit)
18: var intensity = (byte)(255 - (255 * realDepth / 0x0fff));
19:
20: depthFrame32[i32 + RedIndex] = 0;
21: depthFrame32[i32 + GreenIndex] = 0;
22: depthFrame32[i32 + BlueIndex] = 0;
The great lack at this point, is to know the depth of a Joint or an element of the Skeleton in order to have access to gesturas as a Push or Pull.
Unfortunately that doesn’t come from factory in Kinect Beta 2 SDK , but…. isn’t so complicated no?
In the next post about Kinect solve it with 4 lines of code (that if the Victor returns me the Kinect!)
Greetings @ Home
The Bruno
PS: I have finished writing the post, but I see that on the challenges of MSDN they explain very, very well!http://blogs.msdn.com/b/esmsdn/archive/2011/07/20/Reto-kinect-Usar-Las-c-225-maras-del-sensor.aspx
[#KINECT] Veamos un poco de información sobre como funciona el sensor de profundidad
Publicado por elbruno en Code Sample, Kinect, Visual Studio 2010 el 21 noviembre, 2011
Buenas,
después del pequeño post que escribí hace 2 días [#KINECT] HowTo: Mostrar el contenido del depth sensor en nuestras aplicaciones, hoy veremos un poco más el detalle o las tripas de este mecanismo. Así como el visor de la cámara simplemente es mapa de valores RGB que convertimos a una imagen y luego mostramos con un IMAGE de WPF, la información que nos da el sensor de profundidad es una colección de distancias que luego "pintamos” en nuestra aplicación.
El rango de distancias que maneja Kinect va desde los 0,85 metros hasta los 4 metros; y la información que nos provee el sensor de profundidad es en milímetros. Si analizamos el código del ejemplo del post, veremos que durante el procesamiento del evento DepthFrameReady() del sensor, trabajamos con un objeto del tipo PlanarImage (línea 3). En este caso el array de pixels que nos retorna el sensor contiene 2 bytes por cada pixels. Cada uno de estos bytes nos determina la distancia a cada una de las cámaras que utiliza el sensor.
1: void KinectDepthFrameReady(object sender, ImageFrameReadyEventArgs e)
2: {
3: var planarImage = e.ImageFrame.Image;
4: var depthImageHelper = new DepthImageHelper();
5: byte[] convertedDepthBits =
6: depthImageHelper.ConvertDepthFrame(planarImage.Bits, RuntimeOptions);
7: if (this.imageHelper == null)
8: {
9: this.imageHelper = new InteropBitmapHelper(planarImage.Width,
10: planarImage.Height,
11: convertedDepthBits);
12: this.DepthSensorViewer.Source = this.imageHelper.InteropBitmap;
13: }
14: else
15: {
16: this.imageHelper.UpdateBits(convertedDepthBits);
17: }
18: }
Adicionalmente, si inicializamos el sensor con la opción [DepthAndPlayerIndex], el array de información contendrá 3 bytes donde el 3er byte corresponde a un player específico reconocido por el sensor.
Para identificar el valor real de la profundidad de cada elemento del array, tenemos que verificar si el sensor se inicializó con la opción [Depth], o con [DepthAndPlayerIndex]. En el ejemplo del post, lo hacemos a partir de un simple cálculo teniendo en cuenta si trabajamos con 3 o 2 bytes. En este caso depthFrame es un array de bytes que luego convertimos a una imagen utilizando la clase InteropBitmapHelper que vimos en el post anterior.
1: var hasPlayerData = runtimeOptions.HasFlag(RuntimeOptions.UseDepthAndPlayerIndex);
2: for (int i16 = 0, i32 = 0; i16 < depthFrame16.Length && i32 < depthFrame32.Length; i16 += 2, i32 += 4)
3: {
4: var player = hasPlayerData ? depthFrame16[i16] & 0x07 : -1;
5: int realDepth;
6:
7: if (hasPlayerData)
8: {
9: realDepth = (depthFrame16[i16 + 1] << 5) | (depthFrame16[i16] >> 3);
10: }
11: else
12: {
13: realDepth = (depthFrame16[i16 + 1] << 8) | (depthFrame16[i16]);
14: }
15:
16: // transform 13-bit depth information into an 8-bit intensity appropriate
17: // for display (we disregard information in most significant bit)
18: var intensity = (byte)(255 - (255 * realDepth / 0x0fff));
19:
20: depthFrame32[i32 + RedIndex] = 0;
21: depthFrame32[i32 + GreenIndex] = 0;
22: depthFrame32[i32 + BlueIndex] = 0;
La gran carencia en este punto, es poder lograr conocer la profundidad de un Joint o de un elemento del Skeleton para poder tener acceso a gesturas como Push o Pull.
Lamentablemente eso no viene de fábrica en la Beta 2 del SDK de Kinect, pero …. tampoco es tan complicado no?
En el próximo post de Kinect lo solucionamos con 4 líneas de código (eso si el Victor me devuelve el Kinect!!!!)
Saludos @ Home
El Bruno
PD: he terminado de escribir el post, pero veo que en los retos de MSDN lo explican muy pero muy bien !!! http://blogs.msdn.com/b/esmsdn/archive/2011/07/20/reto-kinect-usar-las-c-225-maras-del-sensor.aspx
[# KINECT] HowTo: Display the contents of the depth sensor in our applications
Publicado por elbruno en Code Sample, HowTo, Kinect, Visual Studio 2010 el 17 noviembre, 2011
Hi,
today is a little modify code application that displays the contents of the web cam of Kinect to show in this case, the processed image from the Sensor Kinect Depth in a WPF application. The image that gives us Depth Sensor is the result of the process of information returns the sensor infrared possessing Kinect along with the image of the House of Kinect. With these 2 elements (and a few more things) Kinect manages to assemble a model with some depth which is which gives us Depth Sensor.
The big difference with the previous post is that in this case we will work with the event DepthFrameReady() (line 42) which is that will deliver us the processed image of the DepthSensor. From this moment, we work with an external class DepthImageHelper() to process the image from the sensor in a format compatible with an IMAGE.
1: namespace ElBruno.KinectViewer
2: {
3: using System.Windows;
4: using Microsoft.Research.Kinect.Nui;
5:
6: /// <summary>
7: /// Interaction logic for MainWindow.xaml
8: /// </summary>
9: public partial class MainWindow
10: {
11: private Runtime kinect;
12: private InteropBitmapHelper imageHelper;
13: private RuntimeOptions RuntimeOptions { get; set; }
14:
15: public MainWindow()
16: {
17: InitializeComponent();
18: Loaded += MainWindowLoaded;
19: }
20:
21: void MainWindowLoaded(object sender, RoutedEventArgs e)
22: {
23: InitKinect();
24: }
25:
26: void InitKinect()
27: {
28: if (Runtime.Kinects.Count == 0)
29: return;
30: kinect = Runtime.Kinects[0];
31: RuntimeOptions = RuntimeOptions.UseDepthAndPlayerIndex |
32: RuntimeOptions.UseSkeletalTracking |
33: RuntimeOptions.UseColor;
34: kinect.Initialize(RuntimeOptions);
35: kinect.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240,
36: RuntimeOptions.HasFlag(RuntimeOptions.UseDepthAndPlayerIndex) ||
37: RuntimeOptions.HasFlag(RuntimeOptions.UseSkeletalTracking) ?
38: ImageType.DepthAndPlayerIndex : ImageType.Depth);
39: kinect.DepthFrameReady += this.KinectDepthFrameReady;
40: }
41:
42: void KinectDepthFrameReady(object sender, ImageFrameReadyEventArgs e)
43: {
44: var planarImage = e.ImageFrame.Image;
45: var depthImageHelper = new DepthImageHelper();
46: byte[] convertedDepthBits = depthImageHelper.ConvertDepthFrame(planarImage.Bits, RuntimeOptions);
47:
48: if (this.imageHelper == null)
49: {
50: this.imageHelper = new InteropBitmapHelper(planarImage.Width, planarImage.Height, convertedDepthBits);
51: this.DepthSensorViewer.Source = this.imageHelper.InteropBitmap;
52: }
53: else
54: {
55: this.imageHelper.UpdateBits(convertedDepthBits);
56: }
57: }
58: }
59: }
If we run the application we can see the result of the DepthSensor similar to the following image.
The example code can be downloaded from
Greetings @ Here
The Bruno
[#KINECT] HowTo: Mostrar el contenido del depth sensor en nuestras aplicaciones
Publicado por elbruno en Code Sample, HowTo, Kinect, Visual Studio 2010 el 17 noviembre, 2011
Buenas,
hoy toca modificar un poco el código de la aplicación que muestra el contenido de la cámara web de Kinect para mostrar en este caso, la imagen procesada del Depth Sensor de Kinect en una aplicación WPF. La imagen que nos entrega el Depth Sensor es el resultado del proceso de la información que retorna el sensor infrarojo que posee Kinect junto con la imagen de la cámara de Kinect. Con estos 2 elementos (y un par de cosillas más) Kinect consigue armar un modelo con cierta profundidad que es el que nos entrega el Depth Sensor.
La gran diferencia con el post anterior es que en este caso trabajaremos con el evento DepthFrameReady() (línea 42) que es el que nos entregará la imagen procesada del DepthSensor. A partir de este momento, trabajamos con una clase externa DepthImageHelper() para procesar la imagen del sensor en un formato compatible con un IMAGE.
1: namespace ElBruno.KinectViewer
2: {
3: using System.Windows;
4: using Microsoft.Research.Kinect.Nui;
5:
6: /// <summary>
7: /// Interaction logic for MainWindow.xaml
8: /// </summary>
9: public partial class MainWindow
10: {
11: private Runtime kinect;
12: private InteropBitmapHelper imageHelper;
13: private RuntimeOptions RuntimeOptions { get; set; }
14:
15: public MainWindow()
16: {
17: InitializeComponent();
18: Loaded += MainWindowLoaded;
19: }
20:
21: void MainWindowLoaded(object sender, RoutedEventArgs e)
22: {
23: InitKinect();
24: }
25:
26: void InitKinect()
27: {
28: if (Runtime.Kinects.Count == 0)
29: return;
30: kinect = Runtime.Kinects[0];
31: RuntimeOptions = RuntimeOptions.UseDepthAndPlayerIndex |
32: RuntimeOptions.UseSkeletalTracking |
33: RuntimeOptions.UseColor;
34: kinect.Initialize(RuntimeOptions);
35: kinect.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240,
36: RuntimeOptions.HasFlag(RuntimeOptions.UseDepthAndPlayerIndex) ||
37: RuntimeOptions.HasFlag(RuntimeOptions.UseSkeletalTracking) ?
38: ImageType.DepthAndPlayerIndex : ImageType.Depth);
39: kinect.DepthFrameReady += this.KinectDepthFrameReady;
40: }
41:
42: void KinectDepthFrameReady(object sender, ImageFrameReadyEventArgs e)
43: {
44: var planarImage = e.ImageFrame.Image;
45: var depthImageHelper = new DepthImageHelper();
46: byte[] convertedDepthBits = depthImageHelper.ConvertDepthFrame(planarImage.Bits, RuntimeOptions);
47:
48: if (this.imageHelper == null)
49: {
50: this.imageHelper = new InteropBitmapHelper(planarImage.Width, planarImage.Height, convertedDepthBits);
51: this.DepthSensorViewer.Source = this.imageHelper.InteropBitmap;
52: }
53: else
54: {
55: this.imageHelper.UpdateBits(convertedDepthBits);
56: }
57: }
58: }
59: }
Si ejecutamos la aplicación podremos ver el resultado del DepthSensor similar a la siguiente imagen.
El código del ejemplo lo pueden descargar desde
Saludos @ Here
El Bruno
[#KINECT] HowTo: Change the camera angle
Publicado por elbruno en Code Sample, HowTo, Kinect, Tutorial, Visual Studio 2010 el 14 noviembre, 2011
Hi,
in today’s post we will move the angle of the sensor up or down using the SDK APIs.
It is initially possible to move the camera up or down a twenty-seventh, and to try them we will from the example of yesterday.
1 We modify our application to allow us to define the angle of inclination of the Kinect using a text box and a button.
2. The Xaml is as the following example
1: <Window x:Class="ElBruno.KinectViewer.MainWindow"
2: xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3: xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4: Title="El Bruno - Kinect Viewer" Height="480" Width="740">
5: <Grid>
6: <Grid.RowDefinitions>
7: <RowDefinition Height="40"></RowDefinition>
8: <RowDefinition Height="*"></RowDefinition>
9: <RowDefinition Height="40"></RowDefinition>
10: </Grid.RowDefinitions>
11: <TextBlock Text="Camera Viewer" FontSize="20" HorizontalAlignment="Center"
12: Foreground="Black" Grid.Row="0" />
13: <Image x:Name="CameraViewer" Margin="10,10,10,10"
14: Stretch="Fill" Grid.Row="1" />
15: <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Grid.Row="2" >
16: <TextBox x:Name="txtAngle" Text="0" FontSize="20" HorizontalAlignment="Center" Foreground="Black" />
17: <Button x:Name="SetCameraAngle" Click="SetCameraAngle_Click" Content="Set Camera Angle" />
18: </StackPanel>
19: </Grid>
20: </Window>
3. Then the implementation of the event click of the button is rather simple
1: private void SetCameraAngleClick(object sender, RoutedEventArgs e)
2: {
3: _kinect.NuiCamera.ElevationAngle = Convert.ToInt32(txtAngle.Text);
4: }
Today I will not put the example to download because it is quite simple to modify. And tomorrow some Audio and Speech if the bird allow me.
Greetings @ Here
The Bruno







SocialVibe