SLAM算法与工程实践——相机篇:RealSense T265相机使用(2)

这篇具有很好参考价值的文章主要介绍了SLAM算法与工程实践——相机篇:RealSense T265相机使用(2)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

SLAM算法与工程实践系列文章

下面是SLAM算法与工程实践系列文章的总链接,本人发表这个系列的文章链接均收录于此

SLAM算法与工程实践系列文章链接


下面是专栏地址:

SLAM算法与工程实践系列专栏



前言

这个系列的文章是分享SLAM相关技术算法的学习和工程实践


SLAM算法与工程实践——相机篇:RealSense T265相机使用(2)

校正畸变

参考:

一文讲透鱼眼相机畸变矫正,及目标检测项目应用

一文讲透鱼眼相机畸变矫正,及目标检测项目应用

AVM环视系统——鱼眼相机去畸变算法

无论是单目相机还是双目相机,拍摄的图像都会存在畸变。

它们和鱼眼相机的畸变矫正原理也是一样的:核心是求解一个“好”的重映射矩阵(remap matrix)。

从而将原图中的部分像素点(或插值点)进行重新排列,“拼”成一张矩形图。

“好”是跟最终需求挂钩的,不同任务往往采用不同的矫正/变形方案。

比如:

(1)单目相机的畸变矫正

对于单目相机,为了得到相机像素坐标系和三维世界坐标系的对应关系,我们需要对相机的桶形畸变和枕形畸变进行矫正。

(2)双目相机的畸变矫正

而对于双目相机,为了做极线对齐,实现深度估计。

我们需要将两个相机,输出变换到同一个坐标系下。

张正友的棋盘标定法,通过标志物的位置坐标,估计出相机的内外参数和畸变系数,从而计算出remap matrix。该方法是目前上述两类相机,矫正效果最好的方法。

(3)鱼眼相机的矫正变形

对于鱼眼相机,主要有三种方法:棋盘标定法横向展开法经纬度法

下图是某款鱼眼相机的采集图像,而真正有效的监控区域,是内部的圆形区域。

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

棋盘标定法

棋盘矫正法的目的,是将鱼眼图“天生”的桶形畸变进行矫正。

具体效果类似于“用手对着圆形中心做挤压,把它压平”,使得真实世界中的直线,在矫正后依然是直线。

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

采用棋盘标定法进行矫正后:

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

我们发现:

① 现实世界中的直线,在鱼眼图中发生了扭曲(如鱼眼图中的蓝色和绿色曲线),矫正后变成了直线(如正方形图中的蓝色和绿色直线);

② 矫正图只占据了鱼眼图中间的一部分(如鱼眼图中的红色曲线)。

从这个矫正效果中,可以看出:棋盘标定法的缺点,是靠近圆周(外围区域)的区域,会被拉伸的很严重,视觉效果变差。

所以一般会进行切除,导致矫正后的图片只保留了原图的中间区域

基于以上特点,在实际使用中,我会把棋盘标定法,作为简单测量的前置任务(矫正图中的两点距离和真实世界中的两点距离,存在一一对应的关系)。

也可以作为鱼眼图像拼接的前置任务(真实世界中的三点共线,在拼接图中依然共线)。

横向展开法

横向展开法,主要是利用鱼眼相机的大FOV俯视拍摄的特点,来进行变形。

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

比如我们把上图中的红点,想象成一个观察者,当他身体旋转360度,看到的什么样的画面呢?

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

上图是经过横向展开法,变形后的画面。

可以看到,从原先的俯视视角变为了正视视角。

因此可以根据区域功能,进行切片,再用普通视角的检测模型,做后续任务。

但是缺点也一目了然,比如展开图的左右两侧,在真实世界中应该是连通的。

所以当有目标在鱼眼图中穿过分界线时,在展开图中该目标会从左侧消失,右侧出现(或者倒过来),看起来不是很自然。

基于以上特点,在实际使用中,我会利用鱼眼相机,覆盖面积大的特点(比如3米层高的情况下,至少覆盖100平米),在“某些场景”中取代枪机或半球机,画面展开后用正常的检测器去完成后续任务。

