本文共 4358 字,大约阅读时间需要 14 分钟。
之前一直不知道如何实时保存RGB-D数据,每次都写入PCD文件不现实,对于30fps的,每秒就有30个PCD文件,硬盘速度绝不可能跟得上。保存color和depth视频也总觉得不太方便,而且depth压缩与解压缩会有精度损失。
后来老外提醒我一个简单的方法:使用OpenNI2中的NiViewer,按下s键即可记录oni文件。觉得很方便,于是参考《OpenNI Cookbook》开始编写代码。
通过代码可以生成包含RGB-D信息的ONI文件。以下是一个示例:
#include#include using namespace openni;char ReadLastCharOfLine() { int newChar = 0; int lastChar; fflush(stdout); do { lastChar = newChar; newChar = getchar(); } while ((newChar != '\n') && (newChar != EOF)); return (char)lastChar;}bool HandleStatus(Status status) { if (status == STATUS_OK) { return true; } printf("ERROR: #%d, %s", status, OpenNI::getExtendedError()); ReadLastCharOfLine(); return false;}int main() { Status status = STATUS_OK; printf("Scanning machine for devices and loading modules/drivers ...\r\n"); status = OpenNI::initialize(); if (!HandleStatus(status)) { return 1; } printf("Completed.\r\n"); Device device; printf("Opening first device ...\r\n"); status = device.open(ANY_DEVICE); if (!HandleStatus(status)) { return 1; } printf("%s Opened, Completed.\r\n", device.getDeviceInfo().getName()); printf("Checking if stream is supported ...\r\n"); if (!device.hasSensor(SENSOR_DEPTH)) { printf("Stream not supported by this device.\r\n"); return 1; } printf("Asking device to create a depth stream ...\r\n"); VideoStream depthSensor; VideoStream colorSensor; status = depthSensor.create(device, SENSOR_DEPTH); if (!HandleStatus(status)) { return 1; } status = colorSensor.create(device, SENSOR_COLOR); if (!HandleStatus(status)) { return 1; } printf("Starting stream ...\r\n"); status = depthSensor.start(); if (!HandleStatus(status)) { return 1; } status = colorSensor.start(); if (!HandleStatus(status)) { return 1; } printf("Done.\r\n"); printf("Creating a recorder ...\r\n"); Recorder recorder; status = recorder.create("sample.oni"); if (!HandleStatus(status)) { return 1; } printf("Done.\r\n"); printf("Attaching to depth sensor ...\r\n"); status = recorder.attach(depthSensor); if (!HandleStatus(status)) { return 1; } status = recorder.attach(colorSensor); if (!HandleStatus(status)) { return 1; } printf("Done.\r\n"); printf("Starting recorder ...\r\n"); status = recorder.start(); if (!HandleStatus(status)) { return 1; } printf("Done. Now recording ...\r\n"); ReadLastCharOfLine(); recorder.destroy(); depthSensor.destroy(); colorSensor.destroy(); device.close(); OpenNI::shutdown(); return 0;}
以下是读取ONI文件并保存为PNG文件的代码:
#include#include #include #include using namespace std;int main() { // 定义oni文件中视频的总帧数以及得到的图片的保存目录 int total = 0; char* imagefile = "/home/jst/Data"; // 初始化OpenNI环境 openni::OpenNI::initialize(); // 声明设备并打开oni文件 openni::Device fromonifile; fromonifile.open("sample.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; 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; } return 0;}
读者留言:
这个解决方案真的很好用,尤其是使用OpenNI工具来直接记录RGB-D数据,避免了PCD文件的频繁写入问题。
转载地址:http://dasfk.baihongyu.com/