2d激光雷达(rplidar_s1)与双目摄像头联合标定

2023-05-16

前段时间由于项目需要使用摄像头(realsense d435i)与单线激光雷达进行融合,于是就对这两个传感器进行了标定,使用的是CamLaserCalibraTool ,这是别人开源的一个工具,使用教程如下

https://github.com/llailinn/CamLaserCalibraTool
  1. 首先安装并编译整个工具,具体方法见github中记录的方法
  2. 然后需要修改config文件夹中对应的配置文件(设置相机模型,相机与激光雷达的话题)
  3. 在摄像头时没有遇到什么问题
  4. 激光时,结果发现没办法识别到我们的标定板(识别成功会标成红色),这部分的代表在目录下的src/ 目录下的文件
cv::Vec3b color_value(0,0,255);  
  1. 重点关注这个函数,把这个函数搞懂,就明白了这个标定的原理了
AutoGetLinePts()  //提取标定板的线 原型如下
// 直接从每一帧激光的正前方开始搜索一定距离范围内的符合平面标定板形状的激光线段
    int n = points.size();  //雷达一圈的数据为720个
    //int id = n/2;   //可以设置扫描的开始点
    int id = 0.5*n; 
//        std::cout << points.at(id).transpose() <<" "<<points.at(id+1).transpose() <<std::endl;
    // 假设每个激光点之间的夹角为0.3deg,
    // step 1: 如果有激光标定板,那么激光标定板必须出现在视野的正前方 120 deg 范围内(通常相机视野也只有 120 deg),也就是左右各 60deg.
    //int delta = 60/0.3;
    int delta = 80;
    //int id_left = std::min( id + delta, n-1);
    //int id_right = std::max( id - delta , 0);
    int id_left = std::min( id + delta, n-1);
    int id_right = std::max( id - delta , 0);

    int dist_left = points.at(id_left).norm();
    int dist_right = points.at(id_right).norm();

    // 逻辑别搞复杂了。
    std::vector<LineSeg> segs;
    double dist_thre =  0.05 ; //0.05;
    int skip = 1; //3
    int currentPt = id_right;
    int nextPt = currentPt + skip;
    bool newSeg = true;
    LineSeg seg;
    //for (int i = id_right; i < id_left - skip; i += skip) {
    for (int i = 0; i < 100; i += skip) {
        Eigen::Vector3d pt = points[i];
        int col = (int)(pt.x() / z * focal + img_w/2);
        int row = (int)(- pt.y() / z * focal + img_w/2);  // -Y/Z 加了一个负号, 是为了抵消针孔投影时的倒影效果

        if(col > img_w-1 || col< 0 || row > img_w-1 || row < 0)
            continue;

        cv::Vec3b color_value(255,0,0);
        img.at<cv::Vec3b>(row, col) = color_value;

        if(newSeg)
        {
            seg.id_start = currentPt;
            seg.id_end = nextPt;
            newSeg = false;
        }

        double d1 = points.at(currentPt).head(2).norm();
        double d2 = points.at(nextPt).head(2).norm();
        double range_max = 100;
        if(d1 < range_max && d2 < range_max)    // 有效数据,  激光小于 100 m     激光肯定小于100m
        {
            if(fabs(d1-d2) < dist_thre)  //  8cm    //dist_thre
            {
                seg.id_end = nextPt;

            } else
            {
                newSeg = true;
                Eigen::Vector3d dist = points.at(seg.id_start) - points.at(seg.id_end);
                //std::cout <<"dist: "<< dist.head(2).norm() <<std::endl;
                std::cout <<"seg: "<< seg.id_end-seg.id_start <<std::endl;    
                if(dist.head(2).norm() > 0.2
                   && points.at(seg.id_start).head(2).norm() < 2
                   && points.at(seg.id_end).head(2).norm() < 2
                   && seg.id_end-seg.id_start > 30   )  //50 至少长于 20 cm, 标定板不能距离激光超过2m, 标定板上的激光点肯定多余 50 个  
                {
                    seg.dist = dist.head(2).norm();
                    segs.push_back(seg);
                }
            }

            currentPt = nextPt;        // 下一个点
            nextPt = nextPt + skip;
        } else
        {
            if(d1 > range_max)
            {
                currentPt = nextPt;        // 下一个点
            }
            nextPt = nextPt + skip;
        }
    }

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

