旋转不变性和局部不变性
发布时间:2025-06-24 17:49:54 作者:北方职教升学中心 阅读量:333
PnP 算法使用 3D 点和 2D 点之间的对应关系来估计相机姿态。
步骤:
检测并匹配两张图像中的特征点。SfM 算法的基本原理如下: 图像采集: 使用相机或其他成像设备从不同角度拍摄场景的图像序列。LAS 格式是一个二进制文件格式,它专门用于存储激光扫描仪数据。 代码示例:
import numpy as npfrom scipy.linalg import lstsqdef linear_triangulation(P1, P2, K1, K2, R1, R2, t1, t2): """ 线性三角化 Args: P1 (np.ndarray): 第一个相机中的特征点坐标 P2 (np.ndarray): 第二个相机中的特征点坐标 K1 (np.ndarray): 第一个相机的内参矩阵 K2 (np.ndarray): 第二个相机的内参矩阵 R1 (np.ndarray): 第一个相机的旋转矩阵 R2 (np.ndarray): 第二个相机的旋转矩阵 t1 (np.ndarray): 第一个相机的平移向量 t2 (np.ndarray): 第二个相机的平移向量 Returns: np.ndarray: 三维空间中的点坐标 """ # 将特征点投影到相机坐标系 P1_cam = np.dot(np.linalg.inv(K1), P1.T).T P2_cam = np.dot(np.linalg.inv(K2), P2.T).T # 构建齐次方程组 A = np.array([P1_cam[0] - P2_cam[0], P1_cam[1] - P2_cam[1], P1_cam[2] - P2_cam[2]]) # 求解三维点坐标 _, _, V = np.linalg.svd(A) X = V[:, -1] / V[-1, -1] return Xdef nonlinear_triangulation(P1, P2, K1, K2, R1, R2, t1, t2, max_iter=10): """ 非线性三角化 Args: P1 (np.ndarray): 第一个相机中的特征点坐标 P2 (np.ndarray): 第二个相机中的特征点坐标 K1 (np.ndarray): 第一个相机的内参矩阵 K2 (np.ndarray): 第二个相机的内参矩阵 R1 (np.ndarray): 第一个相机的旋转矩阵 R2 (np.ndarray): 第二个相机的旋转矩阵 t1 (np.ndarray): 第一个相机的平移向量 t2 (np.ndarray): 第二个相机的平移向量 max_iter (int): 最大迭代次数 Returns: np.ndarray: 三维空间中的点坐标 """ # 初始化三维点坐标 X = np.zeros(3) for _ in range(max_iter): # 计算投影误差 P1_proj = np.dot(K1, np.dot(R1, X.T) + t1.T) P2_proj = np.dot(K2, np.dot(R2, X.T) + t2.T) error = np.sum((P1 - P1_proj)**2 + (P2 - P2_proj)**2) # 计算雅可比矩阵 J = np.array([ [K1[0, 0] * R1[0, 0] + K1[0, 1] * R1[1, 0] + K1[0, 2] * R1[2, 0], K1[0, 0] * R1[0, 1] + K1[0, 1] * R1[1, 1] + K1[0, 2] * R1[2, 1], K1[0, 0] * R1[0, 2] + K1[0, 1] * R1[1, 2] + K1[0, 2] * R1[2, 2]], [K2[0, 0] * R2[0, 0] + K2[0, 1] * R2[1, 0] + K2[0, 2] * R2[2, 0], K2[0, 0] * R2[0, 1] + K2[0, 1] * R2[1, 1] + K2[0, 2] * R2[2, 1], K2[0, 0] * R2[0, 2] + K2[0, 1] * R2[1, 2] + K2[0, 2] * R2[2, 2]] ]) # 更新三维点坐标 delta_X = np.dot(np.linalg.inv(J), np.array([P1 - P1_proj, P2 - P2_proj]).T) X += delta_X.T return X
6.1 点云表示 点云是一种三维数据结构,它由一组三维点组成,每个点都有一个 x、 3. 使用最小二乘法优化三维点坐标,以最小化投影误差。本质矩阵是一个 3x3 矩阵,它描述了相机的旋转和平移。旋转不变性和局部不变性。有两种主要的点云构建算法:增量式点云构建和全局点云构建。
3.1.1 八点法 八点法是一种经典的单目相机姿态估计算法,它使用 8 个匹配的特征点来估计本质矩阵。
3.2.1 本质矩阵估计 本质矩阵估计算法使用两张图像中的匹配特征点来估计本质矩阵。
从矩阵 U 和 V 中提取旋转和平移矩阵。通过已知的相机参数和特征点的对应关系,可以计算出特征点在三维空间中的位置。 特征检测与匹配: 在图像中检测特征点并匹配它们以找到图像之间的对应关系。 使用本质矩阵计算对应点的 3D 坐标。五点法比八点法更鲁棒,因为它对噪声和外点更不敏感。它基于 FAST 角点检测算法和 BRIEF 二进制描述符。 使用奇异值分解(SVD)分解本质矩阵,得到矩阵 U、 """ # 构建矩阵 A A = np.zeros((8, 9)) for i in range(8): x1, y1 = points1[i] x2, y2 = points2[i] A[i, :] = [x1 * x2, x1 * y2, x1, y1 * x2, y1 * y2, y1, x2, y2, 1] # 使用 SVD 分解矩阵 A U, S, Vh = np.linalg.svd(A) # 从 U 和 Vh 中提取本质矩阵 E = U[:, :3] @ np.diag([1, 1, 0]) @ Vh[:3, :] # 返回本质矩阵 return E逻辑分析:
该代码块实现了八点法算法。
从矩阵 U 和 V 中提取本质矩阵 E。 代码块:
import numpy as npfrom cv2 import solvePnPdef pnp_algorithm(points3d, points2d, camera_matrix, distortion_coefficients): """ 使用 PnP 算法估计相机姿态。 使用奇异值分解(SVD)分解矩阵 A,得到矩阵 U、 使用奇异值分解(SVD)分解齐次方程组,得到矩阵 U、 3.2.2 PnP 算法 PnP 算法(Perspective-n-Point)是一种常用的双目相机姿态估计算法。
步骤:
将匹配的特征点投影到相机坐标系中,得到点 P1
和 P2
。y 和 z 坐标。 SIFT 特征检测算法的步骤如下:
构建尺度空间: import cv2# 构建尺度空间sift = cv2.SIFT_create()keypoints, descriptors = sift.detectAndCompute(image, None)
检测极值点: # 检测极值点for keypoint in keypoints: if keypoint.response > threshold: # 标记为极值点 keypoint.flag = True
精确定位极值点: # 精确定位极值点for keypoint in keypoints: if keypoint.flag: # 精确定位极值点 keypoint.pt = cv2.KeyPoint_convert(keypoint)
方向赋值: # 方向赋值for keypoint in keypoints: if keypoint.flag: # 计算梯度直方图 hist = cv2.calcHist([image], [0], None, [36], [0, 360]) # 找到最大值 max_idx = np.argmax(hist) # 赋值方向 keypoint.angle = max_idx * 10
2.1.3 ORB 特征检测 定向快速二进制鲁棒特征 (ORB) 是一种快速且鲁棒的特征检测算法。 distortion_coefficients:畸变系数。
使用 3D 点和 2D 点之间的对应关系构建一个齐次方程组。它通过在不同尺度空间中搜索极值点来识别特征点。 返回: R (3x3 np.ndarray): 旋转矩阵。 1. 基于 Python 的三维重建算法 Structure from Motion (SfM) 实现代码 第一章:SfM 算法原理 Structure from Motion (SfM) 是一种三维重建算法,它从图像序列中估计相机姿态和场景结构。
构建一个 8x9 的矩阵 A,其中每一行对应一个特征点对。 3.2 双目相机姿态估计 双目相机姿态估计使用两张图像来估计相机姿态。
4.1.2 本质矩阵的分解 本质矩阵可以分解为旋转矩阵和平移向量:
import numpy as npdef decompose_essential_matrix(E): """ 分解本质矩阵为旋转矩阵和平移向量。 参数: points3d:3D 点。
代码块:
import numpy as npfrom cv2 import findEssentialMatdef five_point_algorithm(points1, points2): """ 使用五点法估计本质矩阵。 本文还有配套的精品资源,点击获取
SIFT 特征具有尺度不变性、
6.2.1 增量式点云构建 增量式点云构建算法逐帧处理图像,并根据当前帧的相机姿态和三角化点更新点云。
3.1.2 五点法 五点法是一种更鲁棒的单目相机姿态估计算法,它使用 5 个匹配的特征点来估计本质矩阵。
5.2.2 非线性三角化 非线性三角化是一种更精确的三角化方法,它考虑了相机投影矩阵的非线性失真。
4.2.1 稠密匹配算法 稠密匹配算法使用本质矩阵来计算图像中每个像素的 3D 坐标。scikit-image等库进行三维重建。
构建一个 5x12 的矩阵 A,其中每一行对应一个特征点对。常用的单目相机姿态估计算法有八点法和五点法。 构建齐次方程组: [P1_x - P2_x, P1_y - P2_y, P1_z - P2_z] * [X, Y, Z, 1] = 0
其中 (X, Y, Z)
为三维空间中的点坐标。 """ # 构建齐次方程组 A = np.zeros((3 * len(points3d), 12)) for i in range(len(points3d)): x, y, z = points3d[i] u, v = points2d[i] A[3 * i, :] = [x, y, z, 1, 0, 0, 0, 0, -u * x, -u * y, -u * z, -u] A[3 * i + 1, :] = [0, 0, 0, 0, x, y, z, 1, -v * x, -v * y, -v * z, -v] # 使用 SVD 分解齐次方程组 U, S, Vh = np.linalg.svd(A) # 从 U 和 Vh 中提取旋转和平移矩阵 R, t = Vh[-1, :3], Vh[-1, 3:] # 返回旋转和平移矩阵 return R, t
逻辑分析:
该代码块实现了 PnP 算法。本教程适合计算机视觉和图像处理领域的初学者和爱好者。
4. 本质矩阵与双目立体匹配 4.1 本质矩阵 4.1.1 本质矩阵的性质 本质矩阵是一个 3x3 的矩阵,描述了两个相机之间的相对位姿。本教程将指导你使用Python实现SfM算法,涵盖从特征检测到点云构建的各个步骤。法线和颜色等信息。
代码块:
import numpy as npfrom cv2 import findEssentialMat, recoverPosedef essential_matrix_estimation(points1, points2): """ 使用本质矩阵估计算法估计相机姿态。 使用八点法或五点法估计本质矩阵。本质矩阵描述了相机的旋转和平移。本教程将指导你使用Python实现SfM算法,涵盖从特征检测到点云构建的各个步骤。该算法的优点是它不需要存储所有图像和点,并且可以实时构建点云。它具有以下性质: 秩为 2: 本质矩阵的秩为 2,这意味着它只有两个独立的行或列。以下介绍三种常用的特征检测算法: 2.1.1 Harris 角点检测 Harris 角点检测是一种基于局部图像梯度计算的算法。该算法的优点是它可以生成更准确和完整的点云,但它需要存储所有图像和点,并且计算成本更高。 points2d:2D 点。点云通常用于表示三维场景,例如物体、
使用奇异值分解(SVD)分解矩阵 A,得到矩阵 U、房间或环境。相机姿态估计算法可以分为单目相机姿态估计和双目相机姿态估计。 参数: points1:第一张图像中的特征点。S 和 V。 3.1 单目相机姿态估计 单目相机姿态估计使用单张图像来估计相机姿态。它通过计算图像每个像素周围的梯度变化量来识别角点。S 和 V。以下是一个半稠密匹配算法:
识别图像中的感兴趣区域。 Harris 角点检测算法的步骤如下:
计算图像每个像素的梯度: import cv2import numpy as np# 计算图像梯度Ix = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)Iy = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
计算结构张量: # 计算结构张量M = np.array([[np.sum(Ix**2), np.sum(Ix*Iy)], [np.sum(Ix*Iy), np.sum(Iy**2)]])
计算角点响应函数: # 计算角点响应函数R = np.trace(M)**2 - np.linalg.det(M)
阈值化和非极大值抑制: # 阈值化R[R < threshold] = 0# 非极大值抑制R = cv2.dilate(R, np.ones((3,3)))R = cv2.erode(R, np.ones((3,3)))
2.1.2 SIFT 特征检测 尺度不变特征变换 (SIFT) 是一种基于图像局部梯度分布的特征检测算法。它首先估计本质矩阵,然后使用 SVD 分解本质矩阵,最后从 U 和 Vh 中提取旋转和平移矩阵。 返回: 本质矩阵。 返回: 旋转和平移矩阵。
4.2.2 半稠密匹配算法 半稠密匹配算法只计算图像中感兴趣区域的 3D 坐标。 """ # 估计本质矩阵 E = eight_point_algorithm(points1, points2) # 使用 SVD 分解本质矩阵 U, S, Vh = np.linalg.svd(E) # 从 U 和 Vh 中提取旋转和平移矩阵 W = np.array([[0, -1, 0], [1, 0, 0], [0, 0, 1]]) R = U @ W @ Vh t = U[:, 2] # 返回旋转和平移矩阵 return R, t
逻辑分析:
该代码块实现了本质矩阵估计算法。
graph LRsubgraph 左相机 A[像素1] --> B[像素2] B[像素2] --> C[像素3]endsubgraph 右相机 D[像素1] --> E[像素2] E[像素2] --> F[像素3]endA --> DB --> EC --> F
5. 三角化 5.1 三角化原理 三角化是 SfM 算法中将匹配的特征点投影到三维空间中的过程。
ORB 特征检测算法的步骤如下:
FAST 角点检测: import cv2# FAST 角点检测orb = cv2.ORB_create()keypoints, descriptors = orb.detectAndCompute(image, None)
BRIEF 二进制描述符: # BRIEF 二进制描述符for keypoint in keypoints: # 计算 BRIEF 二进制描述符 descriptor = cv2.calcHist([image], [0], None, [256], [0, 256]) # 二值化 descriptor = np.where(descriptor > 128, 1, 0) # 赋值描述符 keypoint.descriptor = descriptor
3. 相机姿态估计 相机姿态估计是 SfM 算法中的关键步骤,它确定了相机在不同时刻的位置和方向。
从矩阵 U 和 V 中提取本质矩阵 E。以下是一个简单的稠密匹配算法: 对于图像中的每个像素: 计算像素在两幅图像中的对应点。本文还有配套的精品资源,点击获取
简介:结构从运动(SfM)是一种计算机视觉技术,用于从多个二维图像恢复三维场景结构。 3. 求解方程组,得到三维点坐标。
步骤:
初始化三维点坐标 (X, Y, Z)
。 t (3x1 np.ndarray): 平移向量。通过实践任务,你将掌握SfM算法的原理和实现方法,并学会使用OpenCV、 """ # 奇异值分解 U, S, Vh = np.linalg.svd(E) # 旋转矩阵 R = U @ Vh.T # 平移向量 t = U[:, 2] return R, t4.2 双目立体匹配 双目立体匹配是使用两个相机同时拍摄的图像来计算场景中点的 3D 坐标的过程。
本文还有配套的精品资源,点击获取
简介:结构从运动(SfM)是一种计算机视觉技术,用于从多个二维图像恢复三维场景结构。 参数: points1:第一张图像中的特征点。
步骤:
检测并匹配两张图像中的特征点。 步骤:
检测并匹配两张图像中的特征点。角点具有较大的梯度变化,表明图像在该区域有明显的边缘或纹理。 返回: 旋转和平移矩阵。 点云可以以不同的格式表示,最常见的格式是 PLY(Polygon File Format)和 LAS(LASer)。
5.2 三角化算法 5.2.1 线性三角化 线性三角化是一种简单的三角化方法,它假设相机投影矩阵是已知的,并且特征点在图像平面上是线性的。
行列式为 0: 本质矩阵的行列式为 0,这表明它是一个奇异矩阵。 """ # 构建矩阵 A A = np.zeros((5, 12)) for i in range(5): x1, y1 = points1[i] x2, y2 = points2[i] A[i, :] = [x1 * x2, x1 * y2, x1, y1 * x2, y1 * y2, y1, x2, y2, 1, 0, 0, 0] # 使用 SVD 分解矩阵 A U, S, Vh = np.linalg.svd(A) # 从 U 和 Vh 中提取本质矩阵 E = U[:, :3] @ np.diag([1, 1, 0]) @ Vh[:3, :] # 返回本质矩阵 return E逻辑分析:
该代码块实现了五点法算法。 points2:第二张图像中的特征点。 返回: 本质矩阵。常用的双目相机姿态估计算法有本质矩阵估计和 PnP 算法。本教程适合计算机视觉和图像处理领域的初学者和爱好者。
2. 特征检测与匹配 2.1 特征检测算法 特征检测算法旨在从图像中识别具有显著性的区域,这些区域在图像变换或噪声影响下保持稳定。
旋转矩阵: 本质矩阵的前 3 行构成一个旋转矩阵,表示两个相机之间的旋转关系。本质矩阵在双目立体匹配中起着至关重要的作用,因为它提供了两个相机之间的相对位姿信息。 代码块:
import numpy as npfrom cv2 import findEssentialMatdef eight_point_algorithm(points1, points2): """ 使用八点法估计本质矩阵。
三角化: 利用相机姿态和匹配的特征点三角化场景中点的三维坐标。 参数: E (3x3 np.ndarray): 本质矩阵。ORB 特征具有良好的旋转不变性和计算效率。它首先构建齐次方程组,然后使用 SVD 分解齐次方程组,最后从 U 和 Vh 中提取旋转和平移矩阵。 对于感兴趣区域中的每个像素: 计算像素在两幅图像中的对应点。 计算投影误差: error = (P1 - P1_proj)^2 + (P2 - P2_proj)^2
其中 P1_proj
和 P2_proj
是三维点在两个相机坐标系中的投影。
使用本质矩阵计算对应点的 3D 坐标。在 SfM 中,特征检测对于建立图像之间的对应关系至关重要。 参数: points1:第一张图像中的特征点。 从矩阵 U 和 V 中提取旋转和平移矩阵。它首先构建矩阵 A,然后使用 SVD 分解矩阵 A,最后从 U 和 Vh 中提取本质矩阵 E。PLY 格式是一个文本文件格式,它存储每个点的坐标、 points2:第二张图像中的特征点。 平移向量: 本质矩阵的最后一行是一个平移向量,表示两个相机之间的平移关系。S 和 V。 6.2 点云构建算法 点云构建算法将从 SfM 算法中估计的相机姿态和三角化点组合成一个完整的点云。
步骤:
检测并匹配两张图像中的特征点。S 和 V。 6.2.2 全局点云构建 全局点云构建算法一次性处理所有图像,并使用所有相机姿态和三角化点来构建点云。它首先构建矩阵 A,然后使用 SVD 分解矩阵 A,最后从 U 和 Vh 中提取本质矩阵 E。 points2:第二张图像中的特征点。
点云构建: 将三角化的点连接起来形成场景的点云模型。通过实践任务,你将掌握SfM算法的原理和实现方法,并学会使用OpenCV、scikit-image等库进行三维重建。 相机姿态估计: 根据匹配的特征点估计每个图像的相机姿态,包括位置和方向。 camera_matrix:相机矩阵。这可以提高计算效率,同时仍然提供准确的结果。