写在前面:
🌟 欢迎光临 清流君 的博客小天地,这里是我分享技术与心得的温馨角落。📝
个人主页:清流君_CSDN博客,期待与您一同探索 移动机器人 领域的无限可能。
🔍 本文系 清流君 原创之作,荣幸在CSDN首发🐒
若您觉得内容有价值,还请评论告知一声,以便更多人受益。
转载请注明出处,尊重原创,从我做起。
👍 点赞、评论、收藏,三连走一波,让我们一起养成好习惯😜
在这里,您将收获的不只是技术干货,还有思维的火花!
📚 系列专栏:【机器视觉】系列,带您深入浅出,探索机器视觉技术。🖊
愿我的分享能为您带来启迪,如有不足,敬请指正,让我们共同学习,交流进步!
🎭 人生如戏,我们并非能选择舞台和剧本,但我们可以选择如何演绎 🌟
感谢您的支持与关注,让我们一起在知识的海洋中砥砺前行~~~
引言
上一篇博客介绍了虚拟机 Ubuntu18.04
安装 USB 摄像头 ROS 驱动 usb_cam 的最新方法,本篇博客讲解如何使用 ROS 驱动的 USB 摄像头进行相机标定与 AprilTag 识别。
一、准备工作
1.1 安装 usb_cam 驱动
系统环境:Ubuntu18.04
本教程是基于 usb_cam 包读取图像,因此需要提前安装 usb_cam 驱动,参见:
【Ubuntu】虚拟机安装USB摄像头ROS驱动 usb_cam(最新方法)
1.2 安装相机标定功能包
安装 camera_calibration
功能包:
sudo apt-get install ros-melodic-camera-calibration
1.3 准备标定板和 USB 摄像头
准备一个已知尺寸的标定板,本实验使用的是 6 × 9 6\times9 6×9(列X行),边长为 1.8 c m 1.8cm 1.8cm 的棋盘标定板。
一个通过 ROS 发布图像的单目 USB 摄像头。
二、相机标定
2.1 启动摄像头驱动节点
rosrun usb_cam usb_cam_node
2.2 确定相机编号
确定使用的video_id
,使用如下命令查看:
ls /dev/video*
一般笔记本电脑自带的摄像头 id
为
0
0
0,外接的摄像头 id
为
1
1
1。然后根据需要修改usb_cam/src/usb_cam/launch/usb_cam-test.launch
里面的<param name="video_device" value="/dev/video1" />
。
尝试启动摄像头。
roslaunch usb_cam usb_cam-test.launch
但是博主这样写会报错:
… logging to /home/qingliu/.ros/log/0976c44a-7583-11ef-82de-000c293e3ad5/roslaunch-qingliu-4538.log
Checking log directory for disk usage. This may take a while.
Press Ctrl-C to interrupt
Done checking log file disk usage. Usage is <1GB.
started roslaunch server http://localhost:44077/
SUMMARY
========
PARAMETERS
- /image_view/autosize: True
- /rosdistro: melodic
- /rosversion: 1.14.13
- /usb_cam/camera_frame_id: usb_cam
- /usb_cam/color_format: yuv422p
- /usb_cam/image_height: 480
- /usb_cam/image_width: 640
- /usb_cam/io_method: mmap
- /usb_cam/pixel_format: yuyv
- /usb_cam/video_device: /dev/video1
NODES
/image_view (image_view/image_view)
usb_cam (usb_cam/usb_cam_node)
ROS_MASTER_URI=http://localhost:11311
process[usb_cam-1]: started with pid [4558]
process[image_view-2]: started with pid [4559]
[ INFO] [1726639123.930729617]: Initializing nodelet with 4 worker threads.
[ INFO] [1726639124.024001715]: Using transport “raw”
[ INFO] [1726639124.046743699]: using default calibration URL
[ INFO] [1726639124.047399791]: camera calibration URL: file:///home/qingliu/.ros/camera_info/head_camera.yaml
[ INFO] [1726639124.047502595]: Unable to open camera calibration file [/home/qingliu/.ros/camera_info/head_camera.yaml]
[ WARN] [1726639124.047555944]: Camera calibration file /home/qingliu/.ros/camera_info/head_camera.yaml not found.
[ INFO] [1726639124.047608139]: Starting ‘head_camera’ (/dev/video1) at 640x480 via mmap (yuyv) at 30 FPS
[ERROR] [1726639124.047678525]: VIDIOC_G_FMT error 22, Invalid argument
[usb_cam-1] process has died [pid 4558, exit code 1, cmd /home/qingliu/catkin_ws/devel/lib/usb_cam/usb_cam_node __name:=usb_cam __log:=/home/qingliu/.ros/log/0976c44a-7583-11ef-82de-000c293e3ad5/usb_cam-1.log].
log file: /home/qingliu/.ros/log/0976c44a-7583-11ef-82de-000c293e3ad5/usb_cam-1*.log
解决方法:
修改文件~/catkin_ws/src/usb_cam/launch/usb_cam-test.launch
<param name="video_device" value="/dev/video0" />
修改为 /dev/video0
2.3 查看启动的设备是否正确
查看启动的设备是否正确,若正确则关掉再打开驱动:
rosrun usb_cam usb_cam_node
查看图像是否发布, 列出 topic 确保相机正在通过ROS发布图像:
rostopic list
这会显示所有已发布的 topic,检查是否有 image_raw
topic。以下是本实验的相机topic:
/image_view/output
/image_view/parameter_descriptions
/image_view/parameter_updates
/usb_cam/camera_info
/usb_cam/image_raw
/usb_cam/image_raw/compressed
/usb_cam/image_raw/compressed/parameter_descriptions
/usb_cam/image_raw/compressed/parameter_updates
/usb_cam/image_raw/compressedDepth
/usb_cam/image_raw/compressedDepth/parameter_descriptions
/usb_cam/image_raw/compressedDepth/parameter_updates
/usb_cam/image_raw/theora
/usb_cam/image_raw/theora/parameter_descriptions
/usb_cam/image_raw/theora/parameter_updates
2.4 运行相机标定节点
运行 camera_calibration
标定节点:
rosrun camera_calibration cameracalibrator.py --size 5x8 --square 0.018 image:=/usb_cam/image_raw camera:=/usb_cam --no-service-check
此命令运行标定结点的python脚本,其中 :
--size 5x8
为棋盘内部角点的个数,方格几列几行(需要减 1 1 1),比如我的标定板方格是 6 × 9 6\times 9 6×9,则size
为 5 × 8 5\times 8 5×8--square 0.018
为每个棋盘格的边长,单位默认为米( m m m)
注意: 7 × 9 7\times 9 7×9 中间不能用“ ∗ * ∗”,是字母“ x x x”。
image:=/usb_cam/image_raw
为当前订阅的图像来自名为/usb_cam/image_raw
的 topiccamera:=/usb_cam
为摄像机名- 加上
--no-service-check
是因为一开始运行后出现下面的错误,参考官网加上此参数后就可正常显示。
(‘Waiting for service’, ‘/camera/set_camera_info’, ‘…’)
Service not found
此操作将打开标定窗口,如下图所示:
2.5 移动标定板或摄像头
为了达到良好的标定效果,需要在摄像机周围移动标定板,并完成以下基本需求:
- 移动标定板到画面的最左、右,最上、下方
- 移动标定板到视野的最近和最远处
- 移动标定板使其充满整个画面
- 保持标定板倾斜状态并使其移动到画面的最左、右,最上、下方
右侧四个参数的含义:
- 当标定板移动到画面的最左、右方时,此时,窗口的
X
会达到最小或满值 - 同理,
Y
指示标定板的在画面的上下位置 Size
表示标定板在视野中的距离,也可以理解为标定板离摄像头的远近Skew
为标定板在视野中的倾斜位置
每次移动之后,保持标定板不动直到窗口出现高亮提示。
直到条形变为绿色。当 CRLIBRATE
按钮亮起时,代表已经有足够的数据进行摄像头的标定,此时按下 CRLIBRATE
并等待一分钟左右,标定界面变成灰色,无法进行操作,属于正常情况。
2.6 得到标定结果
*** Added sample 1, p_x = 0.612, p_y = 0.460, p_size = 0.340, skew = 0.152
*** Added sample 2, p_x = 0.556, p_y = 0.498, p_size = 0.319, skew = 0.277
*** Added sample 3, p_x = 0.373, p_y = 0.579, p_size = 0.321, skew = 0.245
*** Added sample 4, p_x = 0.363, p_y = 0.353, p_size = 0.319, skew = 0.201
*** Added sample 5, p_x = 0.471, p_y = 0.309, p_size = 0.294, skew = 0.162
*** Added sample 6, p_x = 0.603, p_y = 0.319, p_size = 0.282, skew = 0.110
*** Added sample 7, p_x = 0.663, p_y = 0.296, p_size = 0.358, skew = 0.164
*** Added sample 8, p_x = 0.671, p_y = 0.199, p_size = 0.434, skew = 0.139
*** Added sample 9, p_x = 0.674, p_y = 0.144, p_size = 0.524, skew = 0.194
*** Added sample 10, p_x = 0.683, p_y = 0.026, p_size = 0.572, skew = 0.131
*** Added sample 11, p_x = 0.623, p_y = 0.086, p_size = 0.652, skew = 0.143
*** Added sample 12, p_x = 0.586, p_y = 0.262, p_size = 0.635, skew = 0.183
*** Added sample 13, p_x = 0.531, p_y = 0.403, p_size = 0.635, skew = 0.250
*** Added sample 14, p_x = 0.485, p_y = 0.223, p_size = 0.663, skew = 0.244
*** Added sample 15, p_x = 0.560, p_y = 0.329, p_size = 0.516, skew = 0.194
*** Added sample 16, p_x = 0.570, p_y = 0.489, p_size = 0.470, skew = 0.177
*** Added sample 17, p_x = 0.515, p_y = 0.515, p_size = 0.399, skew = 0.122
*** Added sample 18, p_x = 0.494, p_y = 0.618, p_size = 0.334, skew = 0.089
*** Added sample 19, p_x = 0.491, p_y = 0.516, p_size = 0.265, skew = 0.061
*** Added sample 20, p_x = 0.459, p_y = 0.414, p_size = 0.207, skew = 0.069
**** Calibrating ****
mono pinhole calibration…
*** Added sample 63, p_x = 0.568, p_y = 0.398, p_size = 0.252, skew = 0.181
*** Added sample 64, p_x = 0.449, p_y = 0.598, p_size = 0.242, skew = 0.006
*** Added sample 65, p_x = 0.382, p_y = 0.635, p_size = 0.218, skew = 0.080
D = [0.03868745150785007, -0.029877004108823855, -0.0007851867081518497, -0.0008866834766470662, 0.0]
K = [433.18386473568006, 0.0, 341.5023734989315, 0.0, 433.4953796121861, 244.3823670617905, 0.0, 0.0, 1.0]
R = [1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0]
P = [438.92010498046875, 0.0, 340.88175832247, 0.0, 0.0, 439.3984375, 243.95816827518865, 0.0, 0.0, 0.0, 1.0, 0.0]
None
# oST version 5.0 parameters
[image]
width 640
height 480
[narrow_stereo]
camera matrix
433.183865 0.000000 341.502373
0.000000 433.495380 244.382367
0.000000 0.000000 1.000000
distortion
0.038687 -0.029877 -0.000785 -0.000887 0.000000
rectification
1.000000 0.000000 0.000000
0.000000 1.000000 0.000000
0.000000 0.000000 1.000000
projection
438.920105 0.000000 340.881758 0.000000
0.000000 439.398438 243.958168 0.000000
0.000000 0.000000 1.000000 0.000000
其中,K为相机内参矩阵
distortion
:畸变系数矩阵camera matrix
:摄像头的内部参数矩阵distortion
:畸变系数矩阵rectification
:矫正矩阵,一般为单位阵projection
:外部世界坐标到像平面的投影矩阵
2.7 保存保定数据
点击 SAVE
按钮。
点击 COMMIT
按钮将结果保存到默认文件夹,终端输出如下信息,说明标定结果已经保存在相应文件夹下。下次启动 usb_cam 节点时,会自动调用。
(‘Wrote calibration data to’, ‘/tmp/calibrationdata.tar.gz’)
其中,ost.yaml
文件即为相机内参的标定文件。
至此,相机标定完成!
三、对焦问题
3.1 启动摄像头存在的警告
启动摄像头存在如下警告:
[ WARN] [1726642015.933315970]: unknown control ‘focus_auto’
3.2 对焦问题的可能原因
出现这个警告可能是有以下两种原因:
-
因为参数设置不匹配,默认像素的宽和高跟摄像头不匹配。
-
还有可能只是所使用的相机根本没有自动对焦功能。
因此不用管这个问题。
四、运行Apriltag_ros
4.1 安装 Apriltag 依赖
首先安装 Apriltag 依赖,从GitHub克隆项目,然后编译并安装这个项目。
使用 Git 版本控制系统从指定的GitHub仓库克隆 apriltag
项目到本地。这将创建一个名为 apriltag
的目录,其中包含该项目的所有源代码。在一个非ROS工作空间的文件里:
git clone https://github.com/AprilRobotics/apriltag.git # 这个不是ros的功能包
改变当前工作目录到刚克隆下来的 apriltag
目录:
cd apriltag
在 apriltag
目录下创建一个名为 build
的新目录,用于存放编译过程中产生的文件:
mkdir build
将当前工作目录切换到新创建的 build 目录:
cd build
运行 CMake 工具,它会读取上级目录(即 apriltag
目录)中的 CMakeLists.txt
文件,并生成适用于本机的 Makefile
和其他构建文件。..
表示 CMake 应该在其父目录中查找 CMakeLists.txt
文件:
cmake ..
使用Make工具根据 CMake 生成的 Makefile
编译项目。这将编译源代码并生成可执行文件或库:
make
以管理员权限运行 Make,并将编译好的文件安装到系统的适当位置。将可执行文件、库文件和头文件复制到系统的 bin
、lib
和 include
目录:
sudo make install
4.2 安装 Apriltag_ros 功能包
下面安装 Apriltag_ros 功能包,将源码放到工作空间路径下,如catkin_ws/src
,然后编译即可。
cd catkin_ws/src
git clone https://github.com/AprilRobotics/apriltag_ros.git
cd ..
catkin_make
4.3 修改配置文件
首先修改 ~/catkin_ws/src/apriltag_ros/apriltag_ros/launch/continuous_detection.launch
文件。
apriltag_ros 需要订阅相机图像数据与相机信息,比如对于USB摄像头,在开启相机时会发布两个相关的 topic:
/usb_cam/camera_info
/usb_cam/image_raw
因此需将 camera_name
与 camera_frame
的内容修改为订阅的 topic。
launch 文件内容修改如下:
<!-- 修改 -->
<arg name="camera_name" default="/usb_cam" />
<arg name="image_topic" default="image_raw" />
<!-- 添加 -->
<arg name="camera_frame" default="/camera" />
完整launch文件内容如下:
<launch>
<!-- set to value="gdbserver localhost:10000" for remote debugging -->
<arg name="launch_prefix" default="" />
<!-- configure camera input -->
<arg name="camera_name" default="/usb_cam" />
<arg name="image_topic" default="image_raw" />
<arg name="camera_frame" default="/camera" />
<arg name="queue_size" default="1" />
<!-- apriltag_ros continuous detection node -->
<node pkg="apriltag_ros" type="apriltag_ros_continuous_node" name="apriltag_ros_continuous_node" clear_params="true" output="screen" launch-prefix="$(arg launch_prefix)">
<!-- Remap topics from those used in code to those on the ROS network -->
<remap from="image_rect" to="$(arg camera_name)/$(arg image_topic)" />
<remap from="camera_info" to="$(arg camera_name)/camera_info" />
<param name="publish_tag_detections_image" type="bool" value="true" /><!-- default: false -->
<param name="queue_size" type="int" value="$(arg queue_size)" />
<!-- load parameters (incl. tag family, tags, etc.) -->
<rosparam command="load" file="$(find apriltag_ros)/config/settings.yaml"/>
<rosparam command="load" file="$(find apriltag_ros)/config/tags.yaml"/>
</node>
</launch>
修改 ~/catkin_ws/src/apriltag_ros/apriltag_ros/config/tags.yaml
文件,添加需要检测的二维码id
与自己测量得到的二维码尺寸大小size
(单位:米)。
standalone_tags:
[
{id: 1, size: 0.0515},
{id: 2, size: 0.0515},
{id: 3, size: 0.0515},
{id: 4, size: 0.0515},
{id: 5, size: 0.0515},
{id: 6, size: 0.0515}
]
注意:
1、同一 ID 的 Apriltag 码不能在该配置文件中以不同的大小出现两次,也不能出现在一张图片的两个地方。这些都将在检测中产生歧义。
2、确保打印的 AprilTag 码至少包含 1 1 1 位宽的白色边框,AprilTag 算法会对周围的白色边框进行采样。
4.4 运行Apriltag_ros
刷新环境变量:
source ~/catkin_ws/devel/setup.bash
分别打开四个终端,运行如下命令行:
(1) 启动 USB 相机驱动
roslaunch usb_cam usb_cam-test.launch
(2) 运行 AprilTag_ros 算法
roslaunch apriltag_ros continuous_detection.launch
(3) RViz 可视化界面
rosrun rviz rviz
(4) 输出定位数据
rostopic echo /tag_detections
正确运行识别到 AprilTag 的界面如下图所示:
输出的定位数据如下:
五、总结
本教程介绍了如何使用 ROS 进行相机标定和 Apriltag 识别。
首先,安装了 usb_cam 驱动和 camera_calibration
功能包,并准备了一个
6
×
9
6\times9
6×9 的棋盘格标定板和一个单目 USB 摄像头。
然后,启动了摄像头驱动节点,并调整了摄像头视频设备 id
,以正确地接收摄像头图像。
接下来,运行了相机标定节点,通过在摄像机周围移动标定板,完成了标定过程,并得到了相机的内参矩阵和畸变系数矩阵。
最后,安装了 Apriltag_ros
功能包,并修改了配置文件以匹配摄像头和 Apriltag 尺寸。运行了 Apriltag 识别节点,并在 RViz 中可视化了检测结果。
通过本教程,读者可掌握如何使用 ROS 进行相机标定和 Apriltag 识别,这对于机器人视觉系统至关重要。
参考资料
1、【Ubuntu】虚拟机安装USB摄像头ROS驱动 usb_cam(最新方法)
2、使用Apriltags实现定位、评估定位精度的全流程记录
3、ROS下采用camera_calibration进行单目相机标定
后记:
🌟 感谢您耐心阅读这篇关于 使用 ROS 驱动的 USB 摄像头进行相机标定与 AprilTag 识别 的技术博客。 📚
🎯 如果您觉得这篇博客对您有所帮助,请不要吝啬您的点赞和评论 📢
🌟您的支持是我继续创作的动力。同时,别忘了收藏本篇博客,以便日后随时查阅。🚀
🚗 让我们一起期待更多的技术分享,共同探索移动机器人的无限可能!💡
🎭感谢您的支持与关注,让我们一起在知识的海洋中砥砺前行 🚀