使用OpenNI2读取oni格式的文件,并将其中的彩色视频,深度视频显示并保存
来源:互联网 发布:信捷plc编程软件xc,xd 编辑:程序博客网 时间:2024/03/29 06:05
前几天做人体行为识别的师姐在网上下载了一个以.oni格式保存的数据集,师姐让我帮忙将.oni格式的数据读出并保存为图片序列,以便能用OpenCV/matlab进行处理弄了两三天,终于能完整的将oni文件中的视频数据一帧不少的读出来了,现在将我的方法分享一下。
之前没有接触过OpenNI,这次用到OpenNI是从零开始学的,到今天我也只学了不到4天,有错误的地方还请指教。
首先说一下我对OpenNI2的认识,开始也用过OpenNI1.5但是发现太难,结构不如OpenNI2这种C++风格的清晰,因此,在最初接触了OpenNI几个小时后我就果断的选择了使用OpenNI2,而且OpenNI2的配置也相对比较简单,我用的版本是OpenNI-Windows-x86-2.2,系统是Win7+VS2010。(我的配置是按照这个方法进行的)
由于我仅仅用OpenNI2读取oni格式的数据并保存,下面就只谈与之相关的。(其他的我也不懂)
目前能查到的将oni格式文件中的视频流中每一帧视频都读出来的方法有两种:
一、设置循环。首先读取视频流中的总帧数,然后用这个总帧数设置循环次数每一次读取一帧并保存。
二、设置事件。为视频流添加一个事件,每当视频流更新则读取当前帧并保存。
这两种方法我都用过但是都会出现同样的问题,那就是丢帧,即不能按顺序的一帧不落的将所有帧都读出,究其原因可能是我的电脑太慢了,在视频流下一帧更新之前不能将当前帧读取并保存。
几经挣扎我终于找到的能一帧不落的读完所有帧,那就是要在设置循环的方法中设置视频流的速度,将视频流的速度设置为-1,即只有程序在进行读取视频流的时候视频流才更新,其他时间视频流是不动作的。
另外,程序中的图片显示以及保存都是用的OpenCV,关于OpenCV,网上的资料很多我就不做过多的介绍了,如果有需要还可以用OpenCV将oni文件保存为.avi的视频。
下面在程序以及注释中进行详细的解释
#include <iostream>#include <OpenNI.h>#include <opencv2\core\core.hpp>#include <opencv2\imgproc\imgproc.hpp>#include <opencv2\highgui\highgui.hpp>using namespace std;int main(){//定义oni文件中视频的总帧数以及得到的图片的保存目录int total = 0;char* imagefile = "D:\\data\\data1";//初始化OpenNI环境openni::OpenNI::initialize();//声明设备并打开oni文件openni::Device fromonifile;fromonifile.open("D:\\USER28_CAL11\\qw\\S13_C11_U26_D3.oni");//声明控制对象,这对视频流的控制起到了关键作用openni::PlaybackControl* pController = fromonifile.getPlaybackControl();//声明视频流对象以及帧对象openni::VideoStream streamColor;openni::VideoFrameRef frameColor;//验证是否有彩色传感器(是否有彩色视频)和建立与设备想关联的视频流if(fromonifile.hasSensor(openni::SENSOR_COLOR)){if(streamColor.create( fromonifile, openni::SENSOR_COLOR ) == openni::STATUS_OK ){cout<<"建立视频流成功"<<endl;}else{cerr<<"ERROR: 建立视频流没有成功"<<endl;system("pause");return -1;}}else{cerr << "ERROR: 该设备没有彩色传感器" << endl;system("pause");return -1;}//建立显示窗口cv::namedWindow("Image");//获取总的视频帧数并将该设备的速度设为-1以便能留出足够的时间对每一帧进行处理、显示和保存total = pController->getNumberOfFrames(streamColor);pController->setSpeed(-1);//开启视频流streamColor.start();for (int i = 1;i <= total; ++ i){//读取视频流的当前帧streamColor.readFrame(&frameColor);cout<<"当前正在读的帧数是:"<<frameColor.getFrameIndex()<<endl;cout<<"当前的循环次数是: "<<i<<endl;//将帧保存到Mat中并且将其转换到BGR模式,因为在OpenCV中图片的模式是BGRcv::Mat rgbImg(frameColor.getHeight(), frameColor.getWidth(), CV_8UC3, (void*)frameColor.getData());cv::Mat bgrImg;cvtColor(rgbImg, bgrImg, CV_RGB2BGR);//将每一帧按顺序帧保存到图片目录下char imagefullname[255];char imagenum[50];sprintf(imagenum,"\\%03d.png",i);strcpy(imagefullname,imagefile);strcat(imagefullname,imagenum);cv::imwrite(imagefullname,bgrImg);//显示当前帧cv::imshow("Image",bgrImg);if (cv::waitKey(30) == 27){break;}}//销毁显示窗口cv::destroyWindow("Image");//关闭视频流streamColor.destroy();//关闭设备fromonifile.close();//关闭OpenNIopenni::OpenNI::shutdown();return 0;}
程序运行的截图(数据集是从网上下载的,不要在意视频上那个人,我也不认识)
如果想要读深度数据那么将30和32行的SENSOR_COLOR改成SENSOR_DEPTH
当然由于在OpenNI中的深度数据到OpenCV中要用CV_16UC1来保存并且要想较好的显示还需要下面的转换
const cv::Mat mImageDepth( frame.getHeight(), frame.getWidth(), CV_16UC1, (void*)frame.getData());int iMaxDepth = stream.getMaxPixelValue();cv::Mat mScaledDepth;mImageDepth.convertTo( mScaledDepth, CV_8U, 255.0 / iMaxDepth );
以上,就是我的一些经验,不免有疏漏,请多多包含。
参考:
http://www.cnblogs.com/yemeishu/archive/2013/01/11/2856859.html
http://blog.csdn.net/chenxin_130/article/details/8580636
http://www.dotblogs.com.tw/v6610688/archive/2014/03/02/openni_oni_format_file_to_avi_opencv.aspx#feedback
- 使用OpenNI2读取oni格式的文件,并将其中的彩色视频,深度视频显示并保存
- 使用编译好的OPENNI2的动态库与静态库进行Kinect2.0的ONI格式视频流录制
- OPenNI获取并保存彩色、深度视频
- OpenCV将彩色视频转换为灰度视频并保存
- 使用OPENNI2来对Kinect2.0进行.ONI格式视频采集
- 将视频流保存成wmv格式的文件
- 使用JDOM读取XML文件,并输出其中的数据
- win8 metro 调用摄像头录制视频并将视频保存在相应的位置
- 视频的读取,显示和保存
- opencv2读取摄像头并保存为视频
- C间隔帧读取yuv视频序列并将提取出的帧序列组成新的yuv文件
- Qt使用opencv调用摄像头录制视频并保存文件
- Realsense(四)github上一种提取彩色和深度视频流并转为mat的方案
- Python之BeautifulSoup学习之三 读取本地html文件,并将其中图片保存下来
- opencv学习笔记(九)捕获摄像头的视频并保存成avi格式
- OpenCV之读取视频并显示
- opencv读取不同步双目视频并显示
- 使用DirectShow捕获视频,并截图保存
- UXIX V7
- 使用FireBreath写浏览器插件(二)
- cocos2dx 特效 3D特效
- 关于java --DWR
- 关于c++中const的用法详解
- 使用OpenNI2读取oni格式的文件,并将其中的彩色视频,深度视频显示并保存
- Android属性之build.prop,及property_get/property_set
- 利用boost库实现字节间的转换
- IOS学习笔记之十七:Category的简单理解和应用
- 算法 (向量旋转)
- VS web编程中 .aspx .aspx.cs
- java工厂模式
- MySQL 5.6源码编译碰到的一个问题
- <c:if test="value ne, eq, lt, gt,...."> 用法