这里还要补充两点:

① COCO数据集上训练的人体检测器,在鱼眼图中直接使用是不会work的;

② 与棋盘标定法不同,横向展开不会损失像素,所以展开图也可以再remap回鱼眼原图

经纬度法

经纬度法主要分为两个方面:

① 经度

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

下图是鱼眼图沿着经度对齐矫正后的画面。

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

该方法与棋盘矫正法相比,没有像素损失,也不需要标定(人为设计规则求解remap matrix)。

但是缺点也很明显,它只对竖直方向(图中的蓝色线和绿色线)进行了矫正,而水平方向(红色线)依然是扭曲的。

② 纬度

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

下图是鱼眼图沿着纬度对齐矫正后的画面。

realsenset265 slam,SLAM算法与工程实践系列,算法,opencv,计算机视觉

可以看到,只对水平方向(图中的蓝色线和绿色线)进行了矫正,而竖直方向(红色线)依然是扭曲的。

基于以上特点,在实际落地中,我没有采用经纬度矫正法。

更多的是在学习和研究阶段,把它当作设计和计算remap matrix的一个作业。

接收和发布图像

参考:

ROS中C++ boost编程,类内回调函数

关于ROS在一个回调函数中处理两个订阅话题消息(多话题回调、多参数回调问题)

ROS之订阅多个话题并对其进行同步处理(多传感器融合)

同时订阅双目图像

订阅多个话题并对其进行同步处理,我这里订阅两个图像后再对图像做处理,使用同一个回调函数

在主函数中实现

利用全局变量 TimeSynchronizer

opencv官方方法:http://wiki.ros.org/action/fullsearch/message_filters?action=fullsearch&context=180&value=linkto%3A%22message_filters%22#Subscriber

#include <message_filters/subscriber.h>
   2 #include <message_filters/synchronizer.h>
   3 #include <message_filters/sync_policies/exact_time.h>
   4 #include <sensor_msgs/Image.h>
   5 #include <sensor_msgs/CameraInfo.h>
   6 
   7 using namespace sensor_msgs;
   8 using namespace message_filters;
   9 
  10 void callback(const ImageConstPtr& image, const CameraInfoConstPtr& cam_info)
  11 {
  12   // Solve all of perception here...
  13 }
  14 
  15 int main(int argc, char** argv)
  16 {
  17   ros::init(argc, argv, "vision_node");
  18 
  19   ros::NodeHandle nh;
  20   message_filters::Subscriber<Image> image_sub(nh, "image", 1);
  21   message_filters::Subscriber<CameraInfo> info_sub(nh, "camera_info", 1);
  22 
  23   typedef sync_policies::ExactTime<Image, CameraInfo> MySyncPolicy;
  24   // ExactTime takes a queue size as its constructor argument, hence MySyncPolicy(10)
  25   Synchronizer<MySyncPolicy> sync(MySyncPolicy(10), image_sub, info_sub);
  26   sync.registerCallback(boost::bind(&callback, _1, _2));
  27 
  28   ros::spin();
  29 
  30   return 0;
  31 }

我的实现

#include "UseT265Cam.h"
#include <iostream>
#include <opencv2/opencv.hpp>
#include <pcl/point_cloud.h>
#include <ros/ros.h>
#include <boost/bind.hpp>
#include <cv_bridge/cv_bridge.h>

void StereoImageCallback(const sensor_msgs::ImageConstPtr &img1_msg, const sensor_msgs::ImageConstPtr &img2_msg) {
    // 将ROS图像消息转换为OpenCV图像
    cv_bridge::CvImagePtr cv_image_left = cv_bridge::toCvCopy(img1_msg, sensor_msgs::image_encodings::MONO8);
    cv_bridge::CvImagePtr cv_image_right = cv_bridge::toCvCopy(img2_msg, sensor_msgs::image_encodings::MONO8);
    cv::Mat image_left = cv_image_left->image.clone();
    cv::Mat image_right = cv_image_right->image.clone();

    std::cout << "xxx" << std::endl;
    // 创建窗口
    cv::namedWindow("Left Raw View", cv::WINDOW_AUTOSIZE);
    cv::namedWindow("Right Raw View", cv::WINDOW_AUTOSIZE);
    // 显示图像
    cv::imshow("Left Raw View", image_left);
    cv::imshow("Right Raw View", image_right);
    cv::waitKey(1);
}


