导 Kinect2库,opencv库,pcl库

2023-05-16

                                     导 Kinect2库,opencv库,pcl库

Kinect2驱动安装:     https://blog.csdn.net/qq_15204179/article/details/107706758 

 

ndfreenect2.cmake   [Kinect2]

# 查找依赖库
FIND_LIBRARY(freenect2_LIBRARY freenect2
        PATHS ~/freenect2/lib
        NO_DEFAULT_PATH
        )
SET(freenect2_LIBRARIES ${freenect2_LIBRARY} pthread)

# 查找路径
FIND_PATH(freenect2_INCLUDE_DIR libfreenect2/libfreenect2.hpp
        PATHS ~/freenect2/include
        NO_DEFAULT_PATH
        )
SET(freenect2_INCLUDE_DIRS ${freenect2_INCLUDE_DIR})

FindOpenCV.cmake   [OpenCV]


# once done, this will define
#OpenCV_FOUND        -  whether there is OpenCV in the prebuilt libraries
#OpenCV_INCLUDE_DIRS -  include directories for OpenCV
#OpenCV_LIBRARY_DIRS -  library directories for OpenCV
#OpenCV_LIBRARIES    -  link this to use OpenCV

set(OpenCV_DIR ~/3rdparty/OpenCV-3.4.9)

unset(OpenCV_FOUND)

MESSAGE(STATUS "OpenCV_DIR TEST  ${PREBUILT_DIR}")

set(OpenCV_INCLUDE_DIRS "${OpenCV_DIR}/include" "${OpenCV_DIR}/include/opencv")
set(OpenCV_LIB_COMPONENTS opencv_core;opencv_ml;opencv_calib3d;opencv_highgui;opencv_superres;opencv_photo;
        opencv_imgcodecs;opencv_features2d;opencv_viz;opencv_flann;opencv_shape;opencv_stitching;opencv_dnn;
        opencv_videostab;opencv_imgproc;opencv_objdetect;opencv_video;opencv_videoio;opencv_reg;opencv_aruco;
        opencv_dpm;opencv_xobjdetect;opencv_xfeatures2d;opencv_surface_matching;opencv_plot;opencv_hfs;
        opencv_tracking;opencv_rgbd;opencv_text;opencv_dnn_objdetect;opencv_face;opencv_optflow;opencv_bgsegm;
        opencv_bioinspired;opencv_ximgproc;opencv_saliency;opencv_freetype;opencv_stereo;opencv_img_hash;
        opencv_fuzzy;opencv_ccalib;opencv_line_descriptor;opencv_hdf;opencv_datasets;opencv_phase_unwrapping;
        opencv_xphoto;opencv_structured_light)

find_path(OpenCV_INCLUDE_DIRS NAMES opencv.h HINTS ${OpenCV_DIR}/include NO_SYSTEM_ENVIRONMENT_PATH)

set(OpenCV_LIBRARY_DIRS ${OpenCV_DIR}/lib)

FOREACH(cvcomponent ${OpenCV_LIB_COMPONENTS})
  find_library(lib_${cvcomponent} NAMES ${cvcomponent} HINTS ${OpenCV_DIR}/lib NO_DEFAULT_PATH)

  set(OpenCV_LIBRARIES ${OpenCV_LIBRARIES};${lib_${cvcomponent}})
ENDFOREACH()

set(OpenCV_LIBS ${OpenCV_LIBRARIES})

set(OpenCV_INCLUDE_DIRS ${OpenCV_INCLUDE_DIRS};${OpenCV_INCLUDE_DIRS}/opencv)

if (OpenCV_INCLUDE_DIRS AND OpenCV_LIBRARIES)
  set(OpenCV_FOUND TRUE)
endif (OpenCV_INCLUDE_DIRS AND OpenCV_LIBRARIES)

if (OpenCV_FOUND)
  if (NOT OpenCV_FIND_QUIETLY)
    message(STATUS "Found OpenCV: ${OpenCV_LIBRARIES}")
  endif (NOT OpenCV_FIND_QUIETLY)
else(OpenCV_FOUND)
  if (OpenCV_FIND_REQUIRED)
    message(FATAL_ERROR "Could not find the OpenCV library")
  endif ()
endif (OpenCV_FOUND)

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
project(kinect2demo)

set(CMAKE_CXX_STANDARD 14)

set(OUTPUT_DIRECTORY_ROOT ${CMAKE_CURRENT_SOURCE_DIR}/build/debug)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${OUTPUT_DIRECTORY_ROOT}/bin" CACHE PATH "Runtime directory" FORCE)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${OUTPUT_DIRECTORY_ROOT}/lib" CACHE PATH "Library directory" FORCE)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${OUTPUT_DIRECTORY_ROOT}/lib" CACHE PATH "Archive directory" FORCE)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
#set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ~/3rdparty/OpenCV-3.4.9/share/OpenCV)

# -------------------------------------------------- 2
find_package(freenect2 REQUIRED)
find_package(OpenCV REQUIRED)
find_package(PCL REQUIRED)

include_directories(${freenect2_INCLUDE_DIR})
include_directories(${OpenCV_INCLUDE_DIRS})
include_directories(${PCL_INCLUDE_DIRS})

