激光和相机的标定

一、手动标定

代码工程:GitHub - Livox-SDK/livox_camera_lidar_calibration: Calibrate the extrinsic parameters between Livox LiDAR and camera

        这是Livox提供的手动校准Livox雷达和相机之间外参的方法,并在Mid-40,Horizon和Tele-15上进行了验证。其中包含了计算相机内参,获得标定数据,优化计算外参和雷达相机融合应用相关的代码。本方案中使用了标定板角点作为标定目标物,由于Livox雷达非重复性扫描的特点,点云的密度较大,比较易于找到雷达点云中角点的准确位置。相机雷达的标定和融合也可以得到不错的结果。

1.1 环境配置

我的基础环境为 ubuntu20.04   ros neotic pcl 1.10 提前还需要装好 Eigen  Ceres

# install Livox_SDK
git clone https://github.com/Livox-SDK/Livox-SDK.git
cd Livox-SDK
sudo ./third_party/apr/apr_build.sh
cd build && cmake ..
make
sudo make install

# install livox_ros_driver
cd ..
git clone https://github.com/Livox-SDK/livox_ros_driver.git ws_livox/src
cd ws_livox
catkin_make

# install camera/lidar calibration package
cd src
git clone https://github.com/Livox-SDK/livox_camera_lidar_calibration.git
cd ..
catkin_make
source devel/setup.bash

编译过程中遇到的问题:

 /usr/include/pcl-1.10/pcl/point_types.h: In function ‘const pcl::CPPFSignature& pcl::common::operator-=(pcl::CPPFSignature&, const float&)’:
/usr/include/pcl-1.10/pcl/point_types.h:574:1: error: ‘minusscalar’ is not a member of ‘pcl::traits’
  574 | POINT_CLOUD_REGISTER_POINT_STRUCT (pcl::CPPFSignature,
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/pcl-1.10/pcl/point_types.h:574:1: error: ‘minusscalar’ is not a member of ‘pcl::traits’
  574 | POINT_CLOUD_REGISTER_POINT_STRUCT (pcl::CPPFSignature,
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/pcl-1.10/pcl/point_types.h:574:1: error: ‘minusscalar’ is not a member of ‘pcl::traits’
  574 | POINT_CLOUD_REGISTER_POINT_STRUCT (pcl::CPPFSignature,
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/pcl-1.10/pcl/point_types.h:574:1: error: ‘minusscalar’ is not a member of ‘pcl::traits’
  574 | POINT_CLOUD_REGISTER_POINT_STRUCT (pcl::CPPFSignature,

解决办法:修改编译文件,将和c++11的位置进行修改

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -O3")

cmake_minimum_required(VERSION 2.8.3)
project(camera_lidar_calibration)

## Compile as C++11, supported in ROS Kinetic and newer
# add_compile_options(-std=c++11)
set(CMAKE_BUILD_TYPE "Release")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
#set(CMAKE_CXX_FLAGS "-std=c++11")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wall -g")
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  pcl_conversions
  pcl_ros
  cv_bridge
)

find_package(PCL 1.10 REQUIRED)
find_package(OpenCV)
find_package(Threads)
find_package(Ceres REQUIRED)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)

list(REMOVE_ITEM PCL_LIBRARIES "vtkproj4")

catkin_package(
 CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
)

###########
## Build ##
###########

## Specify additional locations of header files
## Your package locations should be listed before other locations
include_directories(
# include
  ${catkin_INCLUDE_DIRS}
  ${PCL_INCLUDE_DIRS}
  ${OpenCV_INCLUDE_DIRS}
)

add_executable(cameraCalib src/cameraCalib.cpp)
target_link_libraries(cameraCalib ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})

add_executable(pcdTransfer src/pcdTransfer.cpp src/common.h)
target_link_libraries(pcdTransfer ${catkin_LIBRARIES} ${PCL_LIBRARIES})

add_executable(cornerPhoto src/corner_photo.cpp src/common.h)
target_link_libraries(cornerPhoto ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})


add_executable(getExt1 src/cam_lid_external1.cpp src/common.h)
target_link_libraries(getExt1 ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${CERES_LIBRARIES})

