本程序用于生成oni文件,oni文件是openni录制的用于保存支持openni驱动的设备实时录制的数据,比如RGBD数据的数据集文件。
相关参考代码如下:
OpenNI/OpenNI
main.cpp
#include <iostream>
#include <string>
#include "XnCppWrapper.h"
#include "XnOpenNI.h"
#include "opencv2/opencv.hpp"
using namespace std;
using namespace xn;
vector<vector<string>> readSpaceSeparatedText(string filepath){
//打开文件
std::cout<<"开始读入文件..."<<std::endl;
ifstream file(filepath);
if (!file) {
cerr << "fail to open file" << endl;
exit(1);
}
vector<vector<string>> file_content; //存储每个数据的数据结构
string file_line;
while (std::getline(file, file_line)) { //读取每一行数据
vector<string> file_content_line; //存储分割之后每一行的四个数据
stringstream ss; //利用内存流进行每行数据分割
string each_elem;
ss << file_line;
while (ss >> each_elem) {
file_content_line.push_back(each_elem);
}
file_content.emplace_back(file_content_line); //数据组装
};
return file_content;
}
int CheckError(XnStatus nRetVal,char* what){
if(nRetVal != XN_STATUS_OK){
printf("%s failed: %s \n",what,xnGetStatusString(nRetVal));
return 1;
exit(-1);
}
return 0;
}
//#define CHECK_RC(rc,what)
// if (rc != XN_STATUS_ok){
// printf("%s failed:\n",what xnGetStatusString(rc));
// return rc;
// }
int main() {
vector<vector<string>> associations=readSpaceSeparatedText("/home/atom/RobotProjects/dyson_dataset/association.txt");
XnStatus eResult = XN_STATUS_OK; //标示模块工作状态的属性值
//创建context上下文对象
xn::Context mContext;
eResult = mContext.Init();
CheckError(eResult,"Init");
//创建player
Player player; //创建player
eResult = mContext.OpenFileRecording("/media/atom/0B8B-0DB4/usher.oni", player); // we use existence .oni file to simulate a oni context environment.
CheckError(eResult, "Open input file");
//find existing node
DepthGenerator depth;
ImageGenerator color;
eResult = mContext.FindExistingNode(XN_NODE_TYPE_IMAGE, color);
CheckError(eResult, "Find color generator");
eResult = mContext.FindExistingNode(XN_NODE_TYPE_DEPTH, depth);
CheckError(eResult, "Find depth generator");
//create Map generator mode
XnMapOutputMode mapMode;
mapMode.nXRes = 640;
mapMode.nYRes = 480;
mapMode.nFPS = 30;
// DepthGenerator mDepthGenerator;
// eResult=mDepthGenerator.Create(mContext);
// CheckError(eResult,"depth generator");
// cout<<"nihao2"<<endl;
// eResult = mContext.FindExistingNode(XN_NODE_TYPE_DEPTH, mDepthGenerator);
// CheckError(eResult,"find existing depth node");
// cout<<"nihao2.5"<<endl;
// eResult=mDepthGenerator.SetMapOutputMode(mapMode);
// cout<<"Nihao3"<<endl;
// CheckError(eResult,"set depth generator mode");
//
// ImageGenerator mImageGenerator;
// eResult=mImageGenerator.Create(mContext);
// CheckError(eResult,"rgb generator");
// eResult=mImageGenerator.SetMapOutputMode(mapMode);
// CheckError(eResult,"set rgb generator mode");
MockDepthGenerator mDepthGenerator;
// eResult=mDepthGenerator.Create(mContext);
CheckError(eResult,"mock depth generator");
eResult=mDepthGenerator.CreateBasedOn(depth);
eResult=mDepthGenerator.SetMapOutputMode(mapMode);
CheckError(eResult,"set depth generator mode");
MockImageGenerator mImageGenerator;
// eResult=mImageGenerator.Create(mContext);
eResult=mImageGenerator.CreateBasedOn(color);
CheckError(eResult,"mock rgb generator");
eResult=mImageGenerator.SetMapOutputMode(mapMode);
CheckError(eResult,"set rgb generator mode");
//创建recorder
xn::Recorder mRecorder;
mRecorder.Create(mContext);
mRecorder.SetDestination(XN_RECORD_MEDIUM_FILE,"sample.oni");
//
//add node to recording
eResult = mRecorder.AddNodeToRecording(mDepthGenerator); //向recorder节点添加监听节点
CheckError(eResult, "Add node to recording");
eResult = mRecorder.AddNodeToRecording(mImageGenerator);
CheckError(eResult, "Add node to recording");
// int frame_num=associations.size();
int frame_num=2;
for (int i = 0; i < frame_num;++i) {
cv::Mat depth_img = cv::imread(associations[i][3], CV_LOAD_IMAGE_UNCHANGED);
// depth_img.convertTo(depth_img, CV_16U); //读入depth成为depth_img
// cout<<depth_img.type()<<endl;
cv::Mat color_img = cv::imread(associations[i][1], CV_LOAD_IMAGE_UNCHANGED);
// color_img.convertTo(color_img, CV_8UC3); //读入rgb成为color_img
// cout<<color_img.type()<<endl;
int64_t ts=stol(associations[i][0]);
// cout<<ts<<endl;
//depth
DepthMetaData depthMD; //创建depth元数据
XnUInt32& di = depthMD.FrameID(); //创建一个FrameID的引用
di = i; // set frame id.
XnUInt64& dt = depthMD.Timestamp(); //创建一个Timestamp的引用
dt = ts; // set a proper timestamp.
depthMD.AllocateData(depth_img.cols, depth_img.rows);
DepthMap& depthMap = depthMD.WritableDepthMap();
for (XnUInt32 y = 0; y < depthMap.YRes(); y++)
{
for (XnUInt32 x = 0; x < depthMap.XRes(); x++)
{
depthMap(x, y) = depth_img.at<ushort>(y, x);
}
}
eResult = mDepthGenerator.SetData(depthMD);
CheckError(eResult, "Set mock node new data");
//color
ImageMetaData colorMD;
XnUInt32& ci = colorMD.FrameID();
ci = i;
XnUInt64& ct = colorMD.Timestamp();
ct = ts;
colorMD.AllocateData(color_img.cols, color_img.rows, XN_PIXEL_FORMAT_RGB24);
RGB24Map& imageMap = colorMD.WritableRGB24Map();
for (XnUInt32 y = 0; y < imageMap.YRes(); y++)
{
for (XnUInt32 x = 0; x < imageMap.XRes(); x++)
{
cv::Vec3b intensity = color_img.at<cv::Vec3b>(y, x);
imageMap(x, y).nBlue = (XnUInt8)intensity.val[0];
imageMap(x, y).nGreen = (XnUInt8)intensity.val[1];
imageMap(x, y).nRed = (XnUInt8)intensity.val[2];
}
}
eResult = mImageGenerator.SetData(colorMD);
CheckError(eResult, "Set mock node new data");
mRecorder.Record();
printf("Recorded: frame %u out of %u\r\n", depthMD.FrameID(), frame_num);
}
std::cout << "Hello, World!" << std::endl;
return 0;
}