opencv 调用openni图像-xtion

Opencv 调用Openni图像-Xtion

本例是使用opencv函数调用openni的图像。
通常在使用xtion或kinect时总是只在openni下使用,为
了能在opencv环境下使用xtion搜索了相关资源,通过
实验,总结如下(在ubuntu14.04,qt下):
方案一:
OpenNI 2与OpenCV结合的第一个程序
开始之前,让我们自己开始再熟练熟练OpenNI 2的基本使用,主要包括以下几个步骤:
1. 初始化OpenNI环境: openni::OpenNI::initialize();
2. 声明并打开Device设备: openni::Device devAnyDevice; devAnyDevice.open( openni::ANY_DEVICE );
3. 创建并打开深度数据流:openni::VideoStream streamDepth; streamDepth.create( devAnyDevice, openni::SENSOR_DEPTH ); streamDepth.start();
4. 读取数据流信息并保存在VideoFrameRef中:openni::VideoFrameRef frameDepth;streamDepth.readFrame( &frameDepth );
5. 获取深度(或颜色等)数据,开始我们自己的开发之旅: const openni::DepthPixel* pDepth = (const openni::DepthPixel*)frameDepth.getData();
6. 当结束使用数据时,首先关闭、销毁数据流:streamDepth.destroy();
7. 接着关闭设备: devAnyDevice.close();
8. 最后关闭OpenNI: openni::OpenNI::shutdown();

#include <iostream>
#include "OpenNI.h"

int main( int argc, char** argv )
{
    // 初始化OpenNI环境
    openni::OpenNI::initialize();

    // 声明并打开Device设备,我用的是Kinect。
    openni::Device devAnyDevice;
    devAnyDevice.open( openni::ANY_DEVICE );

    // 创建并打开深度数据流
    openni::VideoStream streamDepth;
    streamDepth.create( devAnyDevice, openni::SENSOR_DEPTH );
    streamDepth.start();

    // 同样的创建并打开彩色图像数据流
    openni::VideoStream streamColor;
    streamColor.create( devAnyDevice, openni::SENSOR_COLOR );
    streamColor.start();

    // 循环读取数据流信息并保存在VideoFrameRef中
    openni::VideoFrameRef frameDepth;
    openni::VideoFrameRef frameColor;
    for( int i = 0; i < 1000; ++ i )
    {
        // 读取数据流
        streamDepth.readFrame( &frameDepth );
        streamColor.readFrame( &frameColor );

        // 获取data array
        const openni::DepthPixel* pDepth
            = (const openni::DepthPixel*)frameDepth.getData();
        const openni::RGB888Pixel* pColor
            = (const openni::RGB888Pixel*)frameColor.getData();

        // 显示深度信息和对应的彩色R、G、B数值
        int idx = frameDepth.getWidth() * ( frameDepth.getHeight() + 1 ) / 2;
        std::cout  << pDepth[idx]  << "( "
            << (int)pColor[idx].r << ","
            << (int)pColor[idx].g << ","
            << (int)pColor[idx].b << ")"
            << std::endl;
    }

    // 关闭数据流
    streamDepth.destroy();
    streamColor.destroy();

    // 关闭设备
    devAnyDevice.close();

    // 最后关闭OpenNI
    openni::OpenNI::shutdown();

    return 0;
}

案列:利用OpenCV函数显示深度图像和彩色图像。直接上代码:

#include "stdafx.h"
#include <iostream>
#include "OpenNI.h"

// 载入OpenCV头文件
#include "opencv2/opencv.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace openni;
using namespace cv;

