using Microsoft.Kinect;
bool isWindowClosing = false;//窗口是否正在关闭
const int MaxSkeletonTrackingCount = 6;//最多同时跟踪用户6人
Skeleton[] allSkeletion = new Skeleton[MaxSkeletonTrackingCount];
int operaFaceIndex = 0;//脸谱编号
//启动窗口
private void Window_Loaded(object sender,RoutedEventArgs e)
{
hideOperaFace();//隐藏道具
KinectSensorChooser1.KinectSensorChanged += new DependencyPropertyChangedEventHandler(KinectSensor Chooser1_KinectSensorchanged);//一旦KinectSensorChanged触发就执行KinectSensorChooser1_KinectSensorchanged方法
}
//关闭窗口
private void Window_Closing(object sender,System.ComponentModle.CancelEventArgs e)
{
isWindowClosing = true;
stopKinect(KinectSensorChooser1.Kinect);//关闭Kinect
}
//Kinect设备状态监听事件
void KinectSensorChooser1_KinectSensorchanged(object sender,DependencyPropertyChangedEventArgs e)
{
KinectSensor oldKinect = (KinectSensor)e.OldValue;
stopKinect(oldKinect);
KinectSensor Kinect = (KinectSensor)e.NewValue;
if(Kinect == null)
{
return ;
}
Kinect.DepthStream.Enable(DepthImageFormat.Resolution640x480Fps30);//启用深度流,分辨率640*480,每秒30帧
Kinect.ColorStream.Enable(ColorImageFormat.RgbResolution640x480Fps30);//启用视频流
Kinect.SkeletonStream.Enable();//启用骨骼追踪
Kinect.AllFreamsReady += new EventHandler<AllFreamsReadyEventArgs>(Kinect_AllFreamsReady);//注册事件,该方法将保证彩色图像、深度图像和骨骼数据同步
try
{
KinectColorViewer1.Kinect = Kinect;//显示彩色摄像头
Kinect.start();//启动
}
catch(System.IO.IOException)//抛出异常
{
KinectSensorChooser1.AppConflictOccurred();
}
}
//关闭Kinect
private void stopKinect(KinectSensor sensor)
{
if(sensor != null)
{
if(sensor.IsRunning)
{
sensor.stop();
}
if(sensor.AudioSource != null)//如果音频流打开
{
sensor.AudioSource.Stop();
}
}
}
//骨骼跟踪核心代码
void Kinect_AllFreamsReady(object sender,AllFreamsReadyEventArgs e)
{
if(isWindowClosing)
{
return ;
}
//仅获得第一个被骨骼跟踪的用户
Skeleton first = GetFirstSkeleton(e);
if(first == null)
{
hideOperaFace();
return ;
}
if(first.TrackingState != SkeletonTrackingState.Tracked)
{
hideOperaFace();
}
else
{
ShowOperaFace();
}
mappingSkeleton2CameraCoordinate(first,e);//坐标映射
operaFaceMagic(first);//表演变脸
}
//查找第一个被骨骼跟踪的对象
Skeleton GetFirstSkeleton(AllFreamsReadyEventArgs e)
{
using (SkeletonFream skeletonFreamData = e.OpenSkeletonFream())
{
if(skeletonFreamData == null)
{
return null;
}
skeletonFreamData.CopySkeletonDataTo(allSkeletions);
//LINQ语法,用于查找第一个被跟踪的骨骼
Skeleton first = ( from s in allSkeletions where s.TrackingState==SkeletonTrackingState.Tracked select s).FirstOrDefault();
return first;
}
}
//判断是否遮挡住脸部
bool isTowSkeletonPointOverlapping (SkeletPoint p1,SketletPoint p2)
{
bool isOverlapping = (Math.abs(p1.x-p2.x)<=0.05&&Math.abs(p1.y-p2.y)<=0.05);
return isOverlapping;
}
//循环显示三张不同的川剧脸谱,中间抹去脸谱
void operaFaceMagic(Skeleton first)
{
if(isTowSkeletonPointOverlapping(first.Joints[JointType.Head].Position,first.Joints[JointType.HandRight].Position)||isTowSkeletonPointOverlapping(first.Joints[JointType.Head].Position,first.Joints[JointType.HandLeft].Position))
{
operaFaceIndex ++;
operaFaceIndex %= 3;
if(operaFaceIndex == 0)
{
headImage.Source = null;//抹去脸谱
}
else
{
String OperaFace = "pack://application:,,,/images/face"+operaFaceIndex+".png";
headImage.Source = new BitmapImage(newUri(OperaFace));
}
}
}
//骨骼坐标系映射为彩色图像坐标系,再进一步映射到屏幕坐标系
void mappingSkeleton2CameraCoordinate(Skeleton first,AllFreamsReadyEventArgs e)
{
using(DepthImageFrame depth = e.OpenDepthImageFrame())
if(depth=null || kinectSensorChoosor1.Kinect==null)
{
return ;
}
//骨骼坐标系映射为彩色图像坐标系
ColorImagePoint headColorPoint = KinectSensorChooser1.Kinect.MapSkeletonPointToColor(first.Joints[JointType.Head].Position,ColorImageFormat.RgbResolution640x480Fps30);
ColorImagePoint leftColorPoint = KinectSensorChooser1.Kinect.MapSkeletonPointToColor(first.Joints[JointType.HandLeft].Position,ColorImageFormat.RgbResolution640x480Fps30);
ColorImagePoint rightColorPoint = KinectSensorChooser1.Kinect.MapSkeletonPointToColor(first.Joints[JointType.HandRight].Position,ColorImageFormat.RgbResolution640x480Fps30);
//修正为中心位置
adjustCameraPosition(headImage,headColorPoint);
adjustCameraPosition(leftEllipse,leftColorPoint);
adjustCameraPosition(rightEllipse,rightColorPoint);
}
//修正为中心位置
private void adjustCameraPosition(FrameWorkElement element,ColorImagePoint point);
{
Canvas.SetLeft(element,point.X-element.Width/2);
Canvas.SetTop(element,point.Y-element.Height/2);
}
Kinect 川剧脸谱变脸
最新推荐文章于 2024-07-11 23:20:46 发布