2d激光雷达(rplidar_s1)与双目摄像头联合标定 的相关文章

  • 初学stm32建议的---实用开发板推荐

    STM32编程作为一项实操性很强的技能 xff0c 所以要多实操 初学的话 xff0c 我觉得书籍就暂时先不买吧 xff0c 先考虑入手一块STM32开发板 xff0c 然后跟着开发板的教程走 几年前 xff0c 做STM32的教程有很多家
  • 嵌入式操作系统-ucos是什么?

    一句话概括ucos系统 xff1a 一款源代码开放的 xff0c 抢占式多任务实时操作系统 其在整个嵌入式产品的架构中的角色和主要功能代码如下图所示 xff1a ucos 系统建立了用户程序和底层硬件之间沟通的渠道 通过ucos系统的管理和
  • 自学stm32,需要会到什么程度能找到一份工作?

    我是从大一就开始接触单片机 xff0c 学过很多类型的单片机 从最简单的51单片机 xff08 stc xff0c atmel intel等类型都用过 xff09 到国内现在最火的stm32 xff08 推荐正点原子 xff0c 后期很多项
  • 学习STM32的寄存器版本好还是库函数版本好

    我个人认为 xff0c 在回答这个问题之前 xff0c 你得先问清楚自己 xff0c 我学习stm32 或者再往更深的地方走 xff0c 我学习单片机 xff0c 究竟是为了什么 xff1f 你现在是处于什么状态 xff1f 你是学生还是已
  • proteus 8 打开proteus 7版本仿真文件的两个方法

    Proteus版本一直在更新 xff0c 其中常见的大版本Proteus 7 和Proteus 8兼容是有问题的 xff0c Proteus是向上兼容的 xff0c 高版本可以打开低版本的仿真 xff0c 低版本打不开高版本的 Proteu
  • stm32 单片机主要优点有哪些?

    51单片机之所以成为经典 xff0c 成为易上手的单片机主要有以下特点 xff1a 特性 xff1a 1 从内部的硬件到软件有一套完整的按位操作系统 xff0c 称作位处理器 xff0c 处理对象不是字或字节而是位 不但能对片内某些特殊功能
  • openmv入门之路

    如果你发现OpenCV函数繁多 xff01 xff01 xff01 如果你发现OpenCV配置繁琐 xff01 xff01 xff01 如果你发现自己买不起miniPC xff01 xff01 xff01 请选择OpenMV来完成你的项目吧
  • GMM(高斯混合模型)的动态背景分割

    以下是GMM xff08 高斯混合模型 xff09 的动态背景分割的实验报告以及源码 xff0c 另外用到了形态学操作与多通道的处理 xff0c 提升了实验结果的性能 一 实验名称 基于混合高斯模型的动态背景分割 二 实验目的 探索如何对W
  • OpenMv学习总结

    入门阶段 简单来说 xff0c OpenMv就是一个可编程的摄像头 xff0c 通过使用python语言 xff0c 专门用作嵌入式当中的视觉感光元件 下面将介绍Openmv使用过程中的常用知识 感光元件 感光元件即sensor模块 xff
  • 分享一下使用机智云APP控制战舰V3

    第一步 xff1a 注册机智云 xff0c 然后进入到开发者中心 xff0c 然后开始创建新产品 具体代码 xff0c 已经上传共享 设置好后点击保存 xff0c 这个时候会跳转到开发向导界面 xff0c 选择去添加数据点 我们建3个数据节
  • FreeRTOS进入函数prvStartFirstTask() 启动SVC后进入HardFault死循环

    FreeRTOS进入函数prvStartFirstTask 启动SVC后进入HardFault死循环 原因 xff1a 在初始化串口时为串口中断配置的NVIC与FreeRTOS的优先级设置冲突 解决方法 xff1a 设置USART的中断分组
  • docker修改默认存储路径

    docker修改默认存储路径 一 环境 xff1a centos7 x系统 xff0c 已经装好docker ce服务包 二 查看当前docker的存储路径 yukw 64 yfb docker info grep Dir WARNING
  • FreeRTOS变量和函数命名规则

    1 变量名 在 FreeRTOS 中 xff0c 定义变量的时候往往会把变量的类型当作前缀加在变量上 xff0c 这样的 好处是让用户一看到这个变量就知道该变量的类型 c char 型变量 s short 型变量 l long型变量 x p
  • Cannot Load Flash Programming Algorithm !错误解决方案,亲自验证过的几套方案

    当你下载程序的时候遇到Cannot Load Flash Programming Algorithm xff01 错误的时候是不是很崩溃 xff1f 按字面翻译的意思大概是编程算法不对 xff1b 一 这个问题我们一般先检查设备是否连接和编
  • 使用snprintf函数使用时注意事项

    snprintf函数 函数原型 xff1a int snprintf char str size t size const char format 简介 xff1a 将可变参数 按照format的格式格式化为字符串 xff0c 然后再将其拷
  • UCOSii中的信号量

    任务间简单通个信 xff0c A告诉B你LED亮一下 这种问题可以用信号量来处理 xff0c UCOSii中关于信号量的函数也就八个 xff0c 今天简单总结下 函数列表 CREATE A SEMAPHORE Description Thi
  • FreeRTOS中的变量,函数命名规则(u.v.x.p什么意思)

    写在前面 初学FreeRTOS时 xff0c 每次打开函数列表都一脸懵逼 xff1f 根本不知道这什么prv v ux是什么意思 xff0c 虽然平时使用也不需要知道这么多东西 xff0c 因为它不怎么影响开发 xff0c 但是理解总比疑惑
  • stm32学习之路---最小系统的介绍

    目标 xff1a stm32最小系统的了解 1 STM32最小系统组成 电源电路复位电路晶振电路下载电路 电源电路 xff1a DC IN1和POWER那是单片机的火牛接口它是5V的 xff0c 不能乱接不然会烧毁芯片 POWER1处是单片
  • 视频目标检测(video object detection)简单综述

    对目前看过的视频目标检测论文做一个简单的综述 xff0c 也欢迎大家补充一些其他遗漏掉的 xff0c 不错的视频目标检测论文 持续更新 github https github com breezelj video object detect
  • AAAI2021第一轮被拒经验分享

    AAAI第一轮悲剧了 俩5分 俩评委给的意见都挺中肯的 xff0c 主要还是创新性不过 xff0c 加基线算法比较不够 对实验结果解释不足 感觉他们对实验方法细节并没有很着重看 xff0c 更多的是宏观的评论 第一次投多少有点失望 xff0

