Realsense 提取彩色和深度视频流

一、简要介绍

关于realsense的介绍,网上很多,这里不再赘述,sdk及相关文档可参考realsense SDK,也可参考开发人员专区

运行代码之前,要确保你已经安装好了realsense的DCM和SDK,官网有教程,具体请参考DCM和SDK安装步骤

二、代码

[cpp] view plain copy print?

  1. #include <pxcsensemanager.h>
  2. #include <pxcsession.h>
  3. #include "util_render.h"
  4. #include <iostream>
  5. #include <string>
  6. #include <stdio.h>
  7. #include <opencv2\opencv.hpp>
  8. #include <windows.h>
  9. #define WIDTH 640
  10. #define HEIGHT 480
  11. using namespace cv;
  12. using namespace std;
  13. int main(int argc, char** argv)
  14. {
  15. UtilRender *renderColor = new UtilRender(L"COLOR_STREAM");
  16. UtilRender *renderDepth = new UtilRender(L"DEPTH_STREAM");
  17. PXCSenseManager *psm = 0;
  18. psm = PXCSenseManager::CreateInstance();
  19. if (!psm)
  20. {
  21. wprintf_s(L"Unabel to create the PXCSenseManager\n");
  22. return 1;
  23. }
  24. pxcStatus sts;
  25. psm->EnableStream(PXCCapture::STREAM_TYPE_COLOR, WIDTH, HEIGHT);
  26. psm->EnableStream(PXCCapture::STREAM_TYPE_DEPTH, WIDTH, HEIGHT);
  27. sts = psm->Init();
  28. if (sts != PXC_STATUS_NO_ERROR)
  29. {
  30. wprintf_s(L"Unabel to Initializes the pipeline\n");
  31. return 2;
  32. }
  33. PXCImage *colorIm, *depthIm;
  34. PXCImage::ImageData depth_data,color_data;
  35. PXCImage::ImageInfo depth_info,color_info;
  36. while (psm->AcquireFrame(true) >= PXC_STATUS_NO_ERROR)
  37. {
  38. if (psm->AcquireFrame(true) < PXC_STATUS_NO_ERROR) break;
  39. PXCCapture::Sample *sample = psm->QuerySample();
  40. colorIm = sample->color;
  41. depthIm = sample->depth;
  42. if (colorIm->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, &color_data) < PXC_STATUS_NO_ERROR)
  43. wprintf_s(L"未正常获取彩色图\n");
  44. if (depthIm->AcquireAccess(PXCImage::ACCESS_READ, &depth_data) < PXC_STATUS_NO_ERROR)
  45. wprintf_s(L"未正常获取深度图\n");
  46. depth_info = sample->depth->QueryInfo();
  47. color_info = sample->color->QueryInfo();
  48. Mat depth(Size(depth_info.width, depth_info.height), CV_16UC1, (void*)depth_data.planes[0], depth_data.pitches[0] / sizeof(uchar));
  49. Mat color(Size(color_info.width, color_info.height), CV_8UC3, (void*)color_data.planes[0], color_data.pitches[0] / sizeof(uchar));
  50. depthIm->ReleaseAccess(&depth_data);
  51. colorIm->ReleaseAccess(&color_data);
  52. if (!renderColor->RenderFrame(colorIm)) break;
  53. if (!renderDepth->RenderFrame(depthIm)) break;
  54. psm->ReleaseFrame();
  55. imshow("color", color);
  56. waitKey(1);
  57. //CV_16UC1的图片在imshow时会除以256,将最远探测距离设为z,那么imshow时可以乘以255*256/z,此处乘以15
  58. imshow("depth", depth * 15);
  59. waitKey(1);
  60. }
  61. psm->Release();
  62. system("pause");
  63. }

#include <pxcsensemanager.h>
#include <pxcsession.h>
#include "util_render.h"
#include <iostream>
#include <string>
#include <stdio.h>
#include <opencv2\opencv.hpp>
#include <windows.h>

#define WIDTH 640
#define HEIGHT 480  

using namespace cv;
using namespace std;

