Kinect 川剧脸谱变脸

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);
}

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值