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数据的方法. 这 ...
随机推荐
- mysql 的 limit 与sql server 的 top n
1.东西学多了,难免会混淆 貌似没有错,但是mysql不支持 top n 语法 而是使用 limit n 或 limit n , m 2. top n 语法 是SQL server 的
- Vue-cli代理解决跨域问题
使用vue-cli调接口的时候,总是会出现垮与问题,因为vue的localhost与访问域名不一致导致.而这一点,开发者显然也想到了,故而在vuejs-templates,也就是vue-cli的使用的 ...
- 【Java】eclipse中的JUnit单元测试
eclipse中的JUnit单元测试 步骤: 选中当前工程 - 右键选择:build path - add libraries - JUnit 4 - 下一步 创建Java类,进行单元测试. 此时的J ...
- 简单Spring MVC项目搭建
1.新建Project 开发环境我使用的是IDEA,其实使用什么都是大同小异的,关键是自己用的顺手. 首先,左上角File→New→Project.在Project页面选择Maven,然后勾上图中所示 ...
- 互联网医疗行业PEST分析实践
前言 今年开始逐步切入产品与数据工作,完全脱离了原来的舒适区,确实有一些挑战.开始以为只做数仓建设的事情,就仓促的学习了一些数仓相关的知识,但没搞多久,还要负责公司BI的工作,又开始补习数分相关的知识 ...
- Ubuntu 桌面版使用总结
最近拿出了大学时买的性(游)能(戏)本(机),其实从直观来看,硬件基础还是不错的,但是跑 WIN10, 清了各种广告,关了各种无效进城之后,用起来仍然还是很不爽.可能是已经用惯 mac 了吧,mac给 ...
- C# 文件对话框例子
OpenFileDialog控件的基本属性InitialDirectory:对话框的初始目录 Filter: 获取或设置当前文件名筛选器字符串,例如,"文本文件(*.txt)|*.txt|所 ...
- MobaXterm中文乱码问题
现在Xshell和SecureCRT都要收费,本着不用盗版的原则,同时需要标签管理session,快捷命令等功能,最后选择了MobaXterm. 但是使用后发现中文会乱码.后按照博客的方法,修改了终端 ...
- Servlet Filter(过滤器)
Servlet Filter 又称 Servlet 过滤器,它是在 Servlet 2.3 规范中定义的,能够对 Servlet 容器传给 Web 资源的 request 对象和 response 对 ...
- Error:(3, 21) java: 程序包javax.servlet不存在的解决方法
采用 https://blog.csdn.net/GK666_/article/details/106442929得到解决