int main(int argc, char** argv)
{
	UtilRender *renderColor = new UtilRender(L"COLOR_STREAM");
	UtilRender *renderDepth = new UtilRender(L"DEPTH_STREAM");

	PXCSenseManager *psm = 0;
	psm = PXCSenseManager::CreateInstance();
	if (!psm)
	{
		wprintf_s(L"Unabel to create the PXCSenseManager\n");
		return 1;
	}
	pxcStatus sts;

	psm->EnableStream(PXCCapture::STREAM_TYPE_COLOR, WIDTH, HEIGHT);

	psm->EnableStream(PXCCapture::STREAM_TYPE_DEPTH, WIDTH, HEIGHT);

	sts = psm->Init();
	if (sts != PXC_STATUS_NO_ERROR)
	{
		wprintf_s(L"Unabel to Initializes the pipeline\n");
		return 2;
	}

	PXCImage *colorIm, *depthIm;
	PXCImage::ImageData depth_data,color_data;
	PXCImage::ImageInfo depth_info,color_info;
	while (psm->AcquireFrame(true) >= PXC_STATUS_NO_ERROR)

	{
		if (psm->AcquireFrame(true) < PXC_STATUS_NO_ERROR) break;

		PXCCapture::Sample *sample = psm->QuerySample();

		colorIm = sample->color;
		depthIm = sample->depth;

		if (colorIm->AcquireAccess(PXCImage::ACCESS_READ, PXCImage::PIXEL_FORMAT_RGB24, &color_data) < PXC_STATUS_NO_ERROR)
			wprintf_s(L"未正常获取彩色图\n");
		if (depthIm->AcquireAccess(PXCImage::ACCESS_READ, &depth_data) < PXC_STATUS_NO_ERROR)
			wprintf_s(L"未正常获取深度图\n");

		depth_info = sample->depth->QueryInfo();
		color_info = sample->color->QueryInfo();

		Mat depth(Size(depth_info.width, depth_info.height), CV_16UC1, (void*)depth_data.planes[0], depth_data.pitches[0] / sizeof(uchar));
		Mat color(Size(color_info.width, color_info.height), CV_8UC3, (void*)color_data.planes[0], color_data.pitches[0] / sizeof(uchar));

		depthIm->ReleaseAccess(&depth_data);
		colorIm->ReleaseAccess(&color_data);

		if (!renderColor->RenderFrame(colorIm)) break;
		if (!renderDepth->RenderFrame(depthIm)) break;

		psm->ReleaseFrame();

		imshow("color", color);
		waitKey(1);
		//CV_16UC1的图片在imshow时会除以256,将最远探测距离设为z,那么imshow时可以乘以255*256/z,此处乘以15
		imshow("depth", depth * 15);
		waitKey(1);

	}
	psm->Release();
	system("pause");
}

三、相关解释

新建项目,写入源代码,生成解决方案之前,记得要在项目的属性管理器右键项目,选择添加现有属性表,选择C:\Program Files (x86)\Intel\RSSDK\props目录下的一个官方配置好的属性表(前提是DCM和SDK的安装路径是默认路径,没有自行修改);另外因为我们还要进行cv::Mat类型的转化,所以也要导入opencv的属性表。

运行之后,可以看到4个窗口,COLOR_STREAM和DEPTH_STREAM为分别realsense提取到的彩色视频流和深度视频流;color和depth分别为我们转化为opencv中mat类型之后的彩色和深度视频流。

目前实现pxcimage到mat类型转化的方法有好几种,大体类似,主要是对PXCImage::ImageData中的plane和pitch的理解,博主理解为plane[0]为该sdk中图片数据的首地址,pitches可参考http://www.cnblogs.com/gamedes/p/4541765.html。

也看到论坛上有人专门写过pxcimage到mat类型的转化函数,函数代码如下:

[cpp] view plain copy print?

  1. void ConvertPXCImageToOpenCVMat(PXCImage *inImg, Mat *outImg) {
  2. int cvDataType;
  3. int cvDataWidth;
  4. PXCImage::ImageData data;
  5. inImg->AcquireAccess(PXCImage::ACCESS_READ, &data);
  6. PXCImage::ImageInfo imgInfo = inImg->QueryInfo();
  7. switch (data.format) {
  8. /* STREAM_TYPE_COLOR */
  9. case PXCImage::PIXEL_FORMAT_YUY2: /* YUY2 image  */
  10. case PXCImage::PIXEL_FORMAT_NV12: /* NV12 image */
  11. throw(0); // Not implemented
  12. case PXCImage::PIXEL_FORMAT_RGB32: /* BGRA layout on a little-endian machine */
  13. cvDataType = CV_8UC4;
  14. cvDataWidth = 4;
  15. break;
  16. case PXCImage::PIXEL_FORMAT_RGB24: /* BGR layout on a little-endian machine */
  17. cvDataType = CV_8UC3;
  18. cvDataWidth = 3;
  19. break;
  20. case PXCImage::PIXEL_FORMAT_Y8:  /* 8-Bit Gray Image, or IR 8-bit */
  21. cvDataType = CV_8U;
  22. cvDataWidth = 1;
  23. break;
  24. /* STREAM_TYPE_DEPTH */
  25. case PXCImage::PIXEL_FORMAT_DEPTH: /* 16-bit unsigned integer with precision mm. */
  26. case PXCImage::PIXEL_FORMAT_DEPTH_RAW: /* 16-bit unsigned integer with device specific precision (call device->QueryDepthUnit()) */
  27. cvDataType = CV_16U;
  28. cvDataWidth = 2;
  29. break;
  30. case PXCImage::PIXEL_FORMAT_DEPTH_F32: /* 32-bit float-point with precision mm. */
  31. cvDataType = CV_32F;
  32. cvDataWidth = 4;
  33. break;
  34. /* STREAM_TYPE_IR */
  35. case PXCImage::PIXEL_FORMAT_Y16:          /* 16-Bit Gray Image */
  36. cvDataType = CV_16U;
  37. cvDataWidth = 2;
  38. break;
  39. case PXCImage::PIXEL_FORMAT_Y8_IR_RELATIVE:    /* Relative IR Image */
  40. cvDataType = CV_8U;
  41. cvDataWidth = 1;
  42. break;
  43. }
  44. // suppose that no other planes
  45. if (data.planes[1] != NULL) throw(0); // not implemented
  46. // suppose that no sub pixel padding needed
  47. if (data.pitches[0] % cvDataWidth!=0) throw(0); // not implemented
  48. outImg->create(imgInfo.height, data.pitches[0] / cvDataWidth, cvDataType);
  49. memcpy(outImg->data, data.planes[0], imgInfo.height*imgInfo.width*cvDataWidth*sizeof(pxcBYTE));
  50. inImg->ReleaseAccess(&data);
  51. }