add_executable(getExt2 src/cam_lid_external2.cpp src/common.h)
target_link_libraries(getExt2 ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${CERES_LIBRARIES})


add_executable(projectCloud src/projectCloud.cpp src/common.h)
target_link_libraries(projectCloud ${catkin_LIBRARIES} ${OpenCV_LIBRARIES})

add_executable(colorLidar src/color_lidar_display.cpp src/common.h)
target_link_libraries(colorLidar ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${CERES_LIBRARIES})


作者使用的硬件设备为:

1.2 执行标定

1)相机内参标定

将拍摄了标定板的相机的图像,放在data/camera/photos下,然后在data/camera/in.txt中写入所有需要使用的照片名称。可以使用以下的代码实现:

"""
#-*-coding:utf-8-*- 
# @author: wangyu a beginner programmer, striving to be the strongest.
# @date: 2022/7/7 20:25
"""
import os

# 文件夹路径
img_path = r'/home/nvidia/calibration_ws/src/livox_camera_lidar_calibration/data/camera/photos/'
# txt 保存路径
save_txt_path = r'./in.txt'

# 读取文件夹中的所有文件
imgs = os.listdir(img_path)

# 图片名列表
names = []

# 过滤:只保留png结尾的图片
for img in imgs:
    if img.endswith(".png"):
        names.append(img)

txt = open(save_txt_path,'w')

for name in names:
    #name = name[:-4]    # 去掉后缀名.png
    txt.write(name + '\n')  # 逐行写入图片名,'\n'表示换行

txt.close()

作者使用的标定板的样子为:

我使用的标定板, 内点是行向是9点和6点,边长是20mm

修改 对应的launch文件,如下进行修改:

<?xml version="1.0" encoding="UTF-8"?>
<launch>
    <param name="camera_in_path"        value="/home/nvidia/calibration_ws/src/livox_camera_lidar_calibration/data/camera/in.txt" />  <!-- the file to contain all the photos -->
    <param name="camera_folder_path"    value="/home/nvidia/calibration_ws/src/livox_camera_lidar_calibration/data/camera/photos/" />  <!-- the file to contain all the photos -->
    <param name="result_path"           value="/home/nvidia/calibration_ws/src/livox_camera_lidar_calibration/data/camera/result.txt" />  <!-- the file to save the intrinsic data -->
    
    <param name="row_number"            type="int" value="9" />  <!-- the number of block on the row -->
    <param name="col_number"            type="int" value="6" />  <!-- the number of block on the column -->
    <param name="width"                 type="int" value="20" />  <!-- the width of each block on the chessboard(mm) -->
    <param name="height"                type="int" value="20" />  <!-- the height of each block on the chessboard(mm)-->
    
    <node pkg="camera_lidar_calibration" name="cameraCalib" type="cameraCalib" output="screen"></node>

</launch>

执行下面的语句进行标定:

roslaunch camera_lidar_calibration cameraCalib.launch

标定的结果会保存在data/camera/result.txt中,包括重投影误差,内参矩阵和畸变纠正参数。以上文件夹需要创建。

最终得到的结果如图所示: 

 

2)准备图像中的角点坐标

首先需要把步骤2得到的内参和畸变纠正参数以下图的格式保存在data/parameters/intrinsic.txt文件下 [注 4]。distortion下面对应5个畸变纠正参数,按顺序是k1和k2 (RadialDistortion),p1和p2 (TangentialDistortion),最后一个是k3,一般默认是0

 

<?xml version="1.0" encoding="UTF-8"?>
<launch>
  
    <param name="intrinsic_path"    value="/home/nvidia/calibration_ws/src/livox_camera_lidar_calibration/data/parameters/intrinsic.txt" />  <!-- intrinsic file -->
    <param name="input_photo_path"  value="/home/nvidia/LVI_ws/src/livox_camera_calib/data/frame4.png" />  <!-- photo to find the corner -->
    <param name="ouput_path"        value="/home/nvidia/calibration_ws/src/livox_camera_lidar_calibration/data/parameters/corner_photo.txt" />  <!-- file to save the photo corner -->
    <node pkg="camera_lidar_calibration" name="cornerPhoto" type="cornerPhoto" output="screen"></node>

</launch>

2)相机和激光的手动标定