int main( int argc, char** argv )
{
    // 初始化OpenNI环境
    OpenNI::initialize();

    // 声明并打开Device设备,我用的是Kinect。
    Device devAnyDevice;
    devAnyDevice.open(ANY_DEVICE );

    // 创建深度数据流
    VideoStream streamDepth;
    streamDepth.create( devAnyDevice, SENSOR_DEPTH );

    // 创建彩色图像数据流
    VideoStream streamColor;
    streamColor.create( devAnyDevice, SENSOR_COLOR );

    // 设置深度图像视频模式
    VideoMode mModeDepth;
    // 分辨率大小
    mModeDepth.setResolution( 640, 480 );
    // 每秒30帧
    mModeDepth.setFps( 30 );
    // 像素格式
    mModeDepth.setPixelFormat( PIXEL_FORMAT_DEPTH_1_MM );

    streamDepth.setVideoMode( mModeDepth);

    // 同样的设置彩色图像视频模式
    VideoMode mModeColor;
    mModeColor.setResolution( 640, 480 );
    mModeColor.setFps( 30 );
    mModeColor.setPixelFormat( PIXEL_FORMAT_RGB888 );

    streamColor.setVideoMode( mModeColor);

    // 图像模式注册
    if( devAnyDevice.isImageRegistrationModeSupported(
        IMAGE_REGISTRATION_DEPTH_TO_COLOR ) )
    {
        devAnyDevice.setImageRegistrationMode( IMAGE_REGISTRATION_DEPTH_TO_COLOR );
    }

    // 打开深度和图像数据流
    streamDepth.start();
    streamColor.start();

    // 创建OpenCV图像窗口
    namedWindow( "Depth Image",  CV_WINDOW_AUTOSIZE );
    namedWindow( "Color Image",  CV_WINDOW_AUTOSIZE );

    // 获得最大深度值
    int iMaxDepth = streamDepth.getMaxPixelValue();

    // 循环读取数据流信息并保存在VideoFrameRef中
    VideoFrameRef  frameDepth;
    VideoFrameRef  frameColor;

    while( true )
    {
        // 读取数据流
        streamDepth.readFrame( &frameDepth );
        streamColor.readFrame( &frameColor );


        // 将深度数据转换成OpenCV格式
        const cv::Mat mImageDepth( frameDepth.getHeight(), frameDepth.getWidth(), CV_16UC1, (void*)frameDepth.getData());
        // 为了让深度图像显示的更加明显一些,将CV_16UC1 ==> CV_8U格式
        cv::Mat mScaledDepth;
        mImageDepth.convertTo( mScaledDepth, CV_8U, 255.0 / iMaxDepth );
        // 显示出深度图像
        cv::imshow( "Depth Image", mScaledDepth );

        // 同样的将彩色图像数据转化成OpenCV格式
        const cv::Mat mImageRGB(frameColor.getHeight(), frameColor.getWidth(), CV_8UC3, (void*)frameColor.getData());
        // 首先将RGB格式转换为BGR格式
        cv::Mat cImageBGR;
        cv::cvtColor( mImageRGB, cImageBGR, CV_RGB2BGR );
        // 然后显示彩色图像
        cv::imshow( "Color Image", cImageBGR );

        // 终止快捷键
        if( cv::waitKey(1) == 'q')
            break;
    }

    // 关闭数据流
    streamDepth.destroy();
    streamColor.destroy();

    // 关闭设备
    devAnyDevice.close();

    // 最后关闭OpenNI
    openni::OpenNI::shutdown();

    return 0;
}

注:在做此实验中,由于自身opencv和openni2的环境部署问题,出现一系列包导入路径问题:

INCLUDEPATH += /usr/include\
                       /usr/include/opencv\
                      /usr/include/opencv2\
                       /usr/include/openni2\#需加

LIBS += /usr/lib/x86_64-linux-gnu/libopencv_highgui.so.2.4\
              /usr/lib/x86_64-linux-gnu/libopencv_core.so \
              /usr/lib/x86_64-linux-gnu/libopencv_imgproc.so\
              /usr/lib/x86_64-linux-gnu/libopencv_video.so\
             /usr/lib/x86_64-linux-gnu/libopencv_objdetect.so\
            /usr/lib/libOpenNI2.so#需加

方案二:此处不在解释,直接上代码,ps:由于用到openni1中的函数,实验没有完成:
OpenNI获取的图像结合OpenCV显示
copenni.cpp:

#include <XnCppWrapper.h>
#include <QtGui/QtGui>
#include <iostream>

using namespace xn;
using namespace std;

