本程序用於生成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;
}