Jeston TX2 使用cmake 运行测试realsense D435i相关代码(C++)
前言:
我这些天作毕设的TX2上面的Jetpack包是4.3的。然后我又自己用JetPack4.6.1包刷机了,这个刷机过程也耗时将近一整个白天(希望你们刷机时候的连线务必是官方提供的线,不然确实会有连不上去的可能,我的就连不上,后来翻箱倒柜找到了厂家原装线,这才连接接成功)。刷机的部分我就不多叙述,网上有很多教程。
刷完机之后我又去装了realsense sdk,根据的是这个教程
使用 TX2 和 realsense D435i 相机运行 ORBSLAM3
,这个教程安装realsense满简单的,然后这个教程中给了如何用cmake运行可以调用librealsense的代码例子。可我还需要加上可以调用opencv库的功能,所以本文的主要目的来了:运行可以调用librealsense和opencv库的代码(使用cmake)。
参考:
使用 TX2 和 realsense D435i 相机运行 ORBSLAM3
【C++】Cmake使用教程(看这一篇就够了)
(我一开始也不会熟练用cmake,看了这个之后,感觉如果是简单使用的话很容易上手)
ubuntu下使用Cmake编译opencv记录
(我也参考了这一篇文章,如何用cmake调用opencv库,我也是把调用librealsense库和调用opencv库结合起来用的。)
主文:
我在目录里面创建了 两个文件夹。一个是 test_realsense 和realsense_test。test_realsense文件夹主要是测试librealsense库调用的。realsense_test文件夹主要是测试调用opencv库和librealsense库的。
编写并测试test_realsense的程序
test_realsense文件夹里主要是三个文件和一个build文件夹。(build文件夹你也可以不用创建)
首先是CMakeLists.txt文件
# License: Apache 2.0. See LICENSE file in root directory.
# Copyright(c) 2019 Intel Corporation. All Rights Reserved.
cmake_minimum_required(VERSION 3.1.0)
project(hello_librealsense2)#这个你可以随便命名
# Find librealsense2 installed package
find_package(realsense2 REQUIRED)#这个自动找realsense 的依赖库
# Enable C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
# Add the application sources to the target
add_executable(${PROJECT_NAME} hello_librealsense2.cpp)
# Link librealsense2 to the target
target_link_libraries(${PROJECT_NAME} ${realsense2_LIBRARY})
然后是
hello_realsense2.cpp
// Copyright(c) 2017 Intel Corporation. All Rights Reserved.
#include <librealsense2/rs.hpp>
#include <librealsense2/hpp/rs_internal.hpp>
#include <iostream>
int main()
{
rs2::context ctx;
std::cout << "hello from librealsense - " << RS2_API_VERSION_STR << std::endl;
std::cout << "You have " << ctx.query_devices().size() << " RealSense devices connected" << std::endl;
return 0;
}
md文件没必要了,这个也是我从网上拷过来的。
好了,接下来开始编译运行吧。
我们进入build文件夹并打开终端
输入cmake …
然后make 得到hello_realsense2这个可执行文件
然后我们就运行吧。
输入./hello_realsense2
运行成功。
我们已经测试好了调用realsense库文件的程序。
接下来
编写并测试调用librealsense和opencv库的程序
进入realsense_test文件夹,我们关注CMakeLists.txt 和main.cpp 文件。其它两个文件,是之前在QT上跑工程的,现在刷机后,我没有装qt,所以这两个文件也没有用了,这两个文件对于我们使用cmake没有任何影响,大家可以忽略它。
CMakeLists.txt文件
# 这是对CMake工具最低版本要求,我们可以使用命令“cmake --version”查看CMake版本
cmake_minimum_required(VERSION 3.1)
# 设置工程文件名
#这是建立一个工程项目(类似于我们VS中建立C++项目一样),括号里面时工程名,工程名我们可以任意给,最后程序编译出来的可执行文件就是这个名字
project(realsense) # 把这块的工程文件名修改成你自己的
# Find OpenCV, you may need to set OpenCV_DIR variable
# to the absolute path to the directory containing OpenCVConfig.cmake file
# via the command line or GUI
find_package(OpenCV REQUIRED) # 这是cmake用来查找opencv包用的,不用改
# Find librealsense2 installed package
find_package(realsense2 REQUIRED)
# If the package has been found, several variables will
# be set, you can find the full list with descriptions
# in the OpenCVConfig.cmake file.
# Print some message showing some of them
message(STATUS "OpenCV library status:")
message(STATUS " config: ${OpenCV_DIR}")
message(STATUS " version: ${OpenCV_VERSION}")
message(STATUS " libraries: ${OpenCV_LIBS}")
message(STATUS " include path: ${OpenCV_INCLUDE_DIRS}")
# Enable C++11
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)
# Declare the executable target built from your sources
# 这里括号里面的两个参数分别是工程项目名和我们要编译文件名的意思,记住中间一空格键隔开
add_executable(${PROJECT_NAME} main.cpp) # 改工程文件名 源文件名
# Link your application with OpenCV libraries 链接到OpenCV库的环节
target_link_libraries(${PROJECT_NAME} ${realsense2_LIBRARY} ${OpenCV_LIBS}) # 改工程文件名
我们发现这个txt文件与上个程序中的文件多了个找opencv库的find_package,和一些message输出函数,还有最后的target_link_libraries。这些功能我个人是顾名思义式地来理解的,大家想深入了解的话,自己去查吧(@。@)
main.cpp
#include <librealsense2/rs.hpp> // Include RealSense Cross Platform API
#include<iostream>
#include<opencv2/opencv.hpp>
int main(int argc, char * argv[]) try
{
rs2::log_to_console(RS2_LOG_SEVERITY_ERROR);
/// Create librealsense context for managing devices
rs2::context ctx;
auto devs = ctx.query_devices(); ///获取设备列表
int device_num = devs.size();
std::cout<<"device num: "<<device_num<<std::endl;///设备数量
///我只连了一个设备,因此我查看第0个设备的信息
/// 当无设备连接时此处抛出rs2::error异常
rs2::device dev = devs[0];
///设备编号,每个设备都有一个不同的编号, 如果连接了多个设备,便可根据此编号找到你希望启动的设备
char serial_number[100] = {0};
strcpy(serial_number, dev.get_info(RS2_CAMERA_INFO_SERIAL_NUMBER));
printf("serial_number: %s\n",serial_number);
///设置从设备管道获取的深度图和彩色图的配置对象
rs2::config cfg;
///配置彩色图像流:分辨率640*480,图像格式:BGR, 帧率:30帧/秒
///默认配置任意一个设备,若要配置指定的设备可以根据设备在设备列表里的序列号进行制定:
///int indx = 0; ///表示第0个设备
///cfg.enable_stream(RS2_STREAM_COLOR,indx, 640, 480, RS2_FORMAT_BGR8, 30);
cfg.enable_stream(RS2_STREAM_COLOR,640, 480, RS2_FORMAT_BGR8, 30);
///配置深度图像流:分辨率640*480,图像格式:Z16, 帧率:30帧/秒
cfg.enable_stream(RS2_STREAM_DEPTH, 640, 480, RS2_FORMAT_Z16, 30);
///生成Realsense管道,用来封装实际的相机设备
rs2::pipeline pipe;
pipe.start(cfg); ///根据给定的配置启动相机管道
rs2::frameset data;
data = pipe.wait_for_frames();///等待一帧数据,默认等待5s
rs2::depth_frame depth = data.get_depth_frame(); ///获取深度图像数据
rs2::video_frame color = data.get_color_frame(); ///获取彩色图像数据
rs2::stream_profile dprofile = depth.get_profile();
rs2::stream_profile cprofile = color.get_profile();
///获取彩色相机内参
rs2::video_stream_profile cvsprofile(cprofile);
rs2_intrinsics color_intrin = cvsprofile.get_intrinsics();
std::cout<<"\ncolor intrinsics: ";
std::cout<<color_intrin.width<<" "<<color_intrin.height<<" ";
std::cout<<color_intrin.ppx<<" "<<color_intrin.ppy<<" ";
std::cout<<color_intrin.fx<<" "<<color_intrin.fy<<std::endl;
std::cout<<"coeffs: ";
for(auto value : color_intrin.coeffs)
std::cout<<value<<" ";
std::cout<<std::endl;
std::cout<<"distortion model: "<<color_intrin.model<<std::endl;///畸变模型
///获取深度相机内参
rs2::video_stream_profile dvsprofile(dprofile);
rs2_intrinsics depth_intrin = dvsprofile.get_intrinsics();
std::cout<<"\ndepth intrinsics: ";
std::cout<<depth_intrin.width<<" "<<depth_intrin.height<<" ";
std::cout<<depth_intrin.ppx<<" "<<depth_intrin.ppy<<" ";
std::cout<<depth_intrin.fx<<" "<<depth_intrin.fy<<std::endl;
std::cout<<"coeffs: ";
for(auto value : depth_intrin.coeffs)
std::cout<<value<<" ";
std::cout<<std::endl;
std::cout<<"distortion model: "<<depth_intrin.model<<std::endl;///畸变模型
///获取深度相机相对于彩色相机的外参,即变换矩阵: P_color = R * P_depth + T
rs2_extrinsics extrin = dprofile.get_extrinsics_to(cprofile);
std::cout<<"\nextrinsics of depth camera to color camera: \nrotaion: "<<std::endl;
for(int i = 0; i < 3; ++i)
{
for(int j = 0; j < 3; ++j)
{
float value = extrin.rotation[3*i + j];
std::cout<<value<<" ";
}
std::cout<<std::endl;
}
std::cout<<std::endl;
std::cout<<"translation: ";
for(auto value : extrin.translation)
std::cout<<value<<" ";
std::cout<<std::endl;
while(1)
{
///等待一帧数据,默认等待5s
data = pipe.wait_for_frames();
rs2::depth_frame depth = data.get_depth_frame(); ///获取深度图像数据
rs2::video_frame color = data.get_color_frame(); ///获取彩色图像数据
int color_width = color.get_width();
int color_height = color.get_height();
int depth_width = depth.get_width();
int depth_height = depth.get_height();
if (!color || !depth) break; ///如果获取不到数据则退出
///将彩色图像和深度图像转换为Opencv格式
cv::Mat image(cv::Size(color_width, color_height), CV_8UC3, (void*)color.get_data(), cv::Mat::AUTO_STEP);
cv::Mat depthmat(cv::Size(depth_width, depth_height), CV_16U, (void*)depth.get_data(), cv::Mat::AUTO_STEP);
///显示
cv::imshow("image",image);
cv::imshow("depth",depthmat);
cv::waitKey(1);
}
return EXIT_SUCCESS;
}
catch (const rs2::error & e)
{
///捕获相机设备的异常
std::cerr << "RealSense error calling " << e.get_failed_function() << "(" << e.get_failed_args() << "):\n " << e.what() << std::endl;
return EXIT_FAILURE;
}
catch (const std::exception& e)
{
std::cerr<<"Other error : " << e.what() << std::endl;
return EXIT_FAILURE;
}
这个代码是我的这台TX2上以前的代码,估计也是从官网上下下来的。我不对这个函数功能做解释了。
我们进入build目录下并打开终端。
执行cmake …和make之后生成了realsense这个可执行文件。
最后执行,输入./realsense
会出现两幅图像,一直在动的,一个彩色图,一个深度图。
总结:
TX2在刷机之后,有些远古教程其实不并使用了,蛮繁琐的,其实中文互联网有用并且新颖的东西太少了,不如外网(@。@)。本人在搞TX2的时候配置环境把我配死了,每天都很忧伤(发发牢骚)。
好了,本文完结。希望帮到有缘人。为中文技术圈贡献自己的一份力。