8

我需要从 Kinnect 相机捕获彩色 RGB 图像,但我想在 OpenCV 中显示它,因为这只是更大程序的一部分。如果你设置了标志,我知道 OpenCV 与 OpenNI 兼容,但是尽管我努力 CMake 找不到 OpenNI2 的路径,所以我无法用 OpenNI 构建 OpenCV。无论如何,我认为知道如何手动将 OpenNI 帧转换为 openCV 帧是件好事,所以我决定采用这种方式。

为了在 OpenNI 中捕获颜色帧,我尝试了以下方法:

openni::Device device;  
openni::VideoStream  color;
openni::VideoFrameRef colorFrame;

rc = openni::OpenNI::initialize();
rc = device.open(openni::ANY_DEVICE);
rc = color.create(device, openni::SENSOR_COLOR);
rc = color.start();

color.readFrame(&colorFrame);
const openni::RGB888Pixel* imageBuffer = (const openni::RGB888Pixel*)colorFrame.getData();

但现在我不明白如何转换为 cv::Mat。

有没有人能做到这一点?

4

2 回答 2

12

好的,首先你应该将初始化与读取帧的循环分开,这样。

初始化

openni::Device device;  
openni::VideoStream  color;
openni::VideoFrameRef colorFrame;

rc = openni::OpenNI::initialize();
rc = device.open(openni::ANY_DEVICE);
rc = color.create(device, openni::SENSOR_COLOR);
rc = color.start();

Mat frame;

现在是阅读框架的主循环。您几乎已经完成了所有工作,唯一剩下的就是将缓冲区复制到 openCV Mat。

循环阅读帧

while (true)
{
   color.readFrame(&colorFrame);
   const openni::RGB888Pixel* imageBuffer = (const openni::RGB888Pixel*)colorFrame.getData();

   frame.create(colorFrame.getHeight(), colorFrame.getWidth(), CV_8UC3);
   memcpy( frame.data, imageBuffer, 3*colorFrame.getHeight()*colorFrame.getWidth()*sizeof(uint8_t) );

   cv::cvtColor(frame,frame,CV_BGR2RGB); //this will put colors right
}
于 2013-04-12T09:03:52.150 回答
1

跟进@Jav_Rock 上面的回答,对于 IR 和 Depth,解决方案是相似的,除了以下内容(分别代替和SENSOR_COLOR):CV_8UC3RGB888Pixel

深度

  • 传感器类型:SENSOR_DEPTH
  • OpenCV 类型:CV_16UC1
  • VideoFrameRef 数据:DepthPixel

请注意,您可能需要将 VideoStream 的 VideoFormat 的 PixelMode 设置为,PIXEL_FORMAT_DEPTH_100_UM否则您的深度图像看起来会很黑。

红外

  • 传感器类型:SENSOR_IR
  • OpenCV 类型:CV_16UC1
  • VideoFrameRef 数据:Grayscale16Pixel

最后,请注意,深度和 IR 都不需要cv::cvtColor调用。

于 2017-03-09T03:25:16.850 回答