link_directories(${OpenCV_LIBRARY_DIRS})
link_directories(${PCL_LIBRARY_DIRS})

add_definitions(${PCL_DEFINITIONS})

add_subdirectory(src)
add_subdirectory(src/camera)


add_executable(kinect2demo main.cpp)

------------------------------------------------------------------------------------------------------------------------------------------------

01-Kinect2Camera.cpp  Kinect2获取保存彩色图及深度图

//
// Created by ty on 20-6-3.
//


#include <iostream>
#include <libfreenect2/libfreenect2.hpp>
#include <libfreenect2/packet_pipeline.h>
#include <libfreenect2/frame_listener_impl.h>
#include <libfreenect2/registration.h>

#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;


const int ACTION_ESC = 27;
const int ACTION_SPACE = 32;


// 图片的输出目录
const string output_dir = "../output";

/**
 * 获取Kinect2相机的内容
 *
 * in:
 *      Kinect2硬件设备
 * out:
 *      彩色图
 *      深度图
 *
 *  过滤深度值 去掉无限值|NAN
 *  水平翻转
 *  保存彩色图和深度图
 *  缩放为0.5倍
 */
int main(int argc, char *argv[]) {

    // 创建libfreenect2对象
    libfreenect2::Freenect2 freenect2;

    if (freenect2.enumerateDevices() == 0) {
        std::cerr << "当前未发现Kinect2设备" << std::endl;
        return -1;
    }

    const string &serial = freenect2.getDefaultDeviceSerialNumber();

    if (serial.empty()) {
        std::cerr << "设备序列号不存在" << std::endl;
        return -1;
    }

    std::cout << "设备序列号:" << serial << std::endl;

    // 创建数据处理管道
//    libfreenect2::OpenGLPacketPipeline *pipeline = new libfreenect2::CpuPacketPipeline();
    libfreenect2::OpenGLPacketPipeline *pipeline = new libfreenect2::OpenGLPacketPipeline();

    // 打开设备
    libfreenect2::Freenect2Device *device = freenect2.openDevice(serial, pipeline);

    // 创建数据接收监听器
    libfreenect2::SyncMultiFrameListener listener(libfreenect2::Frame::Color | libfreenect2::Frame::Depth);

    // 给设备设置数据监听器
    //颜色设备
    device->setColorFrameListener(&listener);
    //红外设备  红外与深度是一个相机
    device->setIrAndDepthFrameListener(&listener);

    // 启动设备
    device->start();

    // 创建对齐工具,帮我们把rgb和depth对齐(去畸变)
    libfreenect2::Registration *registration = new libfreenect2::Registration(device->getIrCameraParams(),//相机内参,相机中再带存了些;最好自己标定下数据会更准确些
                                                                              device->getColorCameraParams());

    std::cout << "设备固件版本:" << device->getFirmwareVersion() << std::endl;

    libfreenect2::Frame undistorted(512, 424, 4),   // 创建对象接收:已经去畸变的深度图,第3个参数:浮点类型的字节数
            registered(512, 424, 4),    // 创建对象接收:已经对齐的彩色图 (可能会有孔洞)把彩色图对齐到深度图上,第3个参数:浮点类型的字节数
            bigdepth(1920, 1082, 4);    // 创建对象接收:将小深度图对齐到彩色图上得到的大深度图  1920*1082 float; 1082 第一行与最好一行多了两空像素需要过干掉,第3个参数:浮点类型的字节数

    // 创建一个容器,准备接收数据
    libfreenect2::FrameMap frames;

    int index = 0;
    while (true) {//用户按下空格保存图片 按下esc退出
        // 这里会阻塞,直到拿到最新的数据。阻塞才会被释放,必须先释放当前的数据:listener.release(frames);
        listener.waitForNewFrame(frames);
        //取颜色图片
        libfreenect2::Frame *rgb = frames[libfreenect2::Frame::Color];
        //取深度图片
        libfreenect2::Frame *depth = frames[libfreenect2::Frame::Depth];

//        std::cout << "rgb->width: " << rgb->width << " rgb->height: " << rgb->height << std::endl;
//        std::cout << "depth->width: " << depth->width << " depth->height: " << depth->height << std::endl;
        // 彩色图与深度图合并; 对原始数据进行对齐 彩色图映射到深度图上  rgb彩色图 ,undistorted去畸变的深度图,registered配准后的彩色图 把彩色图贴到深度图上了 ;是否允许过滤 把相机不可见的像素过滤掉;bigdepth 输出把深度映射到彩色图上的图 大的深度图
        // bigdepth 输出把深度映射到彩色图上的图 大的深度图 1920*1082 float; 1082 第一行与最好一行多了两空像素需要过干掉
        registration->apply(rgb, depth, &undistorted, &registered, true, &bigdepth);

        // 512x424 已和深度对齐的彩色图
//        Mat registeredRgbMat = Mat(registered.height, registered.width, CV_8UC4, registered.data);
        // 512x424 已去畸变的深度图
//        Mat undistortedDepthMat = Mat(undistorted.height, undistorted.width, CV_32FC1, undistorted.data);
        // 512x424 未去畸变的深度图
//        Mat smallDepthMat = Mat(depth->height, depth->width, CV_32FC1, depth->data);

        // 将kinect类型的数据转成OpenCV的Mat
        //CV_8UC4 u代表无符号 c是通道 通道为4
        // 1920x1080
        // opencv提供Mat构造函数 帮我们把unsigned char* 转成 mat对象
        Mat rgbMat = Mat(rgb->height, rgb->width, CV_8UC4, rgb->data);
        // 1920x1082  CV_32FC1 32位精度浮点数 单通道  bigDepthMat_ 深度值单位毫米,接收的时候要用CV_32FC1数据类型
        Mat bigDepthMat_ = Mat(bigdepth.height, bigdepth.width, CV_32FC1, bigdepth.data);


         //过滤深度值 去掉无限值|NAN, 裁剪
        //       起始列   起始行       总列数       需要的行数
        //  Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height); 1920*1082 float 截取深度图 获得1080的长度
       // 截取深度图 获得1080的长度 ,1920*1082 float
        Mat bigDepthMat = bigDepthMat_(Rect(0, 1, bigDepthMat_.cols, bigDepthMat_.rows - 2));
        //过滤深度值 去掉无限值|NAN
        for (int i = 0; i < bigDepthMat.rows; ++i) {
            for (int j = 0; j < bigDepthMat.cols; ++j) {
                float &d = bigDepthMat.at<float>(i, j);
                if (fpclassify(d) == FP_INFINITE || fpclassify(d) == NAN) {
                    d = 0;
                }
            }
        }

        // *  水平翻转
        flip(rgbMat, rgbMat, 1);
        flip(bigDepthMat, bigDepthMat, 1);


        int action = waitKey(30) & 0xFF;

        if (action == ACTION_ESC || action == 'q' || action == 'Q') {//按下q 或 esc 27退出
            break;
        } else if (action == ACTION_SPACE) {//用户按下空格保存32图片
            std::cout << "保存rgb图和depth图" << std::endl;
//            *  保存彩色图和深度图

            // 保存彩图
            stringstream rr;
            rr << output_dir << "/rgb_image_" << index << ".jpg";
            vector<int> params;
            params.push_back(CV_IMWRITE_JPEG_QUALITY);//图片格式
            params.push_back(100);//压缩的比例
            bool rst = imwrite(rr.str(), rgbMat, params);
            if (!rst) {
                std::cerr << "目标目录不存在,请检查后再保存: " << output_dir << std::endl;
                return -1;
            }
            std::cout << "保存彩色图成功:" << rr.str() << std::endl;

            // 保存深度图 深度图全是数字 不是可是的图片,要保存成文件
            // 将数据转成单通道16位UINT,CV_16UC1 整形16位的保存,接收的时候要用CV_32FC1数据类型
            bigDepthMat.convertTo(bigDepthMat, CV_16UC1);
            stringstream dd;
            dd << output_dir << "/depth_image_" << index << ".xml";
            FileStorage fs(dd.str(), FileStorage::WRITE);
            fs << "depth" << bigDepthMat;
            fs.release();
            std::cout << "保存深度值成功:" << dd.str() << std::endl;

        }
//       *  缩放为0.5倍
        resize(rgbMat, rgbMat, Size(), 0.5, 0.5, INTER_LINEAR);
        resize(bigDepthMat, bigDepthMat, Size(), 0.5, 0.5, INTER_LINEAR);

        imshow("color", rgbMat);//彩色图显示
        imshow("depth", bigDepthMat / 4500.0f);//官方推荐显示深度图除4500

        //必须先释放当前的数据  waitForNewFrame才会拿到数据
        listener.release(frames);
    }

    device->stop();//停掉设备
    device->close();//后关闭设备

    delete registration;//回收数据
}

