Visual Studio结合C#调控Kinect俯仰角度

来源:互联网 发布:solidot知乎 编辑:程序博客网 时间:2024/05/01 16:15

总感觉自己前面啰啰嗦嗦写了好多,却一直都没有使用用开发kinect的重型武器——Visual Studio。

那么本次我们就借助于Visual Studio,写一个C#程序,连接Kinect并调用Kinect SDK标准函数库来改变Kinect的俯仰角。

首先我们打开VS创建一个项目。选择Visual C#下面的Windows,然后选择控制台应用程序,命名为Kinect_Controller,选择你自己的保存路径。

建完之后,来到解决方案资源管理器。找到引用,右键——添加引用,在弹出的引用管理器中,右上角直接搜索Kinect,勾选MicrosoftKinect 1.8.0.0,然后点击确定。

如果组件引用设置正常的话,我们就可以在引用下面看到Kinect的相关组件。

接下来是我们的主程序。先在这里把全部的代码贴出来再解释。

using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tasks;using Microsoft.Kinect;using System.Threading;namespace Kinect_Controller{    class Program    {        static void Main(string[] args)        {            KinectSensor sensor = KinectSensor.KinectSensors[0];            if (sensor == null)            {                Console.WriteLine("找不到任何可用的Kinect装置,程序退出");                return;            }            sensor.Start();//获取连接在PC上的第一个传感器并且启动            sensor.ElevationAngle = 0;//俯仰角度恢复到零度            Console.WriteLine("Kinect已启动,空格键退出");            Console.WriteLine("现在角度为" + 0);            ConsoleKey press;//向上箭头加5度,向下箭头减5度,并内置最大最小角度检测            while((press = Console.ReadKey().Key)!= ConsoleKey.Spacebar)            {                if (press == ConsoleKey.DownArrow)                {                    if (sensor.ElevationAngle - 5 < sensor.MinElevationAngle)                        sensor.ElevationAngle = sensor.MinElevationAngle;                    else                        sensor.ElevationAngle = sensor.ElevationAngle - 5;                }                else if(press == ConsoleKey.UpArrow)                {                    if (sensor.ElevationAngle + 5 > sensor.MaxElevationAngle)                        sensor.ElevationAngle = sensor.MaxElevationAngle;                    else                        sensor.ElevationAngle = sensor.ElevationAngle + 5;                }                Thread.Sleep(1000);                Console.WriteLine("现在角度为"+ sensor.ElevationAngle);            }            sensor.Stop();        }    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54

下面我们来从上向下详细解释一下代码。
(1)我们在最上方加入了两个命名空间。
using Microsoft.Kinect;//告知编译程序使用该命名空间,所有的用C#写的Kinect程序都需要如此。
using System.Threading;//程序中使用了Thread方法,所以要引入此命名空间。

(2)获得传感器
KinectSensor sensor = KinectSensor.KinectSensors[0];
直到sensor.Start();这一代码段,是要获取与pc连接的第一个Kinect传感器。如果为空,则输出”找不到任何可用的Kinect装置,程序退出”,若不为空,则启动Kinect。

(3)重置角度
Kinect的俯仰角度可能因为人为原因或者程序原因初始情况并不位于零度,所以启动Kinect后,我们首先要重置Kinect的角度。使用sensor.ElevationAngle = 0,并且输出两句话来说明我们的程序。

(4)结合边界机制上下方向键调节角度
因为Kinect中角度俯仰范围为-27~27,所以我们要加入检测机制。
这个并不困难,原理是读入的按钮如果是上方向键(下方向键),角度如果加5度(减5度)后不超过最大角度那么是安全的,如果将会超过,那么就让它的角度等于最大角度。

sensor.MinElevationAngle和sensor.MaxElevationAngle分别是-27和+27。

并且在调整角度后,输出当前的角度,以提醒操作者

(5)退出
while((press = Console.ReadKey().Key)!= ConsoleKey.Spacebar)
这是while的条件,所以当我们按下空格的时候,会跳出转而直接执行sensor.Stop()退出程序。

(6)注意事项以及存在的问题
Kinect for Windows 1.0的官方文档中提到,1秒钟内最多改变一次角度,连续改变15次后,系统将强制休息20秒以防止电机过热,这也是为什么我们会引入Thread(1000)的原因,就是契合这一要求让Kinect得到充分的休息和冷却。

因为这一点,我们的程序本身就难免会存在一些问题,如果你按下上下方向键的频率快于一秒,键盘的输入会累积在缓冲区等待处理,因为我们的设定是等一秒,处理一次。这会造成很大的延迟和卡顿。我们可以根据需要做一些优化处理,即在沉睡的1秒内,将键盘输入无效化,这一次我们先不做深入讨论,因为写博文的时候,我的C#也是有点儿惨不忍睹的。

最后一个是.NET组件版本的问题,默认情况下,VS认为你的程序需要绑定特定版本的.NET组件。这样就会造成组件升级后,VS找不到原来版本的组件而无法编译。所以在解决方案资源管理器中,选中Microsoft.Kinect右键——属性,特定版本改为False就可以了。

下面来自己跑一跑这个Kinect程序,运行结果如下。

注:博文中代码参考并修改自《Kinect体感程序设计入门》。

2015.3.25 10:05
By 张伟

(function () {('pre.prettyprint code').each(function () { var lines = (this).text().split(\n).length;varnumbering = $('
    ').addClass('pre-numbering').hide(); (this).addClass(hasnumbering).parent().append(numbering); for (i = 1; i
    0 0