class COpenNI
{
public:
    ~COpenNI() {
        context.Release();//释放空间
    }
    bool Initial() {
        //初始化
        status = context.Init();
        if(CheckError("Context initial failed!")) {
            return false;
        }
        context.SetGlobalMirror(true);//设置镜像
        //产生图片node
        status = image_generator.Create(context);
        if(CheckError("Create image generator  error!")) {
            return false;
        }
        //产生深度node
        status = depth_generator.Create(context);
        if(CheckError("Create depth generator  error!")) {
            return false;
        }
        //视角校正
        status = depth_generator.GetAlternativeViewPointCap().SetViewPoint(image_generator);
        if(CheckError("Can't set the alternative view point on depth generator")) {
            return false;
        }

        return true;

    }

    bool Start() {
        status = context.StartGeneratingAll();
        if(CheckError("Start generating error!")) {
            return false;
        }
        return true;
    }

    bool UpdateData() {
        status = context.WaitNoneUpdateAll();
        if(CheckError("Update date error!")) {
            return false;
        }
        //获取数据
        image_generator.GetMetaData(image_metadata);
        depth_generator.GetMetaData(depth_metadata);

        return true;
    }

public:
    DepthMetaData depth_metadata;
    ImageMetaData image_metadata;

private:
    //该函数返回真代表出现了错误,返回假代表正确
    bool CheckError(const char* error) {
        if(status != XN_STATUS_OK ) {
            QMessageBox::critical(NULL, error, xnGetStatusString(status));
            cerr << error << ": " << xnGetStatusString( status ) << endl;
            return true;
        }
        return false;
    }

private:
    XnStatus    status;
    Context     context;
    DepthGenerator  depth_generator;
    ImageGenerator  image_generator;
};

main.cpp:

#include <QCoreApplication>

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <opencv2/core/core.hpp>
#include "copenni.cpp"

#include <iostream>

using namespace cv;
using namespace xn;

int main (int argc, char **argv)
{
    COpenNI openni;
    if(!openni.Initial())
        return 1;

    namedWindow("color image", CV_WINDOW_AUTOSIZE);
    namedWindow("color edge detect", CV_WINDOW_AUTOSIZE);
    namedWindow("depth image", CV_WINDOW_AUTOSIZE);
    namedWindow("depth edge detect", CV_WINDOW_AUTOSIZE);

    if(!openni.Start())
        return 1;
    while(1) {
        if(!openni.UpdateData()) {
            return 1;
        }
        /*获取并显示色彩图像*/
        Mat color_image_src(openni.image_metadata.YRes(), openni.image_metadata.XRes(),
                            CV_8UC3, (char *)openni.image_metadata.Data());
        Mat color_image;
        cvtColor(color_image_src, color_image, CV_RGB2BGR);
        imshow("color image", color_image);

        /*对色彩图像进行canny边缘检测并显示*/
        Mat color_image_gray, color_image_edge;
        cvtColor(color_image_src, color_image_gray, CV_RGB2GRAY);//因为在进行边缘检测的时候只能使用灰度图像
        Canny(color_image_gray, color_image_edge, 5, 100);
        imshow("color edge detect", color_image_edge);

        /*获取并显示深度图像*/
        Mat depth_image_src(openni.depth_metadata.YRes(), openni.depth_metadata.XRes(),
                            CV_16UC1, (char *)openni.depth_metadata.Data());//因为kinect获取到的深度图像实际上是无符号的16位数据
        Mat depth_image, depth_image_edge;
        depth_image_src.convertTo(depth_image, CV_8U, 255.0/8000);
        imshow("depth image", depth_image);

        /*计算深度图像的canny边缘并显示*/
        Canny(depth_image, depth_image_edge, 5, 100);
        imshow("depth edge detect", depth_image_edge);
        waitKey(30);

    }

}

参考:
Kinect+OpenNI学习笔记之4(OpenNI获取的图像结合OpenCV显示)
OpenNI 2与OpenCV结合的第一个程序
使用opencv显示openni获取的图像
Kinect开发教程二:OpenNI读取深度图像与彩色图像并显示