02-PointCloudMaker.cpp  Kinect2转点云图

 

//
// Created by ty on 20-6-3.
//


#include <iostream>

#include <opencv2/opencv.hpp>

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/io/io.h>
#include <pcl/visualization/cloud_viewer.h>

using namespace std;
using namespace cv;

typedef pcl::PointXYZRGB PointT;
typedef pcl::PointCloud<PointT> PointCloud;

/**
 * OpenCV
 * PCL
 *
 * 输入:
 *      彩色图
 *      深度图
 *      相机的内参
 *
 * 输出:
 *      点云图
 *
 */
int main(int argc, char *argv[]) {

    // 读取彩色图和深度图
    const Mat &rgbMat = imread("./output1/rgb_image_0.jpg", CV_LOAD_IMAGE_UNCHANGED);
    // 深度图
    Mat depthMat;
    FileStorage fs("./output1/depth_image_0.xml", FileStorage::READ);
    fs["depth"] >> depthMat;
    fs.release();

    // 读取相机内参
    Mat cameraMatrix = cv::Mat_<double>(3, 3);
    FileStorage camera_fs("./calib/calibration_in_params.yml", FileStorage::READ);
    camera_fs["cameraMatrix"] >> cameraMatrix;
    camera_fs.release();

    std::cout << cameraMatrix << std::endl;

    double fx = cameraMatrix.at<double>(0, 0);
    double fy = cameraMatrix.at<double>(1, 1);
    double cx = cameraMatrix.at<double>(0, 2);//u
    double cy = cameraMatrix.at<double>(1, 2);//v

    // 准备一个点云,接收数据
    PointCloud::Ptr cloud(new PointCloud);

    // 遍历每一个深度图的宽高,给点云的每个点指定其颜色值和深度值
    for (int v = 0; v < depthMat.rows; ++v) { // 所有行
        for (int u = 0; u < depthMat.cols; ++u) { // 所有
            // 取出每个像素对应的Z值
            ushort d = depthMat.at<ushort>(v, u);//单位毫米
            double depth_value = double(d) / 1000.0f;//变为米为单位,计算都是用米为单位,存储都是毫米为单位

            if (depth_value == 0 || isnan(depth_value) || abs(depth_value) < 0.0001) {//depth_value==0 或者不是数字 或者绝对值很小比1微米还小的值
                continue;
            }
            // 创建一个点Point
            PointT p;

            // 根据内参计算出其X,Y -----------------------------------------
            p.z = depth_value;
            p.x = (u - cx) * p.z / fx;
            p.y = (v - cy) * p.z / fy;

            // 给其指定颜色
            Vec3b bgr = rgbMat.at<Vec3b>(v, u);
            p.b = bgr[0];
            p.g = bgr[1];
            p.r = bgr[2];

            // 添加到cloud中
            cloud->points.push_back(p);
        }
    }

    // 显示cloud点云
    cloud->width = cloud->points.size();//无序点云的宽即是cloud长度
    cloud->height = 1;
    cloud->is_dense = false;//是否是密集的

    pcl::visualization::CloudViewer viewer("cloud_viewer");

    viewer.showCloud(cloud);
    //保存成点云文件
//    pcl::io::savePCDFileASCII("output/test_pcd.pcd", cloud);
//    std::cerr << "Saved " << cloud.points.size() << " data points to test_pcd.pcd." << std::endl;
    while (!viewer.wasStopped()) {
        //
    }

}

