看完Kinect官方视频中的捕捉头部位置的那个视频,我在想能不能把右手的位置也给捕捉出来,在第一个红外图像的基础上我进行了第二个实验—捕捉右手的位置
首先要捕捉到右手的位置,故这里我们用到人体读出器:private MultiSourceFrameReader msfr=null;
于是我们开始找人的位置(也就找到了手部的位置,这个Kinect的库里提供了捕捉手部位置的函数),找到后用UI中的Ellipase在手部位置处画一个圆,当然以手心为中心
foreach (Body body in bodies)//逐个看下,找到头部关节点
{
if (body.IsTracked)//对于每个人,我们都要给出那个数组中的每个位置,所以要确保人体被跟踪
{
Joint headjoint = body.Joints[JointType.HandRight];//加入右手的关节点
if (headjoint.TrackingState == TrackingState.Tracked)//找到它在空间中的位置
{
DepthSpacePoint msr= mysensor.CoordinateMapper.MapCameraPointToDepthSpace(headjoint.Position);//确定头部的位置
Ellipse headcircle = new Ellipse() { Width = 50, Height = 50, Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };//画一个圆
bodycavas.Children.Add(headcircle);//添加在跟踪的头部上
Canvas.SetLeft(headcircle,msr.X-25);
Canvas.SetTop(headcircle,msr.Y-25);//为了以头部为中心
}
}
}
具体的多元处理事件如下:
void msfr_MultiSourceFrameArrived(object sendor, MultiSourceFrameArrivedEventArgs args)
{
MultiSourceFrame msf = args.FrameReference.AcquireFrame();//为什么不能用using()?
if (msf != null)
{//打开一张人体帧
using (BodyFrame bodyframe = msf.BodyFrameReference.AcquireFrame())
{//获取一张红外图像
using (InfraredFrame irFrame = msf.InfraredFrameReference.AcquireFrame())
{//保证获取的数据不为空
if (bodyframe != null && irFrame != null)
{ //接下来就是红外帧事件的拷贝了,而不是重写一次
irFrame.CopyFrameDataToArray(this._infrareddata);
for (int i = 0; i < this._infrareddata.Length; i++)
{
byte inteensity = (byte)(this._infrareddata[i] >> 8);
this._infrareddataConverted[i * 4] = inteensity;
this._infrareddataConverted[i * 4 + 1] = inteensity;
this._infrareddataConverted[i * 4 + 2] = inteensity;
this._infrareddataConverted[i * 4 + 3] = 255;
}
this.redinframebitmap.WritePixels(new Int32Rect(0, 0, 512, 424), this._infrareddataConverted, 512 * 4, 0);
bodyframe.GetAndRefreshBodyData(bodies);//获取人体数据,从之前设置的人体数组中
bodycavas.Children.Clear();
foreach (Body body in bodies)//逐个看下,找到头部关节点
{
if (body.IsTracked)//对于每个人,我们都要给出那个数组中的每个位置,所以要确保人体被跟踪
{
Joint headjoint = body.Joints[JointType.HandRight];//加入右手的关节点
if (headjoint.TrackingState == TrackingState.Tracked)//找到它在空间中的位置
{
DepthSpacePoint msr= mysensor.CoordinateMapper.MapCameraPointToDepthSpace(headjoint.Position);//确定头部的位置
Ellipse headcircle = new Ellipse() { Width = 50, Height = 50, Fill = new SolidColorBrush(Color.FromArgb(255, 255, 0, 0)) };//画一个圆
bodycavas.Children.Add(headcircle);//添加在跟踪的头部上
Canvas.SetLeft(headcircle,msr.X-25);
Canvas.SetTop(headcircle,msr.Y-25);//为了以头部为中心
}
}
}
}
}
}
}
}
之后添加一个 Body[] bodies;//储存人体信息的数组
主程序中加个多元帧的处理事件就可以了,如下:
bodies = new Body[6];//人体的数据,最多可同时存放6人
msfr = mysensor.OpenMultiSourceFrameReader(FrameSourceTypes.Body|FrameSourceTypes.Infrared);
//
this.msfr.MultiSourceFrameArrived += msfr_MultiSourceFrameArrived;//订阅多源帧到达事件
具体的运行效果图如下: