Skip to content

Commit

Permalink
lab05
Browse files Browse the repository at this point in the history
  • Loading branch information
jesse-nsquared committed Mar 16, 2015
1 parent c3532b1 commit 7aca8b3
Show file tree
Hide file tree
Showing 3 changed files with 163 additions and 8 deletions.
2 changes: 2 additions & 0 deletions Kinect2Sample/Kinect2Sample.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
<UseVSHostingProcess>false</UseVSHostingProcess>
<ErrorReport>prompt</ErrorReport>
<Prefer32Bit>true</Prefer32Bit>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x64'">
<OutputPath>bin\x64\Release\</OutputPath>
Expand Down
6 changes: 5 additions & 1 deletion Kinect2Sample/MainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<Setter Property="FontSize" Value="20"/>
</Style>
</Page.Resources>

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<Grid Margin="30">
<Grid.RowDefinitions>
Expand Down Expand Up @@ -54,6 +54,10 @@
Click="ColorButton_Click"/>
<Button Content="Depth" Style="{StaticResource FrameSelectorButtonStyle}"
Click="DepthButton_Click"/>
<Button Style="{StaticResource FrameSelectorButtonStyle}"
Click="BodyMaskButton_Click">
<TextBlock Text="Body Mask" TextWrapping="Wrap"/>
</Button>
</StackPanel>
</ScrollViewer>
</Grid>
Expand Down
163 changes: 156 additions & 7 deletions Kinect2Sample/MainPage.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,18 @@
using Windows.UI.Xaml.Navigation;
using WindowsPreview.Kinect;
using System.ComponentModel;
using Windows.Storage.Streams;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace Kinect2Sample
{
public enum DisplayFrameType
{
Infrared,
Color,
Depth
Depth,
BodyMask
}

public sealed partial class MainPage : Page, INotifyPropertyChanged
Expand Down Expand Up @@ -76,6 +80,7 @@ public sealed partial class MainPage : Page, INotifyPropertyChanged
private FrameDescription currentFrameDescription;
private DisplayFrameType currentDisplayFrameType;
private MultiSourceFrameReader multiSourceFrameReader = null;
private CoordinateMapper coordinateMapper = null;

//Infrared Frame
private ushort[] infraredFrameData = null;
Expand All @@ -85,6 +90,9 @@ public sealed partial class MainPage : Page, INotifyPropertyChanged
private ushort[] depthFrameData = null;
private byte[] depthPixels = null;

//BodyMask Frames
private DepthSpacePoint[] colorMappedToDepthPoints = null;

public event PropertyChangedEventHandler PropertyChanged;
public string StatusText
{
Expand Down Expand Up @@ -125,7 +133,9 @@ public MainPage()

SetupCurrentDisplay(DEFAULT_DISPLAYFRAMETYPE);

this.multiSourceFrameReader = this.kinectSensor.OpenMultiSourceFrameReader(FrameSourceTypes.Infrared | FrameSourceTypes.Color | FrameSourceTypes.Depth);
this.coordinateMapper = this.kinectSensor.CoordinateMapper;

this.multiSourceFrameReader = this.kinectSensor.OpenMultiSourceFrameReader(FrameSourceTypes.Infrared | FrameSourceTypes.Color | FrameSourceTypes.Depth | FrameSourceTypes.BodyIndex);

this.multiSourceFrameReader.MultiSourceFrameArrived += this.Reader_MultiSourceFrameArrived;

Expand All @@ -144,6 +154,8 @@ public MainPage()
private void SetupCurrentDisplay(DisplayFrameType newDisplayFrameType)
{
currentDisplayFrameType = newDisplayFrameType;
// Frames used by more than one type are declared outside the switch
FrameDescription colorFrameDescription = null;
switch (currentDisplayFrameType)
{
case DisplayFrameType.Infrared:
Expand All @@ -156,7 +168,7 @@ private void SetupCurrentDisplay(DisplayFrameType newDisplayFrameType)
break;

case DisplayFrameType.Color:
FrameDescription colorFrameDescription = this.kinectSensor.ColorFrameSource.FrameDescription;
colorFrameDescription = this.kinectSensor.ColorFrameSource.FrameDescription;
this.CurrentFrameDescription = colorFrameDescription;
// create the bitmap to display
this.bitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height);
Expand All @@ -171,6 +183,13 @@ private void SetupCurrentDisplay(DisplayFrameType newDisplayFrameType)
this.bitmap = new WriteableBitmap(depthFrameDescription.Width, depthFrameDescription.Height);
break;

case DisplayFrameType.BodyMask:
colorFrameDescription = this.kinectSensor.ColorFrameSource.FrameDescription;
this.CurrentFrameDescription = colorFrameDescription;
// allocate space to put the pixels being received and converted
this.colorMappedToDepthPoints = new DepthSpacePoint[colorFrameDescription.Width * colorFrameDescription.Height];
this.bitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height);
break;
default:
break;
}
Expand All @@ -183,40 +202,158 @@ private void Sensor_IsAvailableChanged(KinectSensor sender, IsAvailableChangedEv

private void Reader_MultiSourceFrameArrived(MultiSourceFrameReader sender, MultiSourceFrameArrivedEventArgs e)
{

MultiSourceFrame multiSourceFrame = e.FrameReference.AcquireFrame();

// If the Frame has expired by the time we process this event, return.
if (multiSourceFrame == null)
{
return;
}
DepthFrame depthFrame = null;
ColorFrame colorFrame = null;
InfraredFrame infraredFrame = null;
BodyIndexFrame bodyIndexFrame = null;
//windows.storage.streams
IBuffer depthFrameData = null;
IBuffer bodyIndexFrameData = null;
// Com interface for unsafe byte manipulation
IBufferByteAccess bodyIndexByteAccess = null;

switch (currentDisplayFrameType)
{
case DisplayFrameType.Infrared:
using (InfraredFrame infraredFrame = multiSourceFrame.InfraredFrameReference.AcquireFrame())
using (infraredFrame = multiSourceFrame.InfraredFrameReference.AcquireFrame())
{
ShowInfraredFrame(infraredFrame);
}
break;
case DisplayFrameType.Color:
using (ColorFrame colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame())
using (colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame())
{
ShowColorFrame(colorFrame);
}
break;
case DisplayFrameType.Depth:
using (DepthFrame depthFrame =
multiSourceFrame.DepthFrameReference.AcquireFrame())
using (depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame())
{
ShowDepthFrame(depthFrame);
}
break;
case DisplayFrameType.BodyMask:
// Put in a try catch to utilise finally() and clean up frames
try
{
depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame();
bodyIndexFrame = multiSourceFrame.BodyIndexFrameReference.AcquireFrame();
colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame();
if ((depthFrame == null) || (colorFrame == null) || (bodyIndexFrame == null))
{
return;
}

// Access the depth frame data directly via LockImageBuffer to avoid making a copy
depthFrameData = depthFrame.LockImageBuffer();
this.coordinateMapper.MapColorFrameToDepthSpaceUsingIBuffer(depthFrameData, this.colorMappedToDepthPoints);
// Process Color
colorFrame.CopyConvertedFrameDataToBuffer(this.bitmap.PixelBuffer, ColorImageFormat.Bgra);
// Access the body index frame data directly via LockImageBuffer to avoid making a copy
bodyIndexFrameData = bodyIndexFrame.LockImageBuffer();
ShowMappedBodyFrame(depthFrame.FrameDescription.Width, depthFrame.FrameDescription.Height, bodyIndexFrameData, bodyIndexByteAccess);

}
finally
{
// ... disposing of depth, color and bodyIndex frames
if (depthFrame != null)
{
depthFrame.Dispose();
}
if (colorFrame != null)
{
colorFrame.Dispose();
}
if (bodyIndexFrame != null)
{
bodyIndexFrame.Dispose();
}

if (depthFrameData != null)
{
// We must force a release of the IBuffer in order to ensure that we have dropped all references to it.
System.Runtime.InteropServices.Marshal.ReleaseComObject(depthFrameData);
}
if (bodyIndexFrameData != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(bodyIndexFrameData);
}
if (bodyIndexByteAccess != null)
{
System.Runtime.InteropServices.Marshal.ReleaseComObject(bodyIndexByteAccess);
}

}
break;

default:
break;
}
}

unsafe private void ShowMappedBodyFrame(int depthWidth, int depthHeight, IBuffer bodyIndexFrameData, IBufferByteAccess bodyIndexByteAccess)
{
bodyIndexByteAccess = (IBufferByteAccess)bodyIndexFrameData;
byte* bodyIndexBytes = null;
bodyIndexByteAccess.Buffer(out bodyIndexBytes);

fixed (DepthSpacePoint* colorMappedToDepthPointsPointer = this.colorMappedToDepthPoints)
{
IBufferByteAccess bitmapBackBufferByteAccess = (IBufferByteAccess)this.bitmap.PixelBuffer;

byte* bitmapBackBufferBytes = null;
bitmapBackBufferByteAccess.Buffer(out bitmapBackBufferBytes);

// Treat the color data as 4-byte pixels
uint* bitmapPixelsPointer = (uint*)bitmapBackBufferBytes;

// Loop over each row and column of the color image
// Zero out any pixels that don't correspond to a body index
int colorMappedLength = this.colorMappedToDepthPoints.Length;
for (int colorIndex = 0; colorIndex < colorMappedLength; ++colorIndex)
{
float colorMappedToDepthX = colorMappedToDepthPointsPointer[colorIndex].X;
float colorMappedToDepthY = colorMappedToDepthPointsPointer[colorIndex].Y;

// The sentinel value is -inf, -inf, meaning that no depth pixel corresponds to this color pixel.
if (!float.IsNegativeInfinity(colorMappedToDepthX) &&
!float.IsNegativeInfinity(colorMappedToDepthY))
{
// Make sure the depth pixel maps to a valid point in color space
int depthX = (int)(colorMappedToDepthX + 0.5f);
int depthY = (int)(colorMappedToDepthY + 0.5f);

// If the point is not valid, there is no body index there.
if ((depthX >= 0) && (depthX < depthWidth) && (depthY >= 0) && (depthY < depthHeight))
{
int depthIndex = (depthY * depthWidth) + depthX;

// If we are tracking a body for the current pixel, do not zero out the pixel
if (bodyIndexBytes[depthIndex] != 0xff)
{
// this bodyIndexByte is good and is a body, loop again.
continue;
}
}
}
// this pixel does not correspond to a body so make it black and transparent
bitmapPixelsPointer[colorIndex] = 0;
}
}

this.bitmap.Invalidate();
FrameDisplayImage.Source = this.bitmap;
}

private void ShowDepthFrame(DepthFrame depthFrame)
{
bool depthFrameProcessed = false;
Expand Down Expand Up @@ -387,5 +524,17 @@ private void DepthButton_Click(object sender, RoutedEventArgs e)
SetupCurrentDisplay(DisplayFrameType.Depth);
}

private void BodyMaskButton_Click(object sender, RoutedEventArgs e)
{
SetupCurrentDisplay(DisplayFrameType.BodyMask);
}

[Guid("905a0fef-bc53-11df-8c49-001e4fc686da"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IBufferByteAccess
{
unsafe void Buffer(out byte* pByte);
}


}
}

0 comments on commit 7aca8b3

Please sign in to comment.