03-PhotoCapture.cpp  Kinect2 实时获取点云图

#include <iostream>
#include <opencv2/opencv.hpp>
#include <sstream>
#include <cstdlib>

#include <pcl/io/pcd_io.h>
#include <pcl/visualization/cloud_viewer.h>
#include <KinectCamera.h>

using namespace std;
using namespace cv;

float qnan_ = std::numeric_limits<float>::quiet_NaN();
const char *cameraInCailFile = "./calib/calibration_in_params.yml";
// 获取目标目录
//const char *output_dir = "./scene";
// 制作模板目录
const char *output_dir = "./capture_temp";

const int ACTION_ESC = 27;
const int ACTION_SPACE = 32;


Eigen::Matrix<float, 1920, 1> colmap;
Eigen::Matrix<float, 1080, 1> rowmap;
const short w = 1920, h = 1080;

// 准备数据
void prepareMake3D(const double cx, const double cy,
                   const double fx, const double fy) {
//    const int w = 512;
//    const int h = 424;
    float *pm1 = colmap.data();
    float *pm2 = rowmap.data();
    for (int i = 0; i < w; i++) {
        *pm1++ = (i - cx + 0.5) / fx;
    }
    for (int i = 0; i < h; i++) {
        *pm2++ = (i - cy + 0.5) / fy;
    }
}

/**
 * 根据内参,合并RGB彩色图和深度图到点云
 * @param cloud
 * @param depthMat
 * @param rgbMat
 */
void getCloud(pcl::PointCloud<pcl::PointXYZRGB>::Ptr &cloud, Mat &depthMat, Mat &rgbMat) {
    const float *itD0 = (float *) depthMat.ptr();
    const char *itRGB0 = (char *) rgbMat.ptr();

    if (cloud->size() != w * h)
        cloud->resize(w * h);

    // 获取点云的点集合的指针
    pcl::PointXYZRGB *itP = &cloud->points[0];
    bool is_dense = true;

    // 遍历所有行
    for (size_t y = 0; y < h; ++y) {

        // 偏差个数, 跳过y行 y * 1920 个
        const unsigned int offset = y * w;
        // 深度图指针加上偏差
        const float *itD = itD0 + offset;
        // 彩色图指针加上偏差
        const char *itRGB = itRGB0 + offset * 4;
        // 获取指定行的系数
        const float dy = rowmap(y);

        // 遍历第y行的所有列
        for (size_t x = 0; x < w; ++x, ++itP, ++itD, itRGB += 4) {
            const float depth_value = *itD / 1000.0f;

            if (!isnan(depth_value) && abs(depth_value) >= 0.0001) {

                const float rx = colmap(x) * depth_value;
                const float ry = dy * depth_value;
                itP->z = depth_value;
                itP->x = rx;
                itP->y = ry;

                itP->b = itRGB[0];
                itP->g = itRGB[1];
                itP->r = itRGB[2];
            } else {
                itP->z = qnan_;
                itP->x = qnan_;
                itP->y = qnan_;

                itP->b = qnan_;
                itP->g = qnan_;
                itP->r = qnan_;
                is_dense = false;
            }
        }
    }
    cloud->is_dense = is_dense;
}


