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数据的方法. 这 ...
随机推荐
- Nginx 防爬虫设置
在conf下 vi 一个文件agent_deny.conf 添加如下内容 #禁止Scrapy|curl等工具的抓取 if ($http_user_agent ~* (Scrapy|Curl|Http ...
- java 反射 的详细总结
1.前言 什么是反射? 引用教科书的解释: 在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法: 对于任意一个对象,都能够调用它的任意方法和属性:这种动态获取信息以及动态调用对象方法的 ...
- js 动态设置键值对数组 ,类似于 java 的Map 类型
1.前言 我想设置一个数据 var json = {a1 :1 , a2 :2 , a3 :3 .....} 这样的动态数据 ,怎么写呢? 2.正确写法 var json = []; for ...
- println打印的原理
由于out是System类中的一个不可变的变量 println方法在PrintStream类中 并且在打印都时候都会转换成字符串
- HTTP API认证授权方案
目录 一.需求背景 二.常用的API认证技术 2.1 App Secret Key + HMAC 2.2 OAuth 2.0 2.2.1 Authorization Code Flow 2.2.2 C ...
- 【一个小发现】VictoriaMetrics中:vm-storage的备份文件,无法给单机版使用
首先导入一个按天的备份: vmrestore-prod \ -configFilePath="/etc/cos/config.ini" \ -credsFilePath=" ...
- Android开发 定时任务清理数据
原文地址:Android开发 定时任务清理数据 | Stars-One的杂货小窝 公司项目,需要整定时任务,对数据进行清理,需要在每天凌晨0:00进行数据的清理,使用了Alarm和广播的方式来实现 P ...
- VUE3 之 Non-Props 属性
1. 概述 墨菲定律告诉我们:人总是容易犯错误的,无论科技发展到什么程度,无论是什么身份的人,错误总是会在不经意间发生.因此我们最好在做重要的事情时,尽量去预估所有可能发生的错误,并思考错误发生后的补 ...
- JavaWeb概念及Web资源的分类
一,JavaWeb概念 1,JavaWeb,所有通过java语言编写可以通过浏览器访问的程序的总称 JavaWeb是基于请求和响应来开发的. 2,什么是请求 请求:指客户端给服务端发送数据,Reque ...
- ES_AutoCheck.sh
#!/bin/bash #@es_check #@date 2019/11/26 #@auth tigergao status=`curl -s GET "http://172.16.71. ...