EDN Admin
Well-known member
This video covers the basics of using depth data from Kinect. You may find it easier to follow along by downloading the http://files.ch9.ms/coding4fun/KinectForWindowsSDKQuickstarts.zip Kinect for Windows SDK Quickstarts samples and slides . [ http://channel9.msdn.com/Series/KinectSDKQuickstarts/Working-with-Depth-Data#time=0m43s 00:43 ] Depth data overview [ http://channel9.msdn.com/Series/KinectSDKQuickstarts/Working-with-Depth-Data#time=4m56s 04:56 ] Initializing the Kinect Runtime [ http://channel9.msdn.com/Series/KinectSDKQuickstarts/Working-with-Depth-Data#time=5m46s 05:46 ] Using the depth data to create an image [ http://channel9.msdn.com/Series/KinectSDKQuickstarts/Working-with-Depth-Data#time=12m13s 12:13 ] Using the PlayerIndex <h3>Setup</h3> The steps below assume you have setup your development environment as explained in the " http://channel9.msdn.com/Series/KinectSDKQuickstarts/Getting-Started Setting Up Your Development Environment " video. <h1>Task Setup the Depth Camera event</h1><h3>Designing the UI</h3> Add an image with Width=320 and Height=240 as shown below: XAML
<pre class="brush: xml <Image Height="240" HorizontalAlignment="Left" Margin="62,41,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="320" />[/code] http://files.channel9.msdn.com/thumbnail/2ef23a05-59df-4ddf-9558-2bb3c0328751.PNG" rel="lightbox <img src="http://files.channel9.msdn.com/thumbnail/2ef23a05-59df-4ddf-9558-2bb3c0328751.PNG" alt=" <h3>Setup the Depth Camera Event</h3> Create an instance of the Kinect Runtime outside of the Window_Loaded event. Then, initialize the Runtime to use DepthAndPlayerIndex and UseSkeletalTracking . Finally register for DepthFrameReady event and open the Depth stream as shown below. C#
<pre class="brush: csharp //Kinect Runtime
Runtime nui = new Runtime();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//UseDepthAndPlayerIndex and UseSkeletalTracking
nui.Initialize(RuntimeOptions.UseDepthAndPlayerIndex | RuntimeOptions.UseSkeletalTracking);
//register for event
nui.DepthFrameReady += new EventHandler<ImageFrameReadyEventArgs>(nui_DepthFrameReady);
//DepthAndPlayerIndex ImageType
nui.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240,
ImageType.DepthAndPlayerIndex);
}
void nui_DepthFrameReady(object sender, ImageFrameReadyEventArgs e)
{}[/code] Visual Basic
<pre class="brush: vb
Private nui As New Runtime
Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
UseDepthAndPlayerIndex and UseSkeletalTracking
nui.Initialize(RuntimeOptions.UseDepthAndPlayerIndex Or RuntimeOptions.UseSkeletalTracking)
register for event
AddHandler nui.DepthFrameReady, AddressOf nui_DepthFrameReady
DepthAndPlayerIndex ImageType
nui.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240, ImageType.DepthAndPlayerIndex)
End Sub
Private Sub nui_DepthFrameReady(ByVal sender As Object, ByVal e As ImageFrameReadyEventArgs)
End Sub[/code] <h3>Understanding the PlanarImage byte[] Array</h3> The DepthFrameReady event returns an ImageFrame class that contains a PlanarImage. That PlanarImage contains a byte[] array which contains the distance of each pixel. The array: Starts at top left of image Moves left to right, then top to bottom Represents distance for pixel <h3>Calculating Distance</h3> Because there are 2 bytes per pixel (16 bits) representing the distance, you will need to use bitshift operators to get the distance for a particular pixel. The exact bitshifting depends on the ImageType you use Depth Image Type
Bitshift second byte left by 8
Distance (0,0) = (int)(Bits[0] | Bits[1] << 8 ); DepthAndPlayerIndex Image Type
Bitshift first byte right by 3 (to remove player index), and second byte left by 5
Distance (0,0) =(int)(Bits[0] >> 3 | Bits[1] << 5); The method below shows returning the distance in millimeters using the 2 bytes for a particular pixel. C#
<pre class="brush: csharp private int GetDistanceWithPlayerIndex(byte firstFrame, byte secondFrame)
{
//offset by 3 in first byte to get value after player index
int distance = (int)(firstFrame >> 3 | secondFrame << 5);
return distance;
}[/code] Visual Basic
<pre class="brush: vb Private Function GetDistanceWithPlayerIndex(ByVal firstFrame As Byte, ByVal secondFrame As Byte) As Integer
offset by 3 in first byte to get value after player index
Dim distance As Integer = (CInt(firstFrame) >> 3 Or CInt(secondFrame) << 5)
Return distance
End Function[/code] The DepthAndPlayerIndex image type is offset by 3 since the first three bits represent the Player Index. The Player Index has the possible three values 0 – No player 1 – Skeleton 0 2 – Skeleton 1 To get a player index, well use the following formula. Since the player index is only in the first byte, we do not need the pixels second byte. C#
<pre class="brush: csharp private static int GetPlayerIndex(byte firstFrame)
{
//returns 0 = no player, 1 = 1st player, 2 = 2nd player...
return (int)firstFrame & 7;
}[/code] Visual Basic
<pre class="brush: vb Private Shared Function GetPlayerIndex(ByVal firstFrame As Byte) As Integer
returns 0 = no player, 1 = 1st player, 2 = 2nd player...
bitwise & on firstFrame
Return CInt(firstFrame) And 7
End Function[/code] <h3>Using distance to color values</h3> Now that we know the distance for a particular pixel using the formula above, we can loop through all of the bytes in the byte[] array and dynamically assign colors to pixels based on their distance. To begin with, well build a colorFrame byte[] array using the Bgr (Blue, Green, Red) pixel format. What this means is that each pixel (ex: the pixel at 0,0) is represented by four bytes, one each for Blue, Green, Red, and an empty one (or transparency byte if you choose the Bgra format). For example, the snippet below would color the pixel blue if the current distance for that pixel was < 900 millimeters from the Kinect. To set the color to blue, we set the first byte (BlueIndex) to the maximum value, 255. C#
<pre class="brush: csharp if (distance <= 900)
{
//we are very close
colorFrame[index + BlueIndex] = 255;
colorFrame[index + GreenIndex] = 0;
colorFrame[index + RedIndex] = 0;
}[/code] Visual Basic
<pre class="brush: vb If distance <= 900 Then
we are very close
colorFrame(index + BlueIndex) = 255
colorFrame(index + GreenIndex) = 0
colorFrame(index + RedIndex) = 0
End If[/code] Similarly, we can use the code snippet below to check if the current pixel represents a Player Index. If it does, well set the maximum value for both green and red which produces a yellow/gold-like color. C#
<pre class="brush: csharp if (GetPlayerIndex(depthData[depthIndex]) > 0)
{
//we are the farthest
colorFrame[index + BlueIndex] = 0;
colorFrame[index + GreenIndex] = 255;
colorFrame[index + RedIndex] = 255;
}[/code] Visual Basic
<pre class="brush: vb If GetPlayerIndex(depthData(depthIndex)) > 0 Then
we are the farthest
colorFrame(index + BlueIndex) = 0
colorFrame(index + GreenIndex) = 255
colorFrame(index + RedIndex) = 255
End If[/code] <h3>Setting a monochrome intensity</h3> While the previous examples we hard-coded colors, you can also build a monochrome histogram that scales the color range (0-255) proportionally based on the distance range (850-4000). To get a monochrome appearance, the intensity is applied equally to all three colors (blue, green, red). C#
<pre class="brush: csharp //equal coloring for monochromatic histogram
var intensity = CalculateIntensityFromDepth(distance);
colorFrame[index + BlueIndex] = intensity;
colorFrame[index + GreenIndex] = intensity;
colorFrame[index + RedIndex] = intensity;
const float MaxDepthDistance = 4000; // max value returned
const float MinDepthDistance = 850; // min value returned
const float MaxDepthDistanceOffset = MaxDepthDistance - MinDepthDistance;
public static byte CalculateIntensityFromDepth(int distance)
{
//formula for calculating monochrome intensity for histogram
return (byte)(255 - (255 * Math.Max(distance - MinDepthDistance, 0) / (MaxDepthDistanceOffset)));
}[/code] Visual Basic
<pre class="brush: vb equal coloring for monochromatic histogram
Dim intensity = CalculateIntensityFromDepth(distance)
colorFrame(index + BlueIndex) = intensity
colorFrame(index + GreenIndex) = intensity
colorFrame(index + RedIndex) = intensity
Private Const MaxDepthDistance As Single = 4000 max value returned
Private Const MinDepthDistance As Single = 850 min value returned
Private Const MaxDepthDistanceOffset As Single = MaxDepthDistance - MinDepthDistance
Public Shared Function CalculateIntensityFromDepth(ByVal distance As Integer) As Byte
formula for calculating monochrome intensity for histogram
Return CByte(255 - (255 * Math.Max(distance - MinDepthDistance, 0) / (MaxDepthDistanceOffset)))
End Function[/code] <h3>Putting it all together</h3> Using the formulas above, well now return a byte[] array that has a color value for each pixel based on if the distance for that pixel: > 900 = Blue > 900 && < 2000 = Green > 2000 = Red If the pixel represents a player, the color will be yellow/gold. C#
<pre class="brush: csharp private byte[] GenerateColoredBytes(ImageFrame imageFrame)
{
int height = imageFrame.Image.Height;
int width = imageFrame.Image.Width;
//Depth data for each pixel
Byte[] depthData = imageFrame.Image.Bits;
//colorFrame contains color information for all pixels in image
//Height x Width x 4 (Red, Green, Blue, empty byte)
Byte[] colorFrame = new byte[imageFrame.Image.Height * imageFrame.Image.Width * 4];
//Bgr32 - Blue, Green, Red, empty byte
//Bgra32 - Blue, Green, Red, transparency
//You must set transparency for Bgra as .NET defaults a byte to 0 = fully transparent
//hardcoded locations to Blue, Green, Red (BGR) index positions
const int BlueIndex = 0;
const int GreenIndex = 1;
const int RedIndex = 2;
var depthIndex = 0;
for (var y = 0; y < height; y++)
{
var heightOffset = y * width;
for (var x = 0; x < width; x++)
{
var index = ((width - x - 1) + heightOffset) * 4;
//var distance = GetDistance(depthData[depthIndex], depthData[depthIndex + 1]);
var distance = GetDistanceWithPlayerIndex(depthData[depthIndex], depthData[depthIndex + 1]);
if (distance <= 900)
{
//we are very close
colorFrame[index + BlueIndex] = 255;
colorFrame[index + GreenIndex] = 0;
colorFrame[index + RedIndex] = 0;
}
else if (distance > 900 && distance < 2000)
{
//we are a bit further away
colorFrame[index + BlueIndex] = 0;
colorFrame[index + GreenIndex] = 255;
colorFrame[index + RedIndex] = 0;
}
else if (distance > 2000)
{
//we are the farthest
colorFrame[index + BlueIndex] = 0;
colorFrame[index + GreenIndex] = 0;
colorFrame[index + RedIndex] = 255;
}
//Color a player
if (GetPlayerIndex(depthData[depthIndex]) > 0)
{
//we are the farthest
colorFrame[index + BlueIndex] = 0;
colorFrame[index + GreenIndex] = 255;
colorFrame[index + RedIndex] = 255;
}
//jump two bytes at a time
depthIndex += 2;
}
}
return colorFrame;
}[/code] Visual Basic
<pre class="brush: vb Private Function GenerateColoredBytes(ByVal imageFrame As ImageFrame) As Byte()
Dim height As Integer = imageFrame.Image.Height
Dim width As Integer = imageFrame.Image.Width
Depth data for each pixel
Dim depthData() As Byte = imageFrame.Image.Bits
colorFrame contains color information for all pixels in image
Height x Width x 4 (Red, Green, Blue, empty byte)
Dim colorFrame(imageFrame.Image.Height * imageFrame.Image.Width * 4 - 1) As Byte
Bgr32 - Blue, Green, Red, empty byte
Bgra32 - Blue, Green, Red, transparency
You must set transparency for Bgra as .NET defaults a byte to 0 = fully transparent
hardcoded locations to Blue, Green, Red (BGR) index positions
Const BlueIndex As Integer = 0
Const GreenIndex As Integer = 1
Const RedIndex As Integer = 2
Dim depthIndex = 0
For y = 0 To height - 1
Dim heightOffset = y * width
For x = 0 To width - 1
Dim index = ((width - x - 1) + heightOffset) * 4
Dim distance = GetDistanceWithPlayerIndex(depthData(depthIndex), depthData(depthIndex + 1))
If distance <= 900 Then
we are very close
colorFrame(index + BlueIndex) = 255
colorFrame(index + GreenIndex) = 0
colorFrame(index + RedIndex) = 0
ElseIf distance > 900 AndAlso distance < 2000 Then
we are a bit further away
colorFrame(index + BlueIndex) = 0
colorFrame(index + GreenIndex) = 255
colorFrame(index + RedIndex) = 0
ElseIf distance > 2000 Then
we are the farthest
colorFrame(index + BlueIndex) = 0
colorFrame(index + GreenIndex) = 0
colorFrame(index + RedIndex) = 255
End If
//Color a player
If GetPlayerIndex(depthData(depthIndex)) > 0 Then
we are the farthest
colorFrame(index + BlueIndex) = 0
colorFrame(index + GreenIndex) = 255
colorFrame(index + RedIndex) = 255
End If
jump two bytes at a time
depthIndex += 2
Next x
Next y
Return colorFrame
End Function[/code] <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Feeds/RSS&WT.dl=0&WT.entryid=Entry:RSSView:6e71e1a9a94844b0908f9efd005862a9
View the full article
<pre class="brush: xml <Image Height="240" HorizontalAlignment="Left" Margin="62,41,0,0" Name="image1" Stretch="Fill" VerticalAlignment="Top" Width="320" />[/code] http://files.channel9.msdn.com/thumbnail/2ef23a05-59df-4ddf-9558-2bb3c0328751.PNG" rel="lightbox <img src="http://files.channel9.msdn.com/thumbnail/2ef23a05-59df-4ddf-9558-2bb3c0328751.PNG" alt=" <h3>Setup the Depth Camera Event</h3> Create an instance of the Kinect Runtime outside of the Window_Loaded event. Then, initialize the Runtime to use DepthAndPlayerIndex and UseSkeletalTracking . Finally register for DepthFrameReady event and open the Depth stream as shown below. C#
<pre class="brush: csharp //Kinect Runtime
Runtime nui = new Runtime();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//UseDepthAndPlayerIndex and UseSkeletalTracking
nui.Initialize(RuntimeOptions.UseDepthAndPlayerIndex | RuntimeOptions.UseSkeletalTracking);
//register for event
nui.DepthFrameReady += new EventHandler<ImageFrameReadyEventArgs>(nui_DepthFrameReady);
//DepthAndPlayerIndex ImageType
nui.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240,
ImageType.DepthAndPlayerIndex);
}
void nui_DepthFrameReady(object sender, ImageFrameReadyEventArgs e)
{}[/code] Visual Basic
<pre class="brush: vb
Private nui As New Runtime
Private Sub Window_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
UseDepthAndPlayerIndex and UseSkeletalTracking
nui.Initialize(RuntimeOptions.UseDepthAndPlayerIndex Or RuntimeOptions.UseSkeletalTracking)
register for event
AddHandler nui.DepthFrameReady, AddressOf nui_DepthFrameReady
DepthAndPlayerIndex ImageType
nui.DepthStream.Open(ImageStreamType.Depth, 2, ImageResolution.Resolution320x240, ImageType.DepthAndPlayerIndex)
End Sub
Private Sub nui_DepthFrameReady(ByVal sender As Object, ByVal e As ImageFrameReadyEventArgs)
End Sub[/code] <h3>Understanding the PlanarImage byte[] Array</h3> The DepthFrameReady event returns an ImageFrame class that contains a PlanarImage. That PlanarImage contains a byte[] array which contains the distance of each pixel. The array: Starts at top left of image Moves left to right, then top to bottom Represents distance for pixel <h3>Calculating Distance</h3> Because there are 2 bytes per pixel (16 bits) representing the distance, you will need to use bitshift operators to get the distance for a particular pixel. The exact bitshifting depends on the ImageType you use Depth Image Type
Bitshift second byte left by 8
Distance (0,0) = (int)(Bits[0] | Bits[1] << 8 ); DepthAndPlayerIndex Image Type
Bitshift first byte right by 3 (to remove player index), and second byte left by 5
Distance (0,0) =(int)(Bits[0] >> 3 | Bits[1] << 5); The method below shows returning the distance in millimeters using the 2 bytes for a particular pixel. C#
<pre class="brush: csharp private int GetDistanceWithPlayerIndex(byte firstFrame, byte secondFrame)
{
//offset by 3 in first byte to get value after player index
int distance = (int)(firstFrame >> 3 | secondFrame << 5);
return distance;
}[/code] Visual Basic
<pre class="brush: vb Private Function GetDistanceWithPlayerIndex(ByVal firstFrame As Byte, ByVal secondFrame As Byte) As Integer
offset by 3 in first byte to get value after player index
Dim distance As Integer = (CInt(firstFrame) >> 3 Or CInt(secondFrame) << 5)
Return distance
End Function[/code] The DepthAndPlayerIndex image type is offset by 3 since the first three bits represent the Player Index. The Player Index has the possible three values 0 – No player 1 – Skeleton 0 2 – Skeleton 1 To get a player index, well use the following formula. Since the player index is only in the first byte, we do not need the pixels second byte. C#
<pre class="brush: csharp private static int GetPlayerIndex(byte firstFrame)
{
//returns 0 = no player, 1 = 1st player, 2 = 2nd player...
return (int)firstFrame & 7;
}[/code] Visual Basic
<pre class="brush: vb Private Shared Function GetPlayerIndex(ByVal firstFrame As Byte) As Integer
returns 0 = no player, 1 = 1st player, 2 = 2nd player...
bitwise & on firstFrame
Return CInt(firstFrame) And 7
End Function[/code] <h3>Using distance to color values</h3> Now that we know the distance for a particular pixel using the formula above, we can loop through all of the bytes in the byte[] array and dynamically assign colors to pixels based on their distance. To begin with, well build a colorFrame byte[] array using the Bgr (Blue, Green, Red) pixel format. What this means is that each pixel (ex: the pixel at 0,0) is represented by four bytes, one each for Blue, Green, Red, and an empty one (or transparency byte if you choose the Bgra format). For example, the snippet below would color the pixel blue if the current distance for that pixel was < 900 millimeters from the Kinect. To set the color to blue, we set the first byte (BlueIndex) to the maximum value, 255. C#
<pre class="brush: csharp if (distance <= 900)
{
//we are very close
colorFrame[index + BlueIndex] = 255;
colorFrame[index + GreenIndex] = 0;
colorFrame[index + RedIndex] = 0;
}[/code] Visual Basic
<pre class="brush: vb If distance <= 900 Then
we are very close
colorFrame(index + BlueIndex) = 255
colorFrame(index + GreenIndex) = 0
colorFrame(index + RedIndex) = 0
End If[/code] Similarly, we can use the code snippet below to check if the current pixel represents a Player Index. If it does, well set the maximum value for both green and red which produces a yellow/gold-like color. C#
<pre class="brush: csharp if (GetPlayerIndex(depthData[depthIndex]) > 0)
{
//we are the farthest
colorFrame[index + BlueIndex] = 0;
colorFrame[index + GreenIndex] = 255;
colorFrame[index + RedIndex] = 255;
}[/code] Visual Basic
<pre class="brush: vb If GetPlayerIndex(depthData(depthIndex)) > 0 Then
we are the farthest
colorFrame(index + BlueIndex) = 0
colorFrame(index + GreenIndex) = 255
colorFrame(index + RedIndex) = 255
End If[/code] <h3>Setting a monochrome intensity</h3> While the previous examples we hard-coded colors, you can also build a monochrome histogram that scales the color range (0-255) proportionally based on the distance range (850-4000). To get a monochrome appearance, the intensity is applied equally to all three colors (blue, green, red). C#
<pre class="brush: csharp //equal coloring for monochromatic histogram
var intensity = CalculateIntensityFromDepth(distance);
colorFrame[index + BlueIndex] = intensity;
colorFrame[index + GreenIndex] = intensity;
colorFrame[index + RedIndex] = intensity;
const float MaxDepthDistance = 4000; // max value returned
const float MinDepthDistance = 850; // min value returned
const float MaxDepthDistanceOffset = MaxDepthDistance - MinDepthDistance;
public static byte CalculateIntensityFromDepth(int distance)
{
//formula for calculating monochrome intensity for histogram
return (byte)(255 - (255 * Math.Max(distance - MinDepthDistance, 0) / (MaxDepthDistanceOffset)));
}[/code] Visual Basic
<pre class="brush: vb equal coloring for monochromatic histogram
Dim intensity = CalculateIntensityFromDepth(distance)
colorFrame(index + BlueIndex) = intensity
colorFrame(index + GreenIndex) = intensity
colorFrame(index + RedIndex) = intensity
Private Const MaxDepthDistance As Single = 4000 max value returned
Private Const MinDepthDistance As Single = 850 min value returned
Private Const MaxDepthDistanceOffset As Single = MaxDepthDistance - MinDepthDistance
Public Shared Function CalculateIntensityFromDepth(ByVal distance As Integer) As Byte
formula for calculating monochrome intensity for histogram
Return CByte(255 - (255 * Math.Max(distance - MinDepthDistance, 0) / (MaxDepthDistanceOffset)))
End Function[/code] <h3>Putting it all together</h3> Using the formulas above, well now return a byte[] array that has a color value for each pixel based on if the distance for that pixel: > 900 = Blue > 900 && < 2000 = Green > 2000 = Red If the pixel represents a player, the color will be yellow/gold. C#
<pre class="brush: csharp private byte[] GenerateColoredBytes(ImageFrame imageFrame)
{
int height = imageFrame.Image.Height;
int width = imageFrame.Image.Width;
//Depth data for each pixel
Byte[] depthData = imageFrame.Image.Bits;
//colorFrame contains color information for all pixels in image
//Height x Width x 4 (Red, Green, Blue, empty byte)
Byte[] colorFrame = new byte[imageFrame.Image.Height * imageFrame.Image.Width * 4];
//Bgr32 - Blue, Green, Red, empty byte
//Bgra32 - Blue, Green, Red, transparency
//You must set transparency for Bgra as .NET defaults a byte to 0 = fully transparent
//hardcoded locations to Blue, Green, Red (BGR) index positions
const int BlueIndex = 0;
const int GreenIndex = 1;
const int RedIndex = 2;
var depthIndex = 0;
for (var y = 0; y < height; y++)
{
var heightOffset = y * width;
for (var x = 0; x < width; x++)
{
var index = ((width - x - 1) + heightOffset) * 4;
//var distance = GetDistance(depthData[depthIndex], depthData[depthIndex + 1]);
var distance = GetDistanceWithPlayerIndex(depthData[depthIndex], depthData[depthIndex + 1]);
if (distance <= 900)
{
//we are very close
colorFrame[index + BlueIndex] = 255;
colorFrame[index + GreenIndex] = 0;
colorFrame[index + RedIndex] = 0;
}
else if (distance > 900 && distance < 2000)
{
//we are a bit further away
colorFrame[index + BlueIndex] = 0;
colorFrame[index + GreenIndex] = 255;
colorFrame[index + RedIndex] = 0;
}
else if (distance > 2000)
{
//we are the farthest
colorFrame[index + BlueIndex] = 0;
colorFrame[index + GreenIndex] = 0;
colorFrame[index + RedIndex] = 255;
}
//Color a player
if (GetPlayerIndex(depthData[depthIndex]) > 0)
{
//we are the farthest
colorFrame[index + BlueIndex] = 0;
colorFrame[index + GreenIndex] = 255;
colorFrame[index + RedIndex] = 255;
}
//jump two bytes at a time
depthIndex += 2;
}
}
return colorFrame;
}[/code] Visual Basic
<pre class="brush: vb Private Function GenerateColoredBytes(ByVal imageFrame As ImageFrame) As Byte()
Dim height As Integer = imageFrame.Image.Height
Dim width As Integer = imageFrame.Image.Width
Depth data for each pixel
Dim depthData() As Byte = imageFrame.Image.Bits
colorFrame contains color information for all pixels in image
Height x Width x 4 (Red, Green, Blue, empty byte)
Dim colorFrame(imageFrame.Image.Height * imageFrame.Image.Width * 4 - 1) As Byte
Bgr32 - Blue, Green, Red, empty byte
Bgra32 - Blue, Green, Red, transparency
You must set transparency for Bgra as .NET defaults a byte to 0 = fully transparent
hardcoded locations to Blue, Green, Red (BGR) index positions
Const BlueIndex As Integer = 0
Const GreenIndex As Integer = 1
Const RedIndex As Integer = 2
Dim depthIndex = 0
For y = 0 To height - 1
Dim heightOffset = y * width
For x = 0 To width - 1
Dim index = ((width - x - 1) + heightOffset) * 4
Dim distance = GetDistanceWithPlayerIndex(depthData(depthIndex), depthData(depthIndex + 1))
If distance <= 900 Then
we are very close
colorFrame(index + BlueIndex) = 255
colorFrame(index + GreenIndex) = 0
colorFrame(index + RedIndex) = 0
ElseIf distance > 900 AndAlso distance < 2000 Then
we are a bit further away
colorFrame(index + BlueIndex) = 0
colorFrame(index + GreenIndex) = 255
colorFrame(index + RedIndex) = 0
ElseIf distance > 2000 Then
we are the farthest
colorFrame(index + BlueIndex) = 0
colorFrame(index + GreenIndex) = 0
colorFrame(index + RedIndex) = 255
End If
//Color a player
If GetPlayerIndex(depthData(depthIndex)) > 0 Then
we are the farthest
colorFrame(index + BlueIndex) = 0
colorFrame(index + GreenIndex) = 255
colorFrame(index + RedIndex) = 255
End If
jump two bytes at a time
depthIndex += 2
Next x
Next y
Return colorFrame
End Function[/code] <img src="http://m.webtrends.com/dcs1wotjh10000w0irc493s0e_6x1g/njs.gif?dcssip=channel9.msdn.com&dcsuri=http://channel9.msdn.com/Feeds/RSS&WT.dl=0&WT.entryid=Entry:RSSView:6e71e1a9a94844b0908f9efd005862a9
View the full article