int main(int argc, char **argv) {
    // 初始化ROS节点
    ros::init(argc, argv, "t265_viewer");

    // 创建RealsenseViewer T265对象
    UseT265Cam *t265_cam = new UseT265Cam();
ros::NodeHandle nh;

message_filters::Subscriber<sensor_msgs::Image> image_sub1(nh, "/camera/fisheye1/image_raw", 1);
    message_filters::Subscriber<sensor_msgs::Image> image_sub2(nh, "/camera/fisheye2/image_raw", 1);
    message_filters::TimeSynchronizer<sensor_msgs::Image, sensor_msgs::Image> sync(image_sub1, image_sub2, 10);
    sync.registerCallback(boost::bind(&StereoImageCallback, _1, _2));
}
在类的成员函数中实现

利用类成员 message_filters::Synchronizer

在类中写函数实现一个回调函数处理多个话题信息时,需要用指针变量,如下所示,

不用指针变量我在写代码时不会进入回调函数,不知道是因为我代码写的有问题还是其他的原因,

在类的成员函数中实现接收多个话题,一定要用指针来实现

//定义变量
public:
    message_filters::Subscriber<sensor_msgs::Image> *sub_1;
    message_filters::Subscriber<sensor_msgs::Image> *sub_2;
    message_filters::Synchronizer<stereoSyncPolicy> *sync;

//类中的函数,将两个图像收到后一起处理
void UseT265Cam::subscribeStereoImage() {
    sub_1 = new message_filters::Subscriber<sensor_msgs::Image>(_nh, "/camera/fisheye1/image_raw", 10);
    sub_2 = new message_filters::Subscriber<sensor_msgs::Image>(_nh, "/camera/fisheye2/image_raw", 10);
    sync = new message_filters::Synchronizer<stereoSyncPolicy>(stereoSyncPolicy(10), *sub_1, *sub_2);
    sync->registerCallback(boost::bind(&UseT265Cam::StereoImageCallback, this, _1, _2));
}

//或者写为
typedef message_filters::sync_policies::ExactTime<sensor_msgs::Image, sensor_msgs::Image> MySyncPolicy;
    message_filters::Synchronizer<MySyncPolicy> *sync1=new message_filters::Synchronizer<MySyncPolicy>(MySyncPolicy(10),*sub_1, *sub_2);
    sync1->registerCallback(boost::bind(&UseT265Cam::StereoImageCallback, this, _1, _2));

使用Opencv库订阅T265图像

T265启动后的话题为

/camera/accel/imu_info
/camera/accel/metadata
/camera/accel/sample
/camera/fisheye1/camera_info
/camera/fisheye1/image_raw
/camera/fisheye1/image_raw/compressed
/camera/fisheye1/image_raw/compressed/parameter_descriptions
/camera/fisheye1/image_raw/compressed/parameter_updates
/camera/fisheye1/image_raw/compressedDepth
/camera/fisheye1/image_raw/compressedDepth/parameter_descriptions
/camera/fisheye1/image_raw/compressedDepth/parameter_updates
/camera/fisheye1/image_raw/theora
/camera/fisheye1/image_raw/theora/parameter_descriptions
/camera/fisheye1/image_raw/theora/parameter_updates
/camera/fisheye1/metadata
/camera/fisheye2/camera_info
/camera/fisheye2/image_raw
/camera/fisheye2/image_raw/compressed
/camera/fisheye2/image_raw/compressed/parameter_descriptions
/camera/fisheye2/image_raw/compressed/parameter_updates
/camera/fisheye2/image_raw/compressedDepth
/camera/fisheye2/image_raw/compressedDepth/parameter_descriptions
/camera/fisheye2/image_raw/compressedDepth/parameter_updates
/camera/fisheye2/image_raw/theora
/camera/fisheye2/image_raw/theora/parameter_descriptions
/camera/fisheye2/image_raw/theora/parameter_updates
/camera/fisheye2/metadata
/camera/gyro/imu_info
/camera/gyro/metadata
/camera/gyro/sample
/camera/odom/metadata
/camera/odom/sample
/camera/realsense2_camera_manager/bond
/camera/tracking_module/parameter_descriptions
/camera/tracking_module/parameter_updates