/*
 * 保存Kenect相机的实时图片
 *  按enter键保存
 * */
int main(int argc, char *argv[]) {

    // 显示RGB图
    // 显示深度图
    // 显示合成后的点云图

    auto *camera = new KinectCamera();
//    cv::VideoCapture capture(0);
    if (!camera->isOpened()) {
        std::cout << "无法开启摄像头!" << std::endl;
        return -1;
    }

    Mat cameraMatrix = cv::Mat_<double>(3, 3);
    FileStorage paramFs(cameraInCailFile, FileStorage::READ);
    paramFs["cameraMatrix"] >> cameraMatrix;
    // 内参数据
    double fx = cameraMatrix.at<double>(0, 0);
    double fy = cameraMatrix.at<double>(1, 1);
    double cx = cameraMatrix.at<double>(0, 2);
    double cy = cameraMatrix.at<double>(1, 2);

    prepareMake3D(cx, cy, fx, fy);

    // 准备点云查看工具
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("3D Viewer"));

    // 创建智能指针点云
    pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZRGB>());
    viewer->setBackgroundColor(0, 0, 0);

    pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgbHandler(cloud);
    viewer->addPointCloud<pcl::PointXYZRGB>(cloud, rgbHandler, "sample cloud");
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 1, "sample cloud");

    int index = 0;
    while (true) {
        cv::Mat rgbMat, depthMat;
        camera->capture(rgbMat, depthMat);


        if (!viewer->wasStopped()) {
            // 将RGB和深度信息合成为一个点云图,保存到cloud中
            getCloud(cloud, depthMat, rgbMat);

            pcl::visualization::PointCloudColorHandlerRGBField<pcl::PointXYZRGB> rgbHandler(cloud);
            viewer->updatePointCloud<pcl::PointXYZRGB>(cloud, rgbHandler, "sample cloud");

            viewer->spinOnce();
        }

        int action = cv::waitKey(20) & 0xFF;

        if (action == ACTION_SPACE || action == 'q') {
            // 保存点云
            std::cout << "保存当前的点云" << std::endl;


            stringstream rr;
            rr << output_dir << "/camera_rgb_" << index << ".jpg";
            vector<int> compression_params;
            compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);  //选择jpeg
            compression_params.push_back(100); //在这个填入你要的图片质量
            bool rst = cv::imwrite(rr.str(), rgbMat, compression_params);
            if (!rst) {
                std::cerr << "保存失败,请检查该文件夹是否存在:" << output_dir << std::endl;
                return -1;
            }
            cout << rr.str() << endl;

            depthMat.convertTo(depthMat, CV_16UC1);

            // 保存深度图
            stringstream ss;
            ss << output_dir << "/camera_depth_" << index << ".xml";
            FileStorage fs(ss.str(), FileStorage::WRITE);
            fs << "depth" << depthMat;
            fs.release();

            stringstream ss_pcd;
            ss_pcd << output_dir << "/table_scene_" << index << ".pcd";
            // 保存模板点云图
            pcl::io::savePCDFile(ss_pcd.str(), *cloud);
            index++;
            cout << "成功保存RGB, 深度图, 点云图" << endl;

        }else if(action == ACTION_ESC) {
            // 退出
            break;

        }

        cv::imshow("rgb", rgbMat);
        cv::imshow("depth", depthMat / 4500);

    }
    camera->release();


    return 0;
}

===========================================================================================

Kinect_封装好的驱动

只能获取彩色图

workspas/HandEyeCalibration/cmake/Findfreenect2.cmake

# 查找依赖库
# 头文件include: freenect2_INCLUDE_DIRS
# 依赖库:       freenect2_LIBRARIES

FIND_LIBRARY(freenect2_LIBRARY freenect2
        PATHS ~/freenect2/lib
        NO_DEFAULT_PATH
        )
SET(freenect2_LIBRARIES ${freenect2_LIBRARY} pthread)

# 查找路径
FIND_PATH(freenect2_INCLUDE_DIR libfreenect2/libfreenect2.hpp
        PATHS ~/freenect2/include
        NO_DEFAULT_PATH
        )
SET(freenect2_INCLUDE_DIRS ${freenect2_INCLUDE_DIR})

workspas/HandEyeCalibration/src/camera/CMakeLists.txt

add_library(kinect_camera KinectCamera.cpp KinectCamera.h)
target_link_libraries(kinect_camera ${OpenCV_LIBRARIES} ${freenect2_LIBRARIES})

workspas/HandEyeCalibration/src/camera/KinectCamera.cpp

//
// Created by ty on 20-9-26.
//

#include "KinectCamera.h"


int KinectCamera::init() {


    // 判断已连接的设备个数
    if (freenect2.enumerateDevices() == 0) {
        std::cerr << "未发现Kinect2设备" << std::endl;
        return -1;
    }

    const string &serial = freenect2.getDefaultDeviceSerialNumber();

    if (serial.empty()) {
        std::cerr << "设备序列号不存在" << std::endl;
        return -1;
    }

    std::cout << "设备序列号: " << serial << std::endl;

    // 创建pipeline接收并处理数据
//    auto *pipeline = new libfreenect2::CpuPacketPipeline();
    auto pipeline = new libfreenect2::OpenGLPacketPipeline();

    // 根据序列号开启设备,并设定数据处理通道
    device = freenect2.openDevice(serial, pipeline);

    // 创建数据接收器(监听器),给设备执行监听;
    device->setColorFrameListener(&listener);
    device->setIrAndDepthFrameListener(&listener);

    device->start();

    return 0;
}

