狙击手作战
下面的程序使用Kinect实现的是一个红点始终瞄向一个人的头部。
在MainWindow中拖放一个canvas控件,在在这个canvas控件上放置一个Image控件,这个Image控件名字为Imagecamara。
程序在上面的一篇文章的基础上改的。
1:在startKinect上注册skeleton事件:
注册完之后开始写这个_kinect_SkeletonFrameReady函数。
在这个函数中添加了一个private变量skeletons,用来存储几个joints。
最后再把狙击枪发射的小红点写到下面的函数里。
ok,狙击手出现了。
下面是实现的具体代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
namespace WpfApplication2
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private KinectSensor _kinect;
const float MaxDepthDistance = 4095;
const float MinDepthDistance = 850;
const float MaxDepthDistanceOffSet = MaxDepthDistance - MinDepthDistance;
private const int RedIndex = 2;
private const int GreenIndex = 1;
private const int BlueIndex = 0;
private void startKinect()
{
if (KinectSensor.KinectSensors.Count > 0)
{
_kinect = KinectSensor.KinectSensors[0];
MessageBox.Show("kinect 目前的状态为:" + _kinect.Status);
_kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);
_kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);
_kinect.SkeletonStream.Enable();
_kinect.AllFramesReady +=
new EventHandler<AllFramesReadyEventArgs>(_kinect_AllFramesReady);
_kinect.SkeletonFrameReady +=
new EventHandler<SkeletonFrameReadyEventArgs>(_kinect_SkeletonFrameReady);
_kinect.Start();
}//if
else
{
MessageBox.Show("没有任何Kinect设备");
}
}//start kinect
private Skeleton[] skeletons;
void _kinect_SkeletonFrameReady(object sender, SkeletonFrameReadyEventArgs e)
{
//bool
bool isSkeletonDataReady = false;
using (SkeletonFrame skeletonFrame = e.OpenSkeletonFrame())
{
if (skeletonFrame != null)
{
skeletons = new Skeleton[skeletonFrame.SkeletonArrayLength];
skeletonFrame.CopySkeletonDataTo(skeletons);
isSkeletonDataReady = true;
}//if
}//using
if (isSkeletonDataReady)
{
Skeleton currentSkelton = (from s in skeletons
where
s.TrackingState == SkeletonTrackingState.Tracked
select s).FirstOrDefault();
if (currentSkelton != null)
{
lockHeadWithRedSpot(currentSkelton);
}//IF NULL
}//ready
}//skeleton
void lockHeadWithRedSpot(Skeleton s)
{
Joint head = s.Joints[JointType.Head];
ColorImagePoint colorPoint =
_kinect.MapSkeletonPointToColor(head.Position, _kinect.ColorStream.Format);
Point p = new Point(
(int)(imageCamera.Width * colorPoint.X / _kinect.ColorStream.FrameWidth),
(int)(imageCamera.Height * colorPoint.Y / _kinect.ColorStream.FrameHeight)
);
Canvas.SetLeft(ellipse1, p.X);
Canvas.SetTop(ellipse1, p.Y);
}//lock
void _kinect_AllFramesReady(object sender, AllFramesReadyEventArgs e)
{
using (ColorImageFrame colorFrame = e.OpenColorImageFrame())
{
if (colorFrame == null)
{
return;
}//if null
byte[] pixels = new byte[colorFrame.PixelDataLength];
colorFrame.CopyPixelDataTo(pixels);
int stride = colorFrame.Width * 4;
imageCamera.Source =
BitmapSource.Create(colorFrame.Width, colorFrame.Height,
96, 96, PixelFormats.Bgr32, null, pixels, stride);
}
using (DepthImageFrame depthFrame = e.OpenDepthImageFrame())
{
if (depthFrame == null)
{
return;
}
byte[] pixels = convertDepthFrameToColorFrame(depthFrame);
int stride = depthFrame.Width * 4;
imageDepth.Source = BitmapSource.Create(depthFrame.Width, depthFrame.Height,
96, 96, PixelFormats.Bgr32, null, pixels, stride);
}//depth frame ;
//throw new NotImplementedException();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
startKinect();
}
private byte[] convertDepthFrameToColorFrame(DepthImageFrame depthFrame)
{
short[] rawDepthData = new short[depthFrame.PixelDataLength];
depthFrame.CopyPixelDataTo(rawDepthData);
byte[] pixels = new byte[depthFrame.Height * depthFrame.Width*4 ];
for (int depthIndex = 0, colorIndex = 0;
depthIndex < rawDepthData.Length && colorIndex < pixels.Length;
depthIndex++, colorIndex+=4)
{
int player = rawDepthData[depthIndex] & DepthImageFrame.PlayerIndexBitmask;
int depth = rawDepthData[depthIndex] >> DepthImageFrame.PlayerIndexBitmaskWidth;
if (depth <= 900)
{
pixels[colorIndex + BlueIndex] = 255;
pixels[colorIndex + GreenIndex] = 0;
pixels[colorIndex + RedIndex] = 0;
}//距离Kinect很近
else if (depth > 900 && depth < 2000)
{
pixels[colorIndex + BlueIndex] = 0;
pixels[colorIndex + GreenIndex] = 255;
pixels[colorIndex + RedIndex] = 0;
}//900,20000
else if (depth > 2000)
{
pixels[colorIndex + BlueIndex] = 0;
pixels[colorIndex + GreenIndex] = 0;
pixels[colorIndex + RedIndex] = 255;
}//2000
if (player > 0)
{
pixels[colorIndex + BlueIndex] = Colors.LightGreen.B;
pixels[colorIndex + GreenIndex] = Colors.LightGreen.G;
pixels[colorIndex + RedIndex] = Colors.LightGreen.R;
}
}//for
return pixels;
}
private void image1_ImageFailed(object sender, ExceptionRoutedEventArgs e)
{
}//convert
}
}