常用的有文章来源地址https://www.toymoban.com/news/detail-800338.html

/camera/fisheye1/image_raw
/camera/fisheye2/image_raw

/camera/accel/imu_info
/camera/accel/metadata
/camera/accel/sample

/camera/gyro/imu_info
/camera/gyro/metadata
/camera/gyro/sample
 #include<iostream>
#include<string>

#include <librealsense2/rs.hpp>

#include <opencv2/opencv.hpp>
#include<opencv2/core/core.hpp>
#include<opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

int main(int argc,char** argv)
{
    rs2::config cfg;

    // 使能 左右目图像数据
    cfg.enable_stream(RS2_STREAM_FISHEYE,1, RS2_FORMAT_Y8);
    cfg.enable_stream(RS2_STREAM_FISHEYE,2, RS2_FORMAT_Y8);

    // 使能 传感器的POSE和6DOF IMU数据
    cfg.enable_stream(RS2_STREAM_POSE, RS2_FORMAT_6DOF);

    rs2::pipeline pipe;
    pipe.start(cfg);

    rs2::frameset data;

    while (1)
   {
    data = pipe.wait_for_frames();
	// Get a frame from the pose stream
	auto f = data.first_or_default(RS2_STREAM_POSE);
	auto pose = f.as<rs2::pose_frame>().get_pose_data();
	
	cout<<"px: "<<pose.translation.x<<"   py: "<<pose.translation.y<<"   pz: "<<pose.translation.z<<
	"vx: "<<pose.velocity.x<<"   vy: "<<pose.velocity.y<<"   vz: "<<pose.velocity.z<<endl;
	cout<<"ax: "<<pose.acceleration.x<<"   ay: "<<pose.acceleration.y<<"   az: "<<pose.acceleration.z<<
	"gx: "<<pose.angular_velocity.x<<"   gy: "<<pose.angular_velocity.y<<"   gz: "<<pose.angular_velocity.z<<endl;

     rs2::frame image_left = data.get_fisheye_frame(1);
      rs2::frame image_right = data.get_fisheye_frame(2);

      if (!image_left || !image_right)
          break;

      cv::Mat cv_image_left(cv::Size(848, 800), CV_8U, (void*)image_left.get_data(), cv::Mat::AUTO_STEP);
      cv::Mat cv_image_right(cv::Size(848, 800), CV_8U, (void*)image_right.get_data(), cv::Mat::AUTO_STEP);

      cv::imshow("left", cv_image_left);
      cv::imshow("right", cv_image_right);
      cv::waitKey(1);
    }

    return 0;
}

