OpenNI2下简单操作两个体感设备(Xtion与Kinect for Xbox 360)
主要内容:
- 设备与驱动准备
- 代码演示
- 总结
一、设备与驱动准备
最近忙着写论文,已好长时间没瞎写了,这两天偶然看到一篇有关OpenNI2操作两个体感设备的文章,自己复制粘贴运行下看了效果挺好的,所以我大胆的搬过来,和大家分享分享~~~
设备准备:一个ASUS Xtion;一个Kinect for Xbox360;
驱动准备:我是win7下运行的,只要在设备管理器中显示如下效果,就没问题;要是有出现一个显示黄的,那就表示其中有一个显示不了,我目前的做法是:反复拔了再插,插了再拔,直到显示如下效果就OK;
二、代码演示
在之前都是用到一个体感设备进行开发,但也有人拿两个把玩着,所以如何同时让两个都运行起来?
在OpenNI2中提供了一个OpenNI::enumerateDevices函数原型是这样的:
/**Fills up an array of @ref DeviceInfo objects with devices that are available.@param [in,out] deviceInfoList An array to be filled with devices.*/static void enumerateDevices(Array<DeviceInfo>* deviceInfoList){OniDeviceInfo* m_pDeviceInfos;int m_deviceInfoCount;oniGetDeviceList(&m_pDeviceInfos, &m_deviceInfoCount);deviceInfoList->_setData((DeviceInfo*)m_pDeviceInfos, m_deviceInfoCount, true);oniReleaseDeviceList(m_pDeviceInfos);}
英语学的不好,大概的意思是将可使用的divices设备信息保存到Array<DeviceInfo>* deviceInfoList中吧~通过看oniGetDeviceList函数:
/*** Get the list of currently connected device.* Each device is represented by its OniDeviceInfo.* pDevices will be allocated inside.*/ ONI_C_API OniStatus oniGetDeviceList(OniDeviceInfo** pDevices, int* pNumDevices);
通过Array<DeviceInfo>* deviceInfoList,我们就可以得到DeviceInfo信息操作Device了,其中DeviceInfo包括设备Uri,供应商名,供应商ID,设备Id,设备名:
class DeviceInfo : private OniDeviceInfo { public:/** Returns the device URI. URI can be used by @ref Device::open to open a specific device. The URI string format is determined by the driver.*/const char* getUri() const { return uri; }/** Returns a the vendor name for this device. */const char* getVendor() const { return vendor; }/** Returns the device name for this device. */const char* getName() const { return name; }/** Returns the USB VID code for this device. */uint16_t getUsbVendorId() const { return usbVendorId; }/** Returns the USB PID code for this device. */uint16_t getUsbProductId() const { return usbProductId; }friend class Device;friend class OpenNI; };
有了这些信息就可以看目前连接的设备的信息了,看代码:
int main( int argc, char **argv ) { // 初始化OpenNI OpenNI::initialize();// 获取设备信息 Array<DeviceInfo> aDeviceList; OpenNI::enumerateDevices( &aDeviceList ); // output information //vector<CDevice> vDevices; cout << "电脑上连接着 " << aDeviceList.getSize() << " 个体感设备." << endl; for( int i = 0; i < aDeviceList.getSize(); ++ i ) { cout << "设备 " << i << endl; const DeviceInfo& rDevInfo = aDeviceList[i]; cout << "设备名: " << rDevInfo.getName() << endl;cout << "设备Id: " << rDevInfo.getUsbProductId() << endl;cout << "供应商名: "<< rDevInfo.getVendor() << endl; cout << "供应商Id: " << rDevInfo.getUsbVendorId() << endl; cout << "设备URI: " << rDevInfo.getUri() << endl; }system("pause"); // 编译运行之后可以 OpenNI::shutdown(); return 0; }
显示效果:
接着在获取Kinect和Xtion信息之后,就可以驱动他们运行了,通过设备Uri驱动,估计大家都懂了,然后获得它们各自的深度信息流数据,再利用OpenCV进行处理,直接上代码:
// MoreDevice.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h"// 标准库头文件 #include <iostream> #include <string> #include <vector> // OpenCV头文件 #include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> // OpenNI头文件 #include <OpenNI.h> // namespace using namespace std; using namespace openni;class CDevice{ public: const char* devicename; Device* pDevice; VideoStream* pDepthStream; CDevice( int idx, const char* uri, const char* deviceName) { devicename = deviceName;// 创建DevicepDevice = new Device(); // 打开指定Uri设备pDevice->open( uri ); // 创建深度数据量pDepthStream = new VideoStream(); pDepthStream->create( *pDevice, SENSOR_DEPTH ); // 创建OpenCV窗口 cv::namedWindow( deviceName, CV_WINDOW_AUTOSIZE );// 开始 pDepthStream->start(); } }; int main( int argc, char **argv ) { // 初始化OpenNI OpenNI::initialize();// 获取设备信息 Array<DeviceInfo> aDeviceList; OpenNI::enumerateDevices( &aDeviceList ); // 将每个设备信息用CDevice类封装 vector<CDevice> vDevices;cout << "电脑上连接着 " << aDeviceList.getSize() << " 个体感设备." << endl; for( int i = 0; i < aDeviceList.getSize(); ++ i ) { cout << "设备 " << i << endl; const DeviceInfo& rDevInfo = aDeviceList[i]; cout << "设备名: " << rDevInfo.getName() << endl;cout << "设备Id: " << rDevInfo.getUsbProductId() << endl;cout << "供应商名: "<< rDevInfo.getVendor() << endl; cout << "供应商Id: " << rDevInfo.getUsbVendorId() << endl; cout << "设备URI: " << rDevInfo.getUri() << endl; // 封装类初始化,传入设备名和设备Uri CDevice mDev(i, aDeviceList[i].getUri(), aDeviceList[i].getName()); vDevices.push_back( mDev ); } while( true ) { for( vector<CDevice>::iterator itDev = vDevices.begin(); itDev != vDevices.end(); ++ itDev ) { // 获取深度图像帧 VideoFrameRef vfFrame; itDev->pDepthStream->readFrame( &vfFrame ); // 转换成 OpenCV 格式 const cv::Mat mImageDepth( vfFrame.getHeight(), vfFrame.getWidth(), CV_16UC1, const_cast<void*>( vfFrame.getData() ) ); // 从 [0,Max] 转为 [0,255] cv::Mat mScaledDepth; mImageDepth.convertTo( mScaledDepth, CV_8U, 255.0 / itDev->pDepthStream->getMaxPixelValue() ); // 显示图像 cv::imshow( itDev->devicename, mScaledDepth ); vfFrame.release(); } // 退出键 if( cv::waitKey( 1 ) == 'q' ) break; } // 停止时的操作 for( vector<CDevice>::iterator itDev = vDevices.begin(); itDev != vDevices.end(); ++ itDev ) { itDev->pDepthStream->stop(); itDev->pDepthStream->destroy(); delete itDev->pDepthStream; itDev->pDevice->close(); delete itDev->pDevice; } OpenNI::shutdown();return 0; }
显示效果:
三、总结
代码挺简单的,我自己碰到的问题主要是xtion和kinect驱动共存的问题,剩下的就好解决了。最后说明的是:根据自己的感觉写代码,没做封装、优化、重构,完全是面向过程,而且肯定还存在细节的问题,会在后面进一步优化的。 写的粗糙,欢迎指正批评~~~
转载于:https://www.cnblogs.com/yemeishu/archive/2013/03/13/2957403.html
OpenNI2下简单操作两个体感设备(Xtion与Kinect for Xbox 360)相关推荐
- VIM - 01. 标准模式 - 下简单操作
1. 概述 标准模式下, 简单操作 移动 删除 复制粘贴 收益 熟练后, 编辑文本基本不需要鼠标操作了 思路 只讲最基本的, 避免初学时的混淆 把基本操作归类了, 方便理解 2. 准备 一篇篇幅较长的 ...
- Microsoft XBOX 360 Project Natal 体感装置2010年6月15正式发布产品正式命名为“Kinect”
在微软E3新闻发布会召开前,今日美国(USA Today)率先报道了微软XBOX 360 之前研发的Project Natal体感装置的正式名称为"Kinect.微软曾在今年4月26日曾经成 ...
- Microsoft XBOX 360 Project Natal 体感装置2010年6月15正式发布产品正式命名为“Kinect”...
在微软E3新闻发布会召开前,今日美国(USA Today)率先报道了微软XBOX 360 之前研发的Project Natal体感装置的正式名称为"Kinect.微软曾在今年4月26日曾经成 ...
- 【论文复现】SimCSE对比学习: 文本增广是什么牛马,我只需要简单Dropout两下
文本增广是什么牛马,我只需要简单Dropout两下 Sentence Embeddings与对比学习 SimCSE 无监督Dropout 有监督对比学习 如何评判Sentence Embeddings ...
- mysql 密码长度约束_MySQL简单操作【1、在cmd下MySQL的运行及简单增删改查】
上篇文章介绍了在Windows10下安装MySQL,本篇文章介绍cmd下简单的操作. 1.登录 MySQL 当 MySQL 服务已经运行时, 我们可以通过 MySQL 自带的客户端工具登录到 MySQ ...
- Linux下简单的邮件服务器搭建
Linux下简单的邮件服务器搭建 电子邮件服务简介 电子邮件是因特网上最为流行的应用之一,而邮件服务器是一种用来负责电子邮件收发管理的设备,它构成了电子邮件系统的核心. 电子邮件系统的组成 MUA( ...
- 28335接两个spi设备_IIC和SPI如此流行,谁才是嵌入式工程师的必备工具?
IICvs SPI 现今,在低端数字通信应用领域,我们随处可见 IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身 ...
- Linux下如何挂载FAT32格式USB设备
From: http://hi.baidu.com/enovo/blog/item/c901eb249c0783064c088db3.html 挂u盘之前,运行命令cat /proc/partitio ...
- 高通平台中gpio简单操作和调试
做底层驱动免不了gpio打交道,所以对其操作和调试进行了一下简单的梳理 一.gpio的调试方法 在Linux下,通过sysfs,获取gpio状态,也可以操作gpio. 1.获取gpio状态 cd /s ...
最新文章
- python 语言教程(2)基础语法之标识符
- Mybatis的insert方法
- 蓝牙小电池图标_丽声小百科 | 乐趣助听器如何连接iPhone手机?
- LeetCode SQL 196. 删除重复的电子邮箱
- django 1.8 官方文档翻译:6-5-1 Django中的测试
- Shell脚本批量清除Nginx缓存
- python元组可以修改吗_python元组元素可以修改吗
- MySQL查看binlog是否开启(开启binlog)
- 三菱5uplc伺服电机指令_PLC中伺服控制指令的应用
- Bolt界面引擎元对象(UIObject)的动态创建
- HTML:网页设计案例3
- 论文翻译 | R-CNN论文:《Rich feature hierarchies for accurate object detection and semantic segmentation》
- -XX:NewRatio 命令
- 关于三角函数级数的一个重要结论+和差化积+积化和差
- 通过电话拨号上网的家用计算机,拨号上网需计算机、电话线、帐号和()
- 慕课网风袖小程序 一一第一阶段
- Java小白常见异常|ArithmeticException算数异常的解决过程
- java专区软件_分享几款让你事半功倍的装机必备软件
- 37岁主管被裁,无奈降薪去小公司遭群嘲:许多人早就破产了,只是活在还没倒闭的公司里!...
- 正版office 2007 简体中文专业版(附正版序列号)高速下载正版office 2007 简体中文专业版...