附录:openni库
OpenNI

  • 0
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 要使用ORB-GMS匹配算法,您需要先下载并安装ORB-GMS匹配算法的相关代码库,然后在OpenCV调用相关的头文件。以下是使用OpenCV调用ORB-GMS匹配算法的头文件示例: ```cpp #include <opencv2/core.hpp> #include <opencv2/highgui.hpp> #include <opencv2/features2d.hpp> #include <opencv2/xfeatures2d.hpp> #include <opencv2/calib3d.hpp> #include "ORBextractor.h" #include "GMSMatcher.h" using namespace cv; using namespace std; using namespace ORB_SLAM2; int main(int argc, char** argv) { // 读取图像 Mat img1 = imread("img1.jpg"); Mat img2 = imread("img2.jpg"); // 提取特征点和特征描述符 ORBextractor orb(500, 1.2, 8, 20, 7); vector<KeyPoint> kp1, kp2; Mat desc1, desc2; orb(img1, Mat(), kp1, desc1); orb(img2, Mat(), kp2, desc2); // GMS匹配 GMSMatcher gms(kp1, img1.size(), kp2, img2.size()); vector<DMatch> matches; gms.GetMatches(kp1, desc1, kp2, desc2, matches); // 绘制匹配结果 Mat img_matches; drawMatches(img1, kp1, img2, kp2, matches, img_matches); imshow("Matches", img_matches); waitKey(0); return 0; } ``` 在上面的示例代码中,我们首先使用ORBextractor类提取图像的特征点和特征描述符。然后,我们使用GMSMatcher类进行特征点匹配,并使用drawMatches函数绘制匹配结果。请注意,为了使用ORBextractor和GMSMatcher类,我们需要包含ORBextractor.h和GMSMatcher.h头文件。 ### 回答2: 要使用OpenCV调用ORB-GMS匹配算法,需要包含以下头文件: #include <opencv2/opencv.hpp> #include <opencv2/features2d.hpp> #include <opencv2/xfeatures2d/nonfree.hpp> #include <opencv2/xfeatures2d.hpp> #include <opencv2/highgui.hpp> 首先,需要包含"opencv2/opencv.hpp"头文件来引入OpenCV的基本功能。 然后,需要包含"opencv2/features2d.hpp"头文件来使用特征点检测和描述子匹配的函数。这个头文件中包含了ORB特征点检测器和描述子提取器的相关类和函数。 接着,需要包含"opencv2/xfeatures2d/nonfree.hpp"头文件来使用现有的ORB特征点检测器和描述子提取器。 然后,需要包含"opencv2/xfeatures2d.hpp"头文件来引入OpenCV的扩展特征点检测和描述子提取器。 最后,需要包含"opencv2/highgui.hpp"头文件来使用OpenCV图像显示和调试函数。 通过包含这些头文件,我们就能够使用OpenCV提供的ORB-GMS匹配算法进行特征点匹配。 ### 回答3: 要调用OpenCV中的ORB-GMS匹配算法,你需要包含以下头文件: #include <opencv2/opencv.hpp> #include <opencv2/features2d.hpp> #include <opencv2/highgui.hpp> #include <opencv2/imgproc.hpp> 其中,第一个头文件opencv2/opencv.hpp是引用整个OpenCV库的头文件,它包含了所有OpenCV的核心功能和数据结构。第二个头文件opencv2/features2d.hpp是引用ORB特征提取和描述符的头文件。第三个头文件opencv2/highgui.hpp是引用图形界面相关的头文件,用于显示图像和结果。第四个头文件opencv2/imgproc.hpp是引用图像处理相关的头文件,用于对图像进行处理和转换。 然后,你需要创建ORB特征提取器和描述符提取器对象: cv::Ptr<cv::ORB> orb = cv::ORB::create(); 接下来,将需要匹配的图像加载到内存中: cv::Mat image1 = cv::imread("image1.jpg", cv::IMREAD_GRAYSCALE); cv::Mat image2 = cv::imread("image2.jpg", cv::IMREAD_GRAYSCALE); 然后,使用ORB特征提取器提取关键点和描述符: std::vector<cv::KeyPoint> keypoints1, keypoints2; cv::Mat descriptors1, descriptors2; orb->detectAndCompute(image1, cv::noArray(), keypoints1, descriptors1); orb->detectAndCompute(image2, cv::noArray(), keypoints2, descriptors2); 接下来,使用GMS方法进行特征匹配: cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::GMS); std::vector<cv::DMatch> matches; matcher->match(descriptors1, descriptors2, matches); 最后,你可以绘制匹配结果并显示出来: cv::Mat result; cv::drawMatches(image1, keypoints1, image2, keypoints2, matches, result); cv::imshow("Matches", result); cv::waitKey(0);

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值