Kinect v2 + WPF获取RGB与Depth图像
date: 2017-09-04 14:51:07
Kinect V2的Depth传感器采用的是「Time of Flight(TOF)」的方式,
通过从投射的红外线反射后返回的时间来取得Depth信息。
本文将Kinect v2 + WPF来得到Kinect所获取的RGB(1920×1080)及Depth(512×424)图像
第一步:Kinect v2开发环境(仅限于本文)
- Visual Studio 2017
- 下载Kinect for Windows SDK 2.0并安装
第二步:创建工程
- 打开Visual Studio 2017, 创建一个WPF工程,名字随意(本文中例子为KinectTest)
- 在Solution Explorer中,右键单击KinectTest,在右键菜单中选择“Add Reference…”。弹出对话框后,在程序集中选择“Microsoft.Kinect”
第三步:编写代码
MainWindow.xaml代码
<Window x:Class="KinectTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:KinectTest"
mc:Ignorable="d"
Title="KinectTest" Height="1080" Width="1600">
<Grid>
<Image Name="RGB_Viewer" Source="{Binding ColorSource}" HorizontalAlignment="Left" Width="960" Height="540" Margin="0, 0, 0, 0"></Image>
<Image Name="Depth_Viewer" Source="{Binding DepthSource}" Width="512" Height="424" HorizontalAlignment="Right"></Image>
</Grid>
</Window>
MainWindow.xaml.cs代码
```cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Kinect;
namespace KinectTest
{
///
/// MainWindow.xaml 的交互逻辑
///
public partial class MainWindow : Window
{
private KinectSensor kinect = null; //用来标记kinect摄像头的实例
private ColorFrameReader colorFrame = null; //用来处理和保存摄像头传过来的彩色影像帧数据
private WriteableBitmap colorBitmap = null; //用来向Image控件中填充彩色影像数据
private FrameDescription colorFrameDescription = null; //用来描述彩色影响帧数据形态的参数
private const int MapDepthToByte = 8000 / 256;
private DepthFrameReader depthFrame = null;
private WriteableBitmap depthBitmap = null;
private FrameDescription depthFrameDescription = null;
private byte[] depthPixels = null;
public MainWindow()
{
this.kinect = KinectSensor.GetDefault(); //获取第一个或默认的Kinect摄像头
this.colorFrame = kinect.ColorFrameSource.OpenReader(); //打开彩色影像数据的获取接口
this.colorFrame.FrameArrived += ColorFrame_FrameArrived; //建立监听事件,当有彩色影像数据帧到达时触发
this.colorFrameDescription = this.kinect.ColorFrameSource.CreateFrameDescription(ColorImageFormat.Bgra);
//按照Bgra格式设定数据帧的描述信息(B:Blue,G:Green,R:Red,A:Alpha)
this.colorBitmap = new WriteableBitmap(colorFrameDescription.Width, colorFrameDescription.Height, 96.0, 96.0, PixelFormats.Bgr32, null);
//根据数据帧的宽高创建colorBitmap的实例
this.depthFrame = kinect.DepthFrameSource.OpenReader();
this.depthFrame.FrameArrived += DepthFrame_FrameArrived;
this.depthFrameDescription = kinect.DepthFrameSource.FrameDescription;
this.depthBitmap = new WriteableBitmap(depthFrameDescription.Width, depthFrameDescription.Height, 96.0, 96.0, PixelFormats.Gray8, null);
this.depthPixels = new byte[this.depthFrameDescription.Width * this.depthFrameDescription.Height];
this.kinect.Open(); //启动kinect摄像头
this.DataContext = this;
InitializeComponent();
}
private void ColorFrame_FrameArrived(object sender, ColorFrameArrivedEventArgs e)
{
using (ColorFrame frame = e.FrameReference.AcquireFrame()) //建立一个ColorFrame的实例frame保存送过来的帧,通过using保证走完函数后及时释放相应资源
{
if (frame != null)
{
this.colorBitmap.Lock(); //锁定一下数据文件,准备进行填充
frame.CopyConvertedFrameDataToIntPtr(this.colorBitmap.BackBuffer, (uint)(this.colorFrameDescription.Width * this.colorFrameDescription.Height * 4), ColorImageFormat.Bgra);
//提供给函数一个空间接收帧数据,将数据储存进colorBitmap的后台缓存中
this.colorBitmap.AddDirtyRect(new Int32Rect(0, 0, this.colorBitmap.PixelWidth, this.colorBitmap.PixelHeight));
//设定colorBitmap需要更改的位图区域,此处设定为整个图片
this.colorBitmap.Unlock(); //解锁位图资源
}
}
}
private void DepthFrame_FrameArrived(object sender, DepthFrameArrivedEventArgs e)
{
using (DepthFrame frame = e.FrameReference.AcquireFrame())
{
if (frame != null)
{
this.depthBitmap.Lock();
using (KinectBuffer _buffer = frame.LockImageBuffer())
{
Cvt_process(_buffer.UnderlyingBuffer, _buffer.Size, frame.DepthMinReliableDistance, ushort.MaxValue);
this.depthBitmap.WritePixels(
new Int32Rect(0, 0, this.depthBitmap.PixelWidth, this.depthBitmap.PixelHeight),
this.depthPixels,
this.depthBitmap.PixelWidth,
0);
}
this.depthBitmap.Unlock();
}
}
}
private unsafe void Cvt_process(IntPtr depthFrameDate, uint depthFrameDateSize, ushort minDepth, ushort maxDepth)
{
ushort* frameDate = (ushort*)depthFrameDate;//强制深度帧数据转为ushort型数组,frameDate指针指向它
for (int i = 0; i < (int)(depthFrameDateSize / this.depthFrameDescription.BytesPerPixel); ++i)
{
//深度帧各深度(像素)点逐个转化为灰度值
ushort depth = frameDate[i];
this.depthPixels[i] = (byte)((depth >= minDepth) && (depth <= maxDepth) ? (depth / MapDepthToByte) : 0);
}
}
public ImageSource ColorSource
{
get
{
return this.colorBitmap;
}
}
public ImageSource DepthSource
{
get
{
return this.depthBitmap;
}
}
}
}
Kinect v2 + WPF获取RGB与Depth图像的更多相关文章
- 【翻译】Kinect v2程序设计(C++) Depth编
Kinect SDK v2预览版,取得Depth数据的方法说明. 上一节,介绍了通过使用Kinect for Windows SDK v2预览版(以下简称为,Kinect SDK v2预览版)从Kin ...
- 【计算机视觉】深度相机(五)--Kinect v2.0
原文:http://blog.csdn.NET/qq1175421841/article/details/50412994 ----微软Build2012大会:Kinect for Windows P ...
- 【翻译】Kinect v1和Kinect v2的彻底比较
本连载主要是比较Kinect for Windows的现行版(v1)和次世代型的开发者预览版(v2),以C++开发者为背景介绍进化的硬件和软件.本文主要是对传感的配置和运行条件进行彻底的比较. ...
- vc/mfc获取rgb图像数据后动态显示及保存图片的方法
vc/mfc获取rgb图像数据后动态显示及保存图片的方法 该情况可用于视频通信中获取的位图数据回放显示或显示摄像头捕获的本地图像 第一种方法 #include<vfw.h> 加载 vfw3 ...
- 【翻译】Kinect v2程序设计(C++) Body 篇
Kinect SDK v2预览版的主要功能的使用介绍,基本上完成了.这次,是关于取得Body(人体姿势)方法的说明. 上一节,是使用Kinect SDK v2预览版从Kinect v2预览版取得B ...
- 【翻译】Kinect v2程序设计(C++) Color篇
Kinect SDK v2预览版,获取数据的基本流程的说明.以及取得Color图像的示例程序的介绍. 上一节,是关于当前型号Kinect for Windows(后面称作Kinect v1)和次世代型 ...
- ROS indigo下Kinect v2的驱动安装与调试
ROS indigo下Kinect v2的驱动安装与调试 一.libfreenect2源码安装与测试 github地址:https://github.com/OpenKinect/libfreenec ...
- 【翻译】Kinect v2程序设计(C++-) AudioBeam篇
Kinect v2,Microphone Array可以用来对于水平面音源方向的推测(AudioBeam)和语音识别(Speech Recognition).这一节是介绍如何取得AudioBeam. ...
- 【翻译】Kinect v2程序设计(C++) BodyIndex篇
通过Kinect SDK v2预览版,取得BodyIndex(人体区域)的方法和示例代码. 上一节,介绍了从Kinect v2预览版用Kinect SDK v2预览版获取Depth数据的方法. 这 ...
随机推荐
- 微信小程序自定义导航栏组件
1.首先,要在json文件中设置为自定义的形式 "navigationStyle": "custom" 2.计算相关值 导航栏分为状态栏和标题栏,只要能算出每台 ...
- .NET对接极光消息推送
什么是APP消息推送? 很多手机APP会不定时的给用户推送消息,例如一些新闻APP会给用户推送用户可能感兴趣的新闻,或者APP有更新了,会给用户推送是否选择更新的消息等等,这就是所谓的"消息 ...
- 使用.NET 6开发TodoList应用(29)——实现静态字符串本地化功能
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在开发一些需要支持多种语言的应用程序时,我们需要根据切换的语言来对应展示一些静态的字符串字段,在本文中我们暂时不去讨论如何结合 ...
- rocketmq实现延迟队列精确到秒级实现方案3-时间轮和秒级文件实现
时间轮和秒级文件实现原理图 这种方案比较简单实现,通过秒级时间,建立对应的文件夹,只要相同的时间超时的消息,就在同一个目录,通过msgid保证文件不重复,等到了时间后,就扫描对应的文件夹的文件,发送到 ...
- 云计算实验二 Docker实验-docker安装
一.实验目的 1.了解Docker服务安装: 2.掌握Docker镜像操作 二.实验内容 1.Docker服务安装 查看内核版本 uname -r 安装依赖环境: yum install -y yu ...
- MySQL数据类型操作(char与varchar)
目录 一:MySQL数据类型之整型 1.整型 2.验证不同类型的int是否会空出一个存储正负号 3.增加约束条件 去除正负号(unsigned) 二:浮点型 1.浮点型 2.验证浮点型精确度 三:字符 ...
- 码风QwQ
注:卡常.压行时怎么有效怎么来QwQ 快读真香.( 不喜欢用字符数组,使用string. 此时cin cout输入前会加这样三句以优化: ios::sync_with_stdio(0); cin.ti ...
- web.xml 配置文件?
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http:// ...
- react之每日一更(实现canvas拖拽,增、删、改拖拽模块大小功能)
效果图: import React, { Component } from 'react'; import scaleImage from './images/scale.png'; import c ...
- Java流程控制03:顺序结构
顺序结构 Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行. 顺序结构是最简单的算法结构.从上到下 语句与语句之间,框与框之间是按从上到下的顺序进行的,它是由若干个依次执行的处 ...