随着信息技术的飞速发展,人们对于计算机处理视频信息的能力提出了更高的要求。未来,计算机将能够识别和理解人类的体态、手势和情感表达,这将引发一场新的信息技术革命。为了实现这一目标,计算机需要使用新型的视频传感器,如Kinect传感器,来提供3D视频。Kinect传感器包含一个传统的彩色视频摄像头和一个红外光传感器,用于测量深度、位置和运动。Kinect传感器最初是为XBox 360游戏系统设计的,但很快,许多软件开发者开始尝试将其用于人体姿势和手势的识别。
坐姿识别算法基于人体骨架追踪,通过获取人体肩部(S)、臀部(H)和膝盖(K)的三维坐标(x_s, y_s, z_s)、(x_h, y_h, z_h)和(x_k, y_k, z_k),计算出坐姿与人体角度α之间的关系。坐姿识别算法能够区分左半身和右半身的角度α,并根据角度α和手部姿势,将坐姿归类为四种类型:睡觉、不集中、举手和非专注。
在开发过程中,遇到了两个主要问题:如何将彩色视频流和骨架图像简单地放置在一个窗口控件中,以及如何处理OpenNI/PrimeSense Nite和Microsoft SDK中视频帧和骨架帧的非同步刷新事件。为了解决这些问题,使用了WPF窗体,其中包含状态栏和网格面板。网格面板中包含一个图像控件和一个画布控件,它们具有相同的大小。
<Window x:Class="RecognitionPose.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="User tracking with Microsoft SDK"
Height="600" Width="862"
Loaded="Window_Loaded"
DataContext="{Binding}">
<DockPanel LastChildFill="True">
<StatusBar Name="statusBar" MinHeight="40" DockPanel.Dock="Bottom">
<StatusBarItem>
<TextBlock Name="textBlock" Background="LemonChiffon" FontSize="10">
Ready
</TextBlock>
</StatusBarItem>
</StatusBar>
<Grid DockPanel.Dock="Top">
<Image Name="imgCamera" Width="820" ClipToBounds="True" Margin="10,0"/>
<Canvas Width="820" Height="510" Name="skeleton" ClipToBounds="True"/>
</Grid>
</DockPanel>
</Window>
对于Microsoft SDK的情况,在SkeletonFrameReady事件处理程序中调用Recognition类的RecognizePose方法,该方法在imgCamera和骨架控件刷新后调用。SkeletonFrameRead事件处理程序通过将当前视频帧复制到平面图像临时变量中,然后将其复制到SkeletonFrameReady事件处理程序中的imgCamera.Source,从而实现与VideoFrameReady事件处理程序的同步。
对于OpenNi/PrimeSense Nite的情况,使用了NuiVision库来同步视频帧和骨架识别事件。在该库的UsersUpdated事件处理程序中调用RecognizePose方法。
坐姿识别的主要问题在于找到人体相对于Kinect传感器的距离和角度,以实现稳定的识别。为此,在应用程序设置中添加了五个参数来控制算法的行为:
发现,当这些参数具有以下值时,坐姿识别最稳定:
Kinect传感器位于地板上,传感器与坐姿人体之间的距离约为2米,人体相对于传感器旋转45度角。坐姿人体的位置优势在于Kinect传感器可以持续跟踪识别所需的人体部位:两个膝盖、一个臀部、两个肩膀、两个手和头部。对于其他人体位置,情况并非如此。例如,对于正面位置,传感器实际上不跟踪臀部;对于侧面位置,传感器只跟踪身体的一个部分:右侧或左侧。