void KinectCamera::capture(Mat& outputMat) {

    listener.waitForNewFrame(frames);

    libfreenect2::Frame *rgb = frames[libfreenect2::Frame::Color];
    libfreenect2::Frame *depth = frames[libfreenect2::Frame::Depth];

    Mat colorMat = Mat(rgb->height, rgb->width, CV_8UC4, rgb->data);
    // 图像进行镜像处理
    flip(colorMat, colorMat, 1);

    colorMat.copyTo(outputMat);

    listener.release(frames);

}


void KinectCamera::release() {
    device->stop();
    device->close();
}

KinectCamera::~KinectCamera() {

}


workspas/HandEyeCalibration/src/camera/KinectCamera.h

//
// Created by ty on 20-9-26.
//

#ifndef HANDEYECALIBRATION_KINECTCAMERA_H
#define HANDEYECALIBRATION_KINECTCAMERA_H


#include <iostream>
#include <opencv2/opencv.hpp>
#include <libfreenect2/libfreenect2.hpp>
#include <libfreenect2/packet_pipeline.h>
#include <libfreenect2/frame_listener_impl.h>

using namespace std;
using namespace cv;


class KinectCamera {

private:
    int status = -2; // -2 初始状态, -1 出现错误, 0 正常可用

    // 1. 初始化Kinect2相机对象
    libfreenect2::Freenect2 freenect2;

    libfreenect2::Freenect2Device *device = nullptr;

    libfreenect2::SyncMultiFrameListener listener;

    libfreenect2::FrameMap frames;

public:
    KinectCamera(): listener(libfreenect2::Frame::Color | libfreenect2::Frame::Depth) {
        status = init();
    }

    virtual ~KinectCamera();

    // 判断设备是否开启
    bool isOpened() {
        return status == 0;
    }

    virtual int init();

    virtual void release();

    void capture(Mat& colorMat);

    void capture(Mat& colorMat, Mat& depthMat);
};


#endif //HANDEYECALIBRATION_KINECTCAMERA_H

使用:

#include <libfreenect2/libfreenect2.hpp>
#include <libfreenect2/packet_pipeline.h>
#include <libfreenect2/frame_listener_impl.h>
#include <opencv2/opencv.hpp>


int main(int argc, char *argv[]) {
   KinectCamera* camera = new KinectCamera();

    if (!camera->isOpened()) {
        std::cerr << "相机打开失败" << std::endl;
        return -1;
    }

    while (true) {
    //  2. 循环接收相机数据rgb,depth (一定要在下次wait之前释放掉frames.   
        //listener.release(frames);)

        Mat colorMat, srcMat, gray;

        camera->capture(colorMat);

        // 备份一份原图
        colorMat.copyTo(srcMat);

     // 3. 在rgb彩色图里查找角点
        cvtColor(colorMat, gray, COLOR_BGR2GRAY);

        imageSize = gray.size();

    }

 cv::destroyAllWindows();
    // 设备使用完毕后,及时关闭
    camera->release();


}

 

------------------------------------------------------------------------------------------------------------------------------------

控制台命令启动相机

cd ~/3rdparty/source/libfreenect2-master/build/bin
./Protonect

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

