小白,啥也不懂,本文仅自己的测试记录。
计划复现SFA3D项目:GitHub - maudzung/SFA3D at ea0222c1b35489dc35d8452c989c4b014e20e0da
如果只record点云数据的话会有点抽象,所以想在至少在测试阶段能有个相机看一下投影结果。
目录
相机:海康威视 USB摄像机 DS-E14 (自己毕设已经没有经费了,所以是问其他项目组的同学借的,谢谢大佬们)
电脑:Ubuntu20.04 + ROS1 Noetic
参考:ROS:使用usb_cam软件包调试usb摄像头_169video4linux: frame mapping timeout (11)36516946-CSDN博客
0. 启动roscore
不管咋样,roscore启动了总没错。新建一个的终端执行后续指令。
$ roscore
1. 安装usb_cam
在noetic系统中用以下命令安装。
$ sudo apt install ros-noetic-usb-cam
2. 确认摄像头设备节点
一般默认是/dev/video0,但是由于我同时还想连其他设备,所以使用了拓展坞。这导致launch需要修改。
当没有插入USB相机时:
$ ls /dev/video*
/dev/video0 /dev/video1 /dev/video2 /dev/video3
当插入USB相机时:
$ ls /dev/video*
/dev/video0 /dev/video1 /dev/video2 /dev/video3 /dev/video4 /dev/video5
由此推测我的USB摄像头节点是 /dev/video4。下一步修改launch文件的第3行(<param name="video_device" value="/dev/video4" />)。记性差怕操作失误的可以先备份一次原文件(比如我)。
$ roscd usb_cam
$ sudo gedit launch/usb_cam-test.launch
3. 测试是否连接成功:
下指令输入后,会自动弹出一个相机窗口,就说明成功连上了。但是终端上会报错,提示缺少校准配置文件。新建一个的终端执行后续指令。
$ roslaunch usb_cam usb_cam-test.launch
如果没有,先试一下cheese指令能不能有图像出来。如果cheese都没有,就说明是USB没连接好,或者相机坏了。
$ cheese
如果还没解决问题,再考虑是不是第2步有问题。
4. 相机内参校准
以前好像参考的是:https://github.com/Livox-SDK/livox_camera_lidar_calibration/blob/master/doc_resources/README_cn.md
但是记忆里他没有运行成功。。。所以这次干脆换个更方便的方法。
额外参考:ROS摄像头标定_ros官方提供了用于双目和单目摄像头标定的功能包—camera_calibration-CSDN博客
Ubuntu20.04 ROS及摄像头的使用记录_ubundu20.04 ros录制视频-CSDN博客
4.1 安装校准包
$ sudo apt install ros-noetic-camera-calibration
4.2 打印校准棋盘
上面Livox的网址能下载到无水印的。这里也放一个10*7的棋盘。
4.3 启动校准节点命令
10*7的棋盘,用8*6的size能增大识别容错率。
$ rosrun camera_calibration cameracalibrator.py --size 8x6 --square 0.024 image:=/usb_cam/image_raw camera:=/usb_cam
上下(Y)左右(X)前后(Size)倾斜(Skew),反正多换换棋盘的位置,移动速度慢一点,让calibrator采集数据。出现下图彩色的点和线,就说明一次数据采集成功。具体信息在终端上也会打印出来。
直到右上角的4个标准进度条都变成绿色了以后,就可以点击右边亮起的CALIBRATE按键,等待内参计算结果。(根据电脑性能不同,计算时间不同。我电脑差,sample数量到80以上就宕机算不出来了)
计算结束后,点击亮起的SAVE按键保存校准信息。储存地址会打印在终端上:
/tmp/calibrationdata.tar.gz
4.4 添加相机校准配置文件
依次执行以下指令:
# 移动到压缩包所在文件夹
$ cd /tmp
# 新建一个你用来存放解压文件的地址,如1_calibration
$ mkdir ~/1_calibration
# 移动压缩包到目标解压地址
$ mv calibratondata.tar.gz ~/1_calibration
# 解压
$ tar xzf calibrationdata.tar.gz
# 重命名 ost.txt -> ost.ini
$ mv ost.txt ost.ini
# 抓取ost.ini文件里的关键信息转换到head_camera.yaml
$ rosrun camera_calibration_parsers convert ost.ini head_camera.yaml
# 新建camera_info文件夹(有可能已存在)
$ mkdir ~/.ros/camera_info
# 把head_camera.yaml移动到目标目录
$ mv head_camera.yaml ~/.ros/camera_info
# 修改yaml文件中第3行的camera_name参数
$ sudo gedit ~/.ros/camera_info/head_camera.yaml
这时,重新执行这个指令,就不会有校准缺失的警告信息了。
$ roslaunch usb_cam usb_cam-test.launch
5. rosbag 录制
首先确认有几个topic
$ rostopic list
其中如果药用rqt来可视化录制的bag,则record的时候必须包含/usb_cam/image_raw/compressed。但是我并不需要这个,所以我只录制/usb_cam/image_raw。前者指的是压缩后的输出,后者则是原相机输出。
$ rosbag record /usb_cam/image_raw
# 如果你要用rqt来可视化
$ rosbag record /usb_cam/image_raw /usb_cam/image_raw/compressed
停止录制是ctrl+c。
6. rosbag 解包 png
参考:rosbag录制数据与解包_rosbag record -o-CSDN博客
我需要提取出bag中的图像做投影处理。
原文中有depth相关的内容,我删除了。用的时候记得修改储存地址,bag地址,和topic。
# coding:utf-8
#!/usr/bin/python
# Extract images from a bag file.
#PKG = 'beginner_tutorials'
import roslib; #roslib.load_manifest(PKG)
import rosbag
import rospy
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
from cv_bridge import CvBridgeError
# Reading bag filename from command line or roslaunch parameter.
#import os
#import sys
rgb_path = '/home/2_cam/img/' #已经建立好的存储rgb彩色图文件的目录
class ImageCreator():
def __init__(self):
self.bridge = CvBridge()
with rosbag.Bag('/home/2_cam/2024-03-20-17-53-34.bag', 'r') as bag: #要读取的bag文件;
for topic,msg,t in bag.read_messages():
if topic == "/usb_cam/image_raw": #图像的topic;
try:
cv_image = self.bridge.imgmsg_to_cv2(msg,"bgr8")
except CvBridgeError as e:
print (e)
timestr = "%.6f" % msg.header.stamp.to_sec()
#%.6f表示小数点后带有6位,可根据精确度需要修改;
image_name = timestr+ ".png" #图像命名:时间戳.png
print(image_name) #查看输出文件,可注释掉
cv2.imwrite(rgb_path + image_name, cv_image) #保存;
if __name__ == '__main__':
#rospy.init_node(PKG)
try:
image_creator = ImageCreator()
except rospy.ROSInterruptException:
pass
$ python3 bag2img.py
不过这有个问题啊,我希望能10hz提取,但是这个脚本并没有设定。以后再说。