随机推荐

  • C语言Sprintf用法

    如图 xff0c 两种简单用法 include lt iostream gt include lt stdio h gt 程序的主函数 int main char a 20 a 0 61 39 p 39 a 1 61 39 t 39 spr
  • UE4——打印函数

    输出当前类名 xff0c 注意是两个 GEngine gt AddOnScreenDebugMessage 0 30 f FColor Red FString FUNCTION 输出当前物体名 GEngine gt AddOnScreenD
  • vscode主题

    刚发现的 xff0c 代码效果比较好
  • VSCode 全局搜索正则排除不想显示的文件

    排除前 排除后 lst
  • 串口打印小数

    一般串口是打印一个8位字符 xff0c 或者打印一个数组 xff0c 如果要打印小数 xff0c 就要用到格式化输出 xff0c 把小数格式化输出到数组里面 u8 a 10 b 10 co2 61 1 001 tvoc 61 2 001 s
  • UE4——蓝图多重for循环

    1 示例 如下打印 xff0c 说明成功进行3次循环
  • C++链表

    上个简单链表 xff0c 写的有些难看 xff0c 现在更改一下 https liu endong blog csdn net article details 111934018 添加了删除尾结点 xff0c 添加了删除头结点 includ
  • 电路设计——发光二极管限流电阻

    0 序 最近在设计电路画板子了 xff0c 画完发现 xff0c 这电阻电容咋用啊我去 于是来学一下电阻和电容的使用 1 限流电阻作用 限流电阻主要是为了防止电流过大损坏器件 这里的限流其实还起到分压的作用 xff0c 比如我们单片机出来的
  • stm32cubeMX+FreeRTOS(4)—— main函数while循环

    0 发现 想在主函数中打印一下串口数据 xff0c 发现一直打印不出来 xff0c 试了下开关小灯 xff0c 发现没有进main函数的while循环 xff0c 阿西吧 xff0c 我大概要重新看一下CubeMX的rtos架构了 本来打算
  • Docker常见操作

    记录docker使用过程中的常用操作 1 xff0c 拉取镜像 docker pull image name image tag such as ubuntu 18 04 2 xff0c 列出所有镜像和容器 docker images do
  • stm32cubeMX+FreeRTOS(5)—— 串口打印

    0 序 cubeMX的FreeRtos和hal库的打印方式一样 本文基于CubeMX6 1 1版本编写 xff0c 此时CubeMX6 3 1已经无法使用此代码 xff08 2022 1 17 xff09 1 CubeMX配置串口 点一下串
  • HLK-B36 WIFI/BLE 二合一透传沙雕按键说明

    模块如下 沙雕说明如下 实际操作如下 恢复出厂设置 xff1a 插usb上电 xff0c 长按ES0 6秒以上 xff0c WIFI灯和STA灯同时灭掉然后亮起 xff0c STA开始闪烁 进入AT模式方式1 xff1a 插上USB xff
  • VScode下载安装及使用教程

    0 序 1 下载 官网下载速度特别慢 xff0c 需要用国内镜像 官网 xff1a Visual Studio Code Code Editing Redefined国内 点进去之后会过慢慢打开下载链接 xff0c 速度非常慢 跳转到这个界
  • 再探C语言链表—TypeDef Struct模式声明链表节点

    0 序 之前看到的网上的书上的都是Struct直接创建节点 我记得typedef struct是大学时候数据结构课本上用来声明链表结点的方法 xff0c 这个方法让人容易操作链表 后来书本扔了 xff0c 再买了盗版书不知道是版本问题还是什
  • STM32CubeMX(6)——Printf导致程序卡死

    0 序 换电脑 xff0c 新安装的cubemx 6 3 0 xff0c vs2019 xff0c minGW7 0 xff0c 不晓得什么原因 xff0c 可能是他们使用了安全函数printf s和scanf s xff0c 导致keil
  • 字符串链式队列入队出队

    include 34 queue h 34 include 34 stdio h 34 include 34 malloc h 34 64 brief 链式队列数据结构定义 typedef struct QueueStruct char v
  • AD21几个容易忘记的快捷键

    CTRL 43 D 打开透明模式 适合等长操作 CTRL 43 M 测量距离 SHIFT 43 R 推挤走线 D 43 K 打开层叠管理器 t 43 v 43 g 从板框选择铺铜 设置鼠标滑过显示高亮 取消自动闭合回路 xff0c 用于打多
  • C字符队列

    链式队列数据结构定义 typedef struct QueueStruct char value struct QueueStruct next queueStruct void QueueInit brief 链式队列初始化 void E
  • QT+OpenGL(1)——包含头文件

    关于智能提示建议放弃Cmake生成 xff0c 直接包含头文件 xff0c 包含方法如下 如果找不到头文件 xff0c 直接用everything搜相应文件 xff0c 再给包含进去 需要新建文件夹 xff0c 新建文件 c cpp pro
  • 2d激光雷达(rplidar_s1)与双目摄像头联合标定

    前段时间由于项目需要使用摄像头 xff08 realsense d435i xff09 与单线激光雷达进行融合 xff0c 于是就对这两个传感器进行了标定 xff0c 使用的是CamLaserCalibraTool xff0c 这是别人开源