OpenCV

OpenCV 是事实上的标准开源计算机视觉库,对于 SLAM 相关工作而言,它是你日常都会用到的工具箱。它用 C++ 编写,并提供近乎完整的 Python 绑定(pip install opencv-python),因此同一套 API 既能用于快速原型开发,也能用于生产环境的前端。

对 SLAM 最重要的 OpenCV 组成部分包括:

一个最简单的 Python 特征匹配流程:

import cv2

orb = cv2.ORB_create(2000)
kp1, des1 = orb.detectAndCompute(img1, None)
kp2, des2 = orb.detectAndCompute(img2, None)

matcher = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = sorted(matcher.match(des1, des2), key=lambda m: m.distance)

pts1 = cv2.KeyPoint_convert(kp1, [m.queryIdx for m in matches])
pts2 = cv2.KeyPoint_convert(kp2, [m.trainIdx for m in matches])
E, inliers = cv2.findEssentialMat(pts1, pts2, K, method=cv2.RANSAC)
_, R, t, _ = cv2.recoverPose(E, pts1, pts2, K, mask=inliers)

继续这个流程:一旦你有了一份 3D 点地图,对新帧进行跟踪就变成了一个 PnP 问题——而这种模式(投影、匹配、solvePnPRansac、精化)本质上就是基于特征的 SLAM 跟踪线程所做的事情:

# pts3d: Nx3 map points, pts2d: Nx2 matched pixel observations
ok, rvec, tvec, inliers = cv2.solvePnPRansac(
    pts3d, pts2d, K, distCoeffs,
    reprojectionError=2.0, iterationsCount=100)
R, _ = cv2.Rodrigues(rvec)          # world-to-camera rotation
# triangulate new points from two calibrated views
P1 = K @ np.hstack([np.eye(3), np.zeros((3, 1))])
P2 = K @ np.hstack([R, tvec])
X_h = cv2.triangulatePoints(P1, P2, pts1.T, pts2.T)
X = (X_h[:3] / X_h[3]).T            # homogeneous -> Euclidean

要清楚它的局限:OpenCV 为你提供前端的基础构件,但不提供 SLAM 后端。光束法平差、位姿图和因子图都存在于 Ceres、g2o 或 GTSAM 中;OpenCV 的角色是输入图像,输出对应关系和初始位姿。

常见陷阱

对SLAM的意义

几乎每一个开源 SLAM 系统——ORB-SLAM、VINS-Mono,以及无数研究性原型——都使用 OpenCV 来处理图像、提取特征以及进行几何求解。熟练掌握它意味着你能够读懂这些代码库,并能在一个下午内搭建出一套完整的视觉里程计流程(检测、匹配、RANSAC、PnP),这正是推荐的 Level 2 练习。

相关条目