void ConvertPXCImageToOpenCVMat(PXCImage *inImg, Mat *outImg) {
    int cvDataType;
    int cvDataWidth;

    PXCImage::ImageData data;
    inImg->AcquireAccess(PXCImage::ACCESS_READ, &data);
    PXCImage::ImageInfo imgInfo = inImg->QueryInfo();

    switch (data.format) {
        /* STREAM_TYPE_COLOR */
        case PXCImage::PIXEL_FORMAT_YUY2: /* YUY2 image  */
        case PXCImage::PIXEL_FORMAT_NV12: /* NV12 image */
            throw(0); // Not implemented
        case PXCImage::PIXEL_FORMAT_RGB32: /* BGRA layout on a little-endian machine */
            cvDataType = CV_8UC4;
            cvDataWidth = 4;
            break;
        case PXCImage::PIXEL_FORMAT_RGB24: /* BGR layout on a little-endian machine */
            cvDataType = CV_8UC3;
            cvDataWidth = 3;
            break;
        case PXCImage::PIXEL_FORMAT_Y8:  /* 8-Bit Gray Image, or IR 8-bit */
            cvDataType = CV_8U;
            cvDataWidth = 1;
            break;

        /* STREAM_TYPE_DEPTH */
        case PXCImage::PIXEL_FORMAT_DEPTH: /* 16-bit unsigned integer with precision mm. */
        case PXCImage::PIXEL_FORMAT_DEPTH_RAW: /* 16-bit unsigned integer with device specific precision (call device->QueryDepthUnit()) */
            cvDataType = CV_16U;
            cvDataWidth = 2;
            break;
        case PXCImage::PIXEL_FORMAT_DEPTH_F32: /* 32-bit float-point with precision mm. */
            cvDataType = CV_32F;
            cvDataWidth = 4;
            break;

        /* STREAM_TYPE_IR */
        case PXCImage::PIXEL_FORMAT_Y16:          /* 16-Bit Gray Image */
            cvDataType = CV_16U;
            cvDataWidth = 2;
            break;
        case PXCImage::PIXEL_FORMAT_Y8_IR_RELATIVE:    /* Relative IR Image */
            cvDataType = CV_8U;
            cvDataWidth = 1;
            break;
        }

    // suppose that no other planes
    if (data.planes[1] != NULL) throw(0); // not implemented
    // suppose that no sub pixel padding needed
    if (data.pitches[0] % cvDataWidth!=0) throw(0); // not implemented

    outImg->create(imgInfo.height, data.pitches[0] / cvDataWidth, cvDataType);

    memcpy(outImg->data, data.planes[0], imgInfo.height*imgInfo.width*cvDataWidth*sizeof(pxcBYTE));

    inImg->ReleaseAccess(&data);
    }

原则上传入pxcimage的指针,再通过case根据原图像类型选择要转化的图像类型是没有问题的,博主尝试过使用这个函数,但总会出现R1060的错误,似乎是指针非法使用。大家可以自行尝试一下,成功的小伙伴麻烦告知一下博主,让博主学习学习。

时间: 2024-08-01 13:45:49

Realsense 提取彩色和深度视频流的相关文章

Deep Learning九之深度学习UFLDL教程:linear decoder_exercise(斯坦福大学深度学习教程)

前言 实验内容:Exercise:Learning color features with Sparse Autoencoders.即:利用线性解码器,从100000张8*8的RGB图像块中提取彩色特征,这些特征会被用于下一节的练习 理论知识:线性解码器和http://www.cnblogs.com/tornadomeet/archive/2013/04/08/3007435.html 实验基础说明: 1.为什么要用线性解码器,而不用前面用过的栈式自编码器等?即:线性解码器的作用? 这一点,Ng

