Intel RealSense学习之图像及图像深度数据获取

来源:互联网 发布:json框架有哪些 编辑:程序博客网 时间:2024/06/05 19:04

本文将介绍如何获取到彩色图像的深度信息。
大家都知道我们可以从realsense 摄像头中获取到RGB数据,红外数据,以及图像的深度数据。至于图像的深度数据我的理解是realsense摄像投抓到的图像的相关距离信息,具体点 可以理解成摄像头距离每个像素点的距离。这个深度数据在某些场景下非常的有意义。本文从之前两篇文章的基础上介绍如何在QT + OpenCV的环境下获取到RGB图像并且拿到深度信息。

主要分以下三个部分
-* RealSense 摄像头操作类的封装*
-* OpenCV Mat与QImage 之间的转换*
-* Realsense 深度数据的获取*

RealSense 摄像头操作类的封装

我们使用一个c++类来封装对librealsense的操作:

#ifndef RSDEVICE_H#define RSDEVICE_H#include <librealsense/rs.hpp>#include <QString>class rsdevice{public:    rs::context ctx;    rs::device * dev;    int devCount;    QString devName;    QString devSerial;    QString devFwVersion;    QString devCamType;    QString devIspFwVersion;    bool streamEnable;public:    QString getDevName(){        return devName;    }    QString getDevSerial(){        return devSerial;    }    QString getDevFwVersion(){        return devFwVersion;    }    QString getCamType(){        return devCamType;    }    QString getIspFwVersion(){        return devIspFwVersion;    }public:    rsdevice();    ~rsdevice();    void initRsDevice();    void enableStream();    uchar * getFrameData();    bool isSteamEnable();    float getDistance(int x,int y);};#endif // RSDEVICE_H

上面一堆获取realsense camera 属性的函数,暂时可以忽略,最主要的是initRsDevice(),enableStream(),getFrameData(),getDistance(),四个函数。

初始化realsense 摄像头

void rsdevice::initRsDevice(){ devCount = ctx.get_device_count(); dev = ctx.get_device(0);..........................................}

开启摄像头数据流,在这里我们只开启两路数据,一路RGB彩色数据,一路深度摄像头数据:

void rsdevice::enableStream(){    streamEnable = true;    dev->enable_stream(rs::stream::color, 640, 480, rs::format::rgb8, 60);    dev->enable_stream(rs::stream::depth,640,480, rs::format::z16, 60);    dev->start();}

获取到RGB彩色数据:

uchar * rsdevice::getFrameData(){    dev->wait_for_frames();    return (uchar *) dev->get_frame_data(rs::stream::color); .................

获取位置的深度距离数据,传入(x,y)点的坐标信息,获取到该点的距离。

float rsdevice::getDistance(int x, int y){    uint16_t *depthImage = (uint16_t *) dev->get_frame_data(rs::stream::depth);    float scale = dev->get_depth_scale();    rs::intrinsics depthIntrin = dev->get_stream_intrinsics(rs::stream::depth);    uint16_t depthValue = depthImage[y * depthIntrin.width + x];    float depthInMeters = depthValue * scale;    return depthInMeters;}

OpenCV Mat与QImage 之间的转换

我们设想的是之后从librealsense中拿到的数据需要通过OpenCV处理一遍,而从上面可得知从摄像头里取得的是uchar* 类型的指针,我们需要先转换成Open CV 中使用的Mat, 而后在QT中显示,需要再转换成QImage。

uchar* —> Mat

      uchar* pRgb = dev->getFrameData();      Mat rgb_show;      Mat rgb(480, 640, CV_8UC3, pRgb);

Mat —> QImage

由于Mat 默认是BGR,需要先转成RGB

 cvtColor(rgb, rgb_show, CV_BGR2RGB); QImage img = QImage((const unsigned char *)(image.data), image.cols, image.rows,                image.cols*image.channels(), QImage::Format_RGB888);

每次QT绘制消息过来的时候,从realsense中取一帧,做相应的转换,转成QImage对象,再刷出去。

Realsense 深度数据的获取

从前面,我们已经拿到了RGB数据,并且显示出去了,现在我们需要去尝试拿到图像上的某一个点的深度信息。

转换坐标

QT中重写mousePressEvent函数,并且将坐标信息映射到图像当中:

void MainWindow::mousePressEvent(QMouseEvent *e){    QPoint p = e->globalPos();    p = picLabel->mapFromGlobal(p);    int depth = dev->getDistance(p.x(),p.y());    if(disInfoLabel != NULL){        QString strLocation;        strLocation.sprintf("The distance is %d",depth);        disInfoLabel->setText(strLocation);        disInfoLabel->move(e->x(),e->y());        disInfoLabel->setFixedWidth(400);        disInfoLabel->show();    }}

从realsense摄像头中计算出该像素点的距离信息:

float rsdevice::getDistance(int x, int y){    uint16_t *depthImage = (uint16_t *) dev->get_frame_data(rs::stream::depth);    float scale = dev->get_depth_scale();    rs::intrinsics depthIntrin = dev->get_stream_intrinsics(rs::stream::depth);    uint16_t depthValue = depthImage[y * depthIntrin.width + x];    float depthInMeters = depthValue * scale;    return depthInMeters;}

Demo 跑起来效果如下,不过貌似R200的深度信息是以米为最小单位,这个精度上会有点问题啊,还需要再确认下。

DEMO

0 0
原创粉丝点击