查看点云的方式
roslaunch livox_ros_driver livox_lidar_rviz.launch
需要录制rosbag时输入另一个命令
roslaunch livox_ros_driver livox_lidar_msg.launch
需要注意:保存的rosbag数据格式是customMsg,后续程序中处理rosbag是对应的“livox custom msg format”格式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/10701.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ReactNative入门

React基本用法&#xff1a; react与js不同的点在于 react使用的是虚拟DOM js是真实DOM 作用&#xff1a;当有新的数据填充 可以复用之前的&#xff0c;而js需要整体重新渲染 创建虚拟DOM还可以使用jsx语法直接声明&#xff1a; 注意要用babel标签将jsx转化为js 但是建议采用j…

图解并用 C 语言实现非比较排序(计数排序、桶排序和基数排序)

目录 一、计数排序 二、桶排序 三、基数排序 一、计数排序 算法步骤&#xff1a; 找出待排序数组 arr 中的最小值和最大值&#xff08;分别用 min 和 max 表示&#xff09;。 创建一个长度为 max - min 1、元素初始值全为 0 的计数器数组 count。 扫描一遍原始数组&…

2023 年嵌入式世界的3 大趋势分析

目录 大家好&#xff0c;本文讲解了嵌入式发展的3个大趋势&#xff0c;分享给大家。 趋势#1 – Visual Studio Code Integration 趋势#2 –支持“现代”软件流程 趋势 #3 – 在设计中利用 AI 和 ML 结论 大家好&#xff0c;本文讲解了嵌入式发展的3个大趋势&#xff0c;分享…

Python圈的普罗米修斯——一套近乎完善的监控系统

文章目录前言一、怎么采集监控数据&#xff1f;二、采集的数据结构与指标类型2.1 数据结构2.2 指标类型2.3 实例概念2.4.数据可视化2.5.应用前景总结前言 普罗米修斯(Prometheus)是一个SoundCloud公司开源的监控系统。当年&#xff0c;由于SoundCloud公司生产了太多的服务&…

网络安全实战之植入后门程序

在 VMware 上建立两个虚拟机&#xff1a;win7 和 kali。 Kali&#xff1a;它是 Linux 发行版的操作系统&#xff0c;它拥有超过 300 个渗透测试工具&#xff0c;就不用自己再去找安装包&#xff0c;去安装到我们自己的电脑上了&#xff0c;毕竟自己从网上找到&#xff0c;也不…

如何把数据库中的数据显示到页面

主要内容&#xff1a;使用JDBC访问数据库中数据&#xff08;Java Web数据可视化案例&#xff09; 文章目录前期准备&#xff1a;案例&#xff1a;第一步&#xff1a;创建数据库及数据第二步&#xff1a;编写实体类第三步&#xff1a;编写Dao类第四步&#xff1a;编写Servlet代码…

springboot集成hadoop3.2.4HDFS

前言 记录springboot集成hadoop3.2.4版本&#xff0c;并且调用HDFS的相关接口&#xff0c;这里就不展示springboot工程的建立了&#xff0c;这个你们自己去建工程很多教程。 一、springboot配置文件修改 1.1 pom文件修改 <!-- hadoop依赖 --><dependency><gro…

Stable Diffusion - API和微服务开发

Stable Diffusion 是一种尖端的开源工具&#xff0c;用于从文本生成图像。 Stable Diffusion Web UI 通过 API 和交互式 UI 打开了许多这些功能。 我们将首先介绍如何使用此 API&#xff0c;然后设置一个示例&#xff0c;将其用作隐私保护微服务以从图像中删除人物。 推荐&…

一种轻量的“虚拟机”——Windows 沙盒模式

Windows 沙盒模式Windows沙盒的好处操作步骤Windows沙盒的好处 相比虚拟机和第三方的沙盒软件&#xff0c;Windows Sandbox启用后仅占用100MB硬盘空间&#xff0c;还能与物理机安全地共享部分内存空间。简单来说就是易用、免费、不卡机&#xff01; 由于要保证沙盒内的数据不…

(九)【软件设计师】计算机系统-浮点数习题