导 Kinect2库,opencv库,pcl库 的相关文章

  • 使用 OpenCV 和/或 Numpy 对两个图像进行 Alpha 混合 [重复]

    这个问题在这里已经有答案了 我想将一个填充纯色的半透明矩形添加到已加载的半透明 PNG 中 这是我正在使用的输入图像示例 该图像加载了标准cv2 IMREAD UNCHANGED标志 以便完美保留 alpha 通道 该输入图像存储在imag
  • uri 警告中缺少端口:使用 Python OpenCV cv2.VideoCapture() 打开文件时出错

    当我尝试流式传输 ipcam 时 出现了如下所示的错误 tcp 000000000048c640 uri 中缺少端口 警告 打开文件时出错 build opencv modules videoio src cap ffmpeg impl h
  • 2d 图像点和 3d 网格之间的交点

    Given 网格 源相机 我有内在和外在参数 图像坐标 2d Output 3D 点 是从相机中心发出的光线穿过图像平面上的 2d 点与网格的交点 我试图找到网格上的 3d 点 This is the process From Multip
  • iOS 上的 OpenCV - VideoCapture 属性始终返回 1

    我一直在尝试构建一个简单的 OpenCV iOS 应用程序 该应用程序从捆绑包中加载视频并查询其帧数 持续时间等 然后它将尝试从中获取各个帧 不幸的是 当我使用VideoCapture类中 所有属性返回值 1 然后我尝试导航到frame 1
  • 同时从多个流中捕获、最佳方法以及如何减少 CPU 使用率

    我目前正在编写一个应用程序 该应用程序将捕获大量 RTSP 流 在我的例子中为 12 个 并将其显示在 QT 小部件上 当我超过大约 6 7 个流时 问题就会出现 CPU 使用率激增并且出现明显的卡顿 我认为它不是 QT 绘制函数的原因是因
  • 二值图像中骨架上两点之间的最短路径

    我有一个二进制图像 其中包含图像的一个像素宽度骨架 您可能基本上知道 在这个二值图像中 我在骨架上有 1 在其他地方有 0 如何找到骨架上两个非零元素之间的最短距离 路径也应该在骨架本身上 我想使用 A star 算法的 C 实现 我找到了
  • OpenCV VideoWriter 未写入 Output.avi

    我正在尝试编写一段简单的代码来获取视频 裁剪视频并写入输出文件 系统设置 OS Windows 10 Conda Environment Python Version 3 7 OpenCV Version 3 4 2 ffmpeg Vers
  • “没有名为‘cv2’的模块”,但已安装

    我已经安装了包含 opencv 贡献的 whl 文件 因为我想使用 SIFT 算法 我在 conda 环境中使用 pip 安装了它 所以当我在 conda list 中提示时 它会向我显示 opencv python 3 4 5 contr
  • 在 Visual Studio C++ 2008 中包含 dll

    有没有办法将 dll 包含在项目中 这样我就不必在编译后将这些 dll 与可执行文件放在同一文件夹中 这样我就可以用它们编译我的项目 这是否有可能 如果是 有人可以指导我 我的项目是一个 opencv 项目 有很多 dll 我必须包含在文件
  • 如何将多行文本插入到框架/图像中

    我使用 C 和 OpenCV 创建了一个框架 并想在其中插入几行文本 使用以下代码 putText frame My text here cvPoint 30 30 FONT HERSHEY COMPLEX SMALL 0 8 cvScal
  • 从 NumPy 数组到 Mat 的 C++ 转换 (OpenCV)

    我正在围绕 ArUco 增强现实库 基于 OpenCV 编写一个薄包装器 我试图构建的界面非常简单 Python 将图像传递给 C 代码 C 代码检测标记并将其位置和其他信息作为字典元组返回给 Python 但是 我不知道如何在 Pytho
  • 开放简历fisherfaces

    我有这个问题 当我使用 vs2010 调试 opencv 2 4 0 facetec demo c 运行时 程序出现此错误 OpenCV错误 未知函数中图像步长错误 矩阵不连续 因此其行数无法更改 文件 src opencv modul e
  • 如何加速 svm.predict?

    我正在编写一个滑动窗口来提取特征并将其输入到 CvSVM 的预测函数中 然而 我偶然发现 svm predict 函数相对较慢 基本上 窗口以固定的步幅长度在图像比例上滑动穿过图像 遍历图像加上提取每个图像特征的速度 窗口大约需要 1000
  • 使用卡尔曼滤波器跟踪位置和速度

    我正在使用卡尔曼滤波器 恒定速度模型 来跟踪物体的位置和速度 我测量对象的 x y 并跟踪 x y vx vy 这是有效的 但是如果在传感器读数 x y vx vy 上添加 20 mm 的高斯噪声 即使该点没有移动 只是噪声也会发生波动 对
  • 选择合适的IDE

    您会推荐使用以下哪种 IDE 语言来在 Windows 下开发涉及识别手势并与操作系统交互的项目 我将使用 OpenCV 库来执行图像处理任务 之后 我将使用 win32 API 或 NET 框架与操作系统交互 具体取决于您建议的工具 性能
  • 使用 OpenCV 进行图像模糊检测

    我正在研究图像的模糊检测 我已经用过拉普拉斯方法的方差在 OpenCV 中 img cv2 imread imgPath gray cv2 cvtColor img cv2 COLOR BGR2GRAY value cv2 Laplacia
  • 如何在python 3.8中安装opencv-python

    我在 pycharm 中安装 opencv python 时遇到问题 打开 pycharm 后 我单击 设置 然后单击 项目解释器 单击 并搜索正确的模块 我开始安装 但失败了 Could not find a version that s
  • 尝试使使用 OpenCV 的 java 应用程序(可执行 Jar)可移植。出现不满意的链接错误

    我制作了一个应用程序 用于从网络摄像头抓取视频并使用 OpenCV 和 JavaCV 检测运动 我正在尝试使用 eclipse 导出为可执行 jar 该程序在 eclipse 中运行良好 就像我编写该程序的计算机上的 exe jar 一样
  • 在openCV内部调用Gstreamer

    我需要在 openCV 代码中调用 Gstremaer 本质上是打开摄像机 当我查看源代码时 modules highgui src cap gstreamer cpp似乎是我正在寻找的文件 我用 Gstreamer 标志编译了 OpenC
  • 为什么在 OpenCV 中访问该矩阵时出现内存错误?

    我只是想写入给定大小的矩阵 当我在 Valgrind 中运行该程序时 出现内存错误 如下所示 主要 cpp include