OpenNI2获取华硕XtionProLive深度图和彩色图并用OpenCV显示

使用OpenNI2打开XtionProLive时有个问题,彩色图分辨率无论如何设置始终是320*240,深度图倒是可以设成640*480,而OpenNI1.x是可以获取640*480的彩色图的. 彩色图 配准到彩色图后的深度图 1:1融合图 代码: #include <opencv2/core/core.hpp> #include <opencv2/imgproc/imgproc.hpp> #include <opencv2/highgui/highgui.hpp> #

kinect2.0 基础篇第3篇 用C#在Visual Studio上编写把深度图像转换成彩色图像

本示例实现的功能有:有两个Radiobutton控件  选一个,点击启动按钮, 第一个是将深度图像转换成彩色图像 第二个是将深度图像做一些简单处理(例如太暗的调白一点) 涉及到一点遥感图像处理知识,将深度数据值转换为色调和饱和度 遥感图像处理那块不懂,有兴趣的自己可以研究研究,代码的基于kinect1的教程,慢慢尝试出来的,虽然功能实现了,但是原理还不是很懂 <Window x:Class="EnhancedDepthWPF.MainWindow" xmlns="htt

深度学习之概述(Overview)

2016年被称为人工智能的元年,2017年是人能智能应用的元年:深度学习技术和应用取得飞速发展:深度学习在互联网教育场景也得到广泛应用.本文主要介绍机器学习及深度学习之定义及基本概念.相关网络结构等. 本文主要内容包括机器学习的定义及组成分类.深度学习的定义.深度学习和机器学习的区别.神经网络基本概念及基本结构.深度学习的相关核心概念(基本假设.数据集.表示.泛化.容量.优化.超参数.误差.欠拟合.过拟合.正则化).两种典型深度网络结构(CNN.RNN)基本介绍. 引言 人工智能究竟能够做什么?

Python提取netCDF数据并转换为csv文件

netCDF全称是network Common Data Format(网络通用数据格式),是由美国大学大气研究协会(University Corporation for Atmospheric Research,UCAR)的Unidata项目科学家针对科学数据的特点开发的,是一种面向数组型并适于网络共享的数据的描述和编码标准.目前,NetCDF广泛应用于大气科学.水文.海洋学.环境模拟.地球物理等诸多领域. 我们使用python对数据进行分析处理,首先我们需要下载安装netCDF4包,可使用p

【转】OpenNI2 开发者指南

转自:http://blog.csdn.net/linkageworld/article/details/52621156 本文由官方文档翻译而来 总览 目的 OpenNI 2.0 API(应用程序编程接口)提供了访问PrimerSense的兼容深度传感器.这就使得一个应用程序能够初始化传感器和从设备接收深度(depth),彩图(RGB)和红外(IR)视频流,还提供了一个统一的接口给传感器和通过深度传感器创建.oni记录文件. OpenNI也提供了第三方中间件开发者可以相互使用深度传感器的统一接

三维重建基础

三维重建技术通过深度数据获取.预处理.点云配准与融合.生成表面等过程,把真实场景刻画成符合计算机逻辑表达的数学模型.这种模型可以对如文物保护.游戏开发.建筑设计.临床医学等研究起到辅助的作用. 1.1 研究背景及意义 人类通过双眼来探索与发现世界.人类接收外部信息的方式中,有不到三成来自于听觉.触觉.嗅觉等感受器官,而超过七成.最丰富.最复杂的信息则通过视觉[1]进行感知的.计算机视觉便是一种探索给计算机装备眼睛(摄像头)与大脑(算法)的技术,以使计算机能够自主独立的控制行为.解决问题,同时感知

人脸旋转 《转》

近期接触了一下四元数,目的是要获取人脸朝向,看到这篇文章才发现了一些线索,所以记录一下. ----------------------------------------------------------------------- 更新一下进展: 自从发现了下面的 pitch roll yaw 对照,基本上也算是了解了个大概了. 然后就又发现了下面的文章: 原贴地址:https://www.amobbs.com/thread-5504669-1-1.html 四元数转换成欧拉角,pitch角范

写了个项目 Web-Rtmp: 使用 WebSocket 在网页上播放 RTMP 直播流

http://neue.v2ex.com/t/316766 虽说浏览器里用 js 解码'播放'视频的方案已经有几个了... 为什么不再多一个呢... 基本原理: 服务端使用 websockify 中转一个 rtmp 流. 浏览器中使用 node-rtmpapi 解析 RTMP 协议,完成握手和通信. 提取其中的 H264 视频流 发送给 Broadway 解码 Repo: https://github.com/yingDev/Web-Rtmp 目前只是一个 demo 级别的东西, 算是验证了可行