文章目录一、2009年下半年第3、4题二、2011年上半年第5题三、2012年下半年第3题四、2015年上半年第1题五、2015年下半年第3题六、2016年下半年第3题七、2018年上半年第1题八、2020年下半年第3题知识点回顾 &#xff08;八&#xff09;【软件设计师】计算机系统—浮点数一、2009…

Android13 PMS是如何启动的?

作者&#xff1a;Arthas0v0 平常使用安卓实际就是在使用各种app&#xff0c;而下载的app实际是一个apk文件。这个apk文件的安装就交给了PackageManagerService来实现。PackageManagerService的启动也是在SystemServer中。这个过程比较长需要长一点的时间来理。 SystemServer.s…

ORACLE EBS 系统架构与应用实践(一)

一、从ERP到EBS 从上世纪70年代晚期的物料需求计划MRP&#xff08;Material Requirements Planning&#xff09;到80年代的MRP II&#xff0c;再到90年代的企业资源计划ERP&#xff08;Enterprise Resource Planning&#xff09;&#xff0c;企业管理软件&#xff08;或曰应用…

u盘里的文件被自动删除了怎么办?五种数据恢复方案

u盘是我们日常生活中常常用到的一种便携式存储设备&#xff0c;可以帮助我们存储和携带大量的文件信息。但是&#xff0c;使用过程中难免会遇到一些问题&#xff0c;例如u盘会自己删除文件的情况&#xff0c;如果你遇到了这种情况&#xff0c;该怎样找回u盘自己删除的文件呢&am…

AI 芯片的简要发展历史

随着人工智能领域不断取得突破性进展。作为实现人工智能技术的重要基石&#xff0c;AI芯片拥有巨大的产业价值和战略地位。作为人工智能产业链的关键环节和硬件基础&#xff0c;AI芯片有着极高的技术研发和创新的壁垒。从芯片发展的趋势来看&#xff0c;现在仍处于AI芯片发展的…

FFMPEG: [ API ] >打开/关闭一个输入文件

它们是成对出现的. ffmpeg 把输入文件--转换成--->AVFormatContext实例 ◆ avformat_open_input() int avformat_open_input(AVFormatContext ** ps,const char * url,ff_const59 AVInputFormat * fmt,AVDictionary ** options )Open an input stream and read the header.…

分子生物学 第二章 遗传物质

文章目录第二章 遗传物质第一节 遗传物质的分子本质大多数生物体的遗传物质是DNA有些生物体的遗传物质是RNA蛋白质能否充当遗传物质第二节 核酸的结构1 DNA双螺旋结构的特征2 影响DNA双螺旋结构稳定性的因素3 DNA结构的多态性4 DNA多链结构5 DNA的超螺旋结构6 RNA的二级结构第三…

归并排序(非递归实现) 计数排序

上一期我们说了归并排序的递归是如何实现的&#xff0c;但是递归如果层次太多的话容易栈溢出&#xff0c;所以我们还需要掌握非递归的实现&#xff0c;但是我们非递归需要如何实现&#xff1f; 下面我们就来看一下非递归的实现 归并排序的非递归实现他并不需要栈队列这些东西…

day10_oop

今日内容 零、 复习昨日 一、面向对象的概念 二、面向对象编程 三、内存图 零、 复习昨日 晨考复习… 一、作业 package com.qf.homework;import java.util.Arrays;/*** --- 天道酬勤 ---** author QiuShiju* desc* ----------------* 引用数据类型的默认初始值null*/ public …

Redis数据备份与恢复

Redis数据备份与恢复 文章目录Redis数据备份与恢复1. Redis备份的方式2. RDB持久化2.1 什么是RDB&#xff1f;2.2 Fork操作2.3 save VS bgsave2.4 关于RDB备份的一些配置项2.5 RDB的备份与恢复2.6 RDB的自动触发2.7 RDB的优势与劣势3. AOF持久化3.1 什么是AOF&#xff1f;3.2 A…

ASP一个简单的网上教务系统模型的设计与实现

对于一个学校来说&#xff0c;大量教师信息&#xff0c;学生信息管理&#xff0c;学生成绩管理&#xff0c;基本数据的维护都难于通过传统的方法进行管理&#xff1a;这就迫切需要利用计算机技术来帮助学校管理者处理这些日常管理。本系统正是为了简化教学任务的管理&#xff0…