| name | visual-slam |
| description | 视觉 SLAM 技能 - ORB-SLAM3、VINS-Fusion、RTAB-Map、ROS2 视觉里程计 |
| argument-hint | 视觉SLAM OR ORB-SLAM3 OR VINS OR visual slam |
| user-invocable | true |
视觉 SLAM 技能
视觉同步定位与地图构建
何时使用
当需要以下帮助时使用此技能:
- ORB-SLAM3 部署
- VINS-Fusion 配置
- 单目/双目/深度 SLAM
- 视觉里程计
- 地图复用
核心实现
ORB-SLAM3 ROS2 节点
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Image, CameraInfo
from nav_msgs.msg import Odometry
import numpy as np
class ORBSLAM3Node(Node):
def __init__(self):
super().__init__('orb_slam3')
self.image_sub = self.create_subscription(
Image, '/camera/image_raw', self.image_callback, 10)
self.info_sub = self.create_subscription(
CameraInfo, '/camera/camera_info', self.info_callback, 10)
self.odom_pub = self.create_publisher(Odometry, '/visual_odom', 10)
self.map_pub = self.create_publisher(PointCloud2, '/map_points', 10)
self.K = None
self.Tcw = None
def image_callback(self, msg):
cv_image = self.bridge.imgmsg_to_cv2(msg, desired_encoding='mono8')
self.Tcw = self.slam.track_monocular(cv_image, msg.header.stamp.sec)
if self.Tcw is not None:
self.publish_odom()
def info_callback(self, msg):
self.K = np.array(msg.k).reshape(3, 3)
self.slam.set_camera_params(self.K)
VINS-Fusion 配置
header:
seq: 0
stamp: 0
frame_id: world
model_configuration:
fx: 500.0
fy: 500.0
cx: 320.0
cy: 240.0
k1: 0.0
p1: 0.0
p2: 0.0
k2: 0.0
extrinsicRotation: [1, 0, 0, 0, 1, 0, 0, 0, 1]
extrinsicTranslation: [0, 0, 0]
vins_config:
max_solver_time: 0.04
max_num_iterations: 10
keyframe_parallax: 10.0
acceleration_noise: 0.001
gyroscope_noise: 0.001
accelerometer_bias: 0.0001
视觉里程计
class VisualOdometry:
def __init__(self, K):
self.K = K
self.prev_features = None
self.prev_pose = np.eye(4)
def compute_pose(self, image):
"""计算相机位姿"""
features = self.detect_features(image)
if self.prev_features is None:
self.prev_features = features
return np.eye(4)
matches = self.match_features(self.prev_features, features)
E, mask = self.compute_essential_matrix(
self.prev_features, features, matches)
R, t, mask = self.recover_pose(E, self.prev_features, features, self.K)
pose = np.eye(4)
pose[:3, :3] = R
pose[:3, 3] = t
self.prev_features = features
self.prev_pose = pose
return pose
def ():
orb = cv2.ORB_create()
kp, des = orb.detectAndCompute(image, )
{: kp, : des}
():
bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=)
matches = bf.(prev[], curr[])
matches
():
pts1 = np.float32([prev[][m.queryIdx].pt m matches])
pts2 = np.float32([curr[][m.trainIdx].pt m matches])
E, mask = cv2.findEssentialMat(pts1, pts2, .K)
E, mask
():
_, R, t, mask = cv2.recoverPose(E, pts1, pts2, K)
R, t, mask