到了这里,关于SLAM算法与工程实践——相机篇:RealSense T265相机使用(2)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在realsense D455相机上运行orb_slam3

    参考https://blog.csdn.net/weixin_42990464/article/details/133019718?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522171109916816777224423276%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id=171109916816777224423276biz_id=0utm_medium=distribute.pc_search_result.none-task-blog-2 blog first_rank_ecpm_v1~rank_v31_ecpm

    2024年03月26日
    浏览(56)
  • PX4实战之旅(五):利用T265实现室内定点飞行

    硬件: Intel NUC Intel Realsense T265 Pixhawk 2.4.8 软件: PX4 1.13.0 Ubuntu 20.04 Ros Neotic Mavros 视觉惯性里程计测距(VIO)是一种计算机视觉技术,用于估算3D姿态(本地位置和方向),相对于本地起始位置的移动的机体速度。 它通常用于在GPS不存在或不可靠的情况下(例如室内或在桥下

    2024年04月13日
    浏览(33)
  • Jetson Xavier NX配置全过程——D435i和T265驱动安装(三)

    Jetson Xavier NX配置全过程——系统与SDK烧录(一) Jetson Xavier NX配置全过程——安装OpenCV4.5.3(二) Jetson Xavier NX配置全过程——D435i驱动安装(三) 目录 一、安装RealSense SDK 1、RealSense SDK源码下载  2、安装依赖库 3、编译与安装 二、安装pyrealsense2 三、安装Realsense_ros 因为课题需

    2024年02月02日
    浏览(51)
  • 视觉SLAM理论到实践系列(四)——相机模型

    下面是《视觉SLAM十四讲》学习笔记的系列记录的总链接,本人发表这个系列的文章链接均收录于此 下面是专栏地址: 高翔博士的《视觉SLAM14讲》学习笔记的系列记录 相机将三维世界中的坐标点(单位为米)映射到二维图像平面(单位为像素)的过程能够用一个几何模型进行

    2024年02月04日
    浏览(37)
  • 自学SLAM(6)相机与图像实践:OpenCV处理图像与图像拼接(点云)

    如果写过SLAM14讲第一次的作业,或者看过我之前的运行ORB_SLAM2教程应该都安装过OpenCV了,如果没有安装,没关系,可以看我之前的博客,里面有如何安装OpenCV。 链接: 运行ORB-SLAM2(含OpenCV的安装) 让我们先来看一段代码,学习一下OpenCV的函数调用。 改代码中,演示了如下几

    2024年02月06日
    浏览(41)
  • 【工程实践】飞马SLAM100三维数据处理

    有兴趣的伙伴可以去参照官网信息,网址https://www.feimarobotics.com/zhcn/productDetailSlam100 官网标称: 项目 Value 激光视场角 270°×360° 绝对精度 5cm 相机分辨率 3×500万pxs 点频 320kpts/s 最大测距 120m 在SN_XXXX文件夹之下,会有三个文件,分别是数据文件夹,相机状态文件,激光雷达状态

    2024年02月13日
    浏览(38)
  • Intel Realsense D455深度相机的标定及使用(一)——安装librealsense SDK2.0以及realsense-ros

             Intel® RealSense™ SDK 2.0 的DKMS内核驱动包(librealsense2-dkms)支持Ubuntu LTS内核版本4.4、4.8、4.10、4.13、4.15、4.18、5.0、5.3、5.4。 sudo cat /proc/version         如果非上述版本,需要手动安装和修补版本,请移步官网教程:https://github.com/IntelRealSense/librealsense/blob/master

    2024年01月23日
    浏览(50)
  • 工程(十)——github代码ubuntu20.04在ROS环境运行单目和RGBD相机ORB-SLAM3稠密

    博主创建了一个科研互助群Q:772356582,欢迎大家加入讨论交流一起学习。 加稠密建图:git@github.com:huashu996/ORB_SLAM3_Dense_YOLO.git 纯净版:git@github.com:huashu996/ORB_SLAM3.git orb-slam3的整个环境配置还是比较麻烦的,先将一些坑写在前面,供大家参考和避开这些坑。 orb-slam3的配置要求

    2024年01月25日
    浏览(53)
  • Ubuntu18.04安装配置使用Intel RealSense D435i深度相机以及在ROS环境下配置

    最近因为学习开发需要,要开始接触一些视觉相关的内容,拿到了一个Inter 的D435i深度相机,记录一下在Ubuntu18环境下配置SDK 包的历程 注意 : Intel官方最新版的librealsense版本与ROS1的ROS Wrapper是 版本不一致的 ,且ROS Wrapper支持的是较低版本的SDK ,具体可以去网站查看 如果完全

    2024年02月07日
    浏览(53)
  • ORB_SLAM3启动流程以stereo_inertial_realsense_D435i为例

    概述 ORB-SLAM3 是第一个同时具备纯视觉(visual)数据处理、视觉+惯性(visual-inertial)数据处理、和构建多地图(multi-map)功能,支持单目、双目以及 RGB-D 相机,同时支持针孔相机、鱼眼相机模型的 SLAM 系统。 主要创新点: 1.在 IMU 初始化阶段引入 MAP。该初始化方法可以实时

    2024年02月12日
    浏览(48)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包