随机推荐

  • mysql数据更新时变更时间自动更新

    ALTER TABLE test CHANGE startTime startTime timestamp NOT NULL ON UPDATE CURRENT TIMESTAMP DEFAULT CURRENT TIMESTAMP
  • docker、docker-compose和Portainer的安装

    一 docker安装 span class token comment 安装docker相关依赖 span yum span class token function install span y yum utils device mapp
  • vue-cli+spring boot前后端分离跨域及session丢失解决办法

    前后端分离跨域笔记 小小的唠叨前端代码后端 小小的唠叨 曾几何时 xff0c 项目开发时间很紧 xff0c 项目组很多的人即不懂vue也不大懂spring boot及mybatic的强大之处 xff0c 也没有做过前后端分离 xff0c 项
  • vue打包整合到spring boot一记

    目录 背景vue cli打包之前的配置总结 背景 前段时间 xff0c 根据需求 xff0c 要将项目烧入到芯片 xff0c 但我的擅长之处就是前后端分离开发 xff0c 因此需要前端vue开发好 xff0c 打包放到后端里面一起执行 那时
  • 小四轴编程入门教程

    小四轴编程入门教程之一 xff1a 陀螺仪和加速度计 在小四轴中 xff0c 陀螺仪是一种用于测量小四轴旋转速度的传感器 xff0c 它测量的是角速度 xff0c 是指物体在单位时间内转过的角度大小 通过测量物体在X Y Z三个轴上的角速度
  • 从0开始教你三天完成毕业设计-后端api

    目录 前言 开始 env 数据库配置文件 app controller 控制器接口api 工具类 分类表 categoryController 收藏表 collecetionController 商品表 goodController 订单表
  • ZYNQ双核通信 Linux+FreeRTOS(一)

    ZYNQ 双核通信 一 OpenAMP开发换环境搭建编译U boot编译Kernel编译设备树什么是devicetree xff1f Devicetree基础设备树属性设备树生成器 xff08 DTG xff09 Task Output P
  • ZYNQ 安装ubuntu文件系统

    ZYNQ 7020 Ubuntu16 04文件系统安装 在关于zynq openamp的章节我们已经完成了zynq 的u boot 内核 xff0c 设备树的制作 xff0c 通过XSDK完成了启动文件的创建 同样道理制作zynq7020的
  • RPMsg:协议简介

    RPMsg xff1a 协议简介 本篇文章转载于简书 xff0c 在此做个整理和备份 xff0c 方便查阅 在此感谢原博主SunnyZhou1024 RPMsg xff1a 协议简介0 起因1 AMP2 RPMsg2 1 Linux中的RP
  • GEM TSU Interface Details and IEEE 1588 Support

    GEM TSU Interface Details and IEEE 1588 Support Chapter 1 IntroductionChapter 2 GEM TSU Clock SourcePCW 中的 GEM TSU 时钟源选择
  • ZYNQ UltraScale+ MPSoC Linux + ThreadX AMP玩法

    ZYNQ UltraScale 43 MPSoC Linux 43 ThreadX AMP玩法 ZYNQ UltraScale 43 MPSoC与ZYNQ 7000架构比较目标 一 创建Linux1 修改kernel2 修改设备树编译 am
  • Zipwire

    文章目录 Chapter 55 Zipwire55 1 Chip specific Zipwire information52 2 Overview55 3 Introduction55 4 Zipwire Block Diagram55
  • arm启动过程详解

    ARM芯片的启动程序的分析和总结 2009 02 04 14 35 26 标签 xff1a 杂谈 分类 xff1a ARM 1 综述 xff1a 目前大多基于ARM芯片的系统都是一个比较复杂的片上系统 xff0c 多数硬件模块都是可配置的
  • 数据读写的乒乓操作

    数据读写的乒乓操作 文中一部分从其他博客中学习到 xff0c 加入了自己实际应用的过程 在重要数据的解帧与处理过程中 xff0c 为了确保数据的实时性与可靠性 xff0c 我们一般对收到的数据存储到芯片的RAM或Flash xff08 掉电
  • 生命在于学习——Linux提权

    本篇文章仅用于学习记录 xff0c 不得用于其他违规用途 一 内核漏洞提权 1 常规查找 查看内核版本信息 uname span class token operator span a uname span class token oper
  • 前入式JUC常用类源码分析

    CountDownLatch span class token keyword public span span class token keyword class span span class token class name Coun
  • dockerfile中的命令:run, cmd, entrypoint, copy和add

    总结一下 xff0c run 可以有多个 xff0c cmd 和entrypoint 只能有一个 xff08 常用来跑app xff09 cmd 可以被docker 指令overwrite xff0c entrypoint不可以 此命令会在
  • Qt类关系一览表

    Qt类关系一览表
  • ros之pid

    PID口诀 参数整定找最佳 xff0c 从小到 大顺序查 先是比例后积分 xff0c 最后再把微分加 曲线振荡很频繁 xff0c 比例度盘要放大 曲线漂浮绕大湾 xff0c 比例度盘往小扳 曲线偏离回复慢 xff0c 积分时间往下降 曲线波
  • 导 Kinect2库,opencv库,pcl库

    导 Kinect2库 opencv库 pcl库 Kinect2驱动安装 https blog csdn net qq 15204179 article details 107706758 ndfreenect2 cmake Kinect2