1. cv::triangulatePoints
cv::triangulatePoints
是 OpenCV 中用于三角测量的函数,用于从两个视角的图像点计算出对应的三维空间点。这在立体视觉和计算机视觉中非常有用,尤其是在从多视角图像中恢复三维结构时。
函数声明
cpp
void cv::triangulatePoints(
const cv::Mat& projMatrix1,
const cv::Mat& projMatrix2,
const cv::Mat& projPoints1,
const cv::Mat& projPoints2,
cv::Mat& points4D
);
参数解释
projMatrix1
: 第一个视角的投影矩阵(3x4),描述了从三维空间到第一视角图像的映射关系。可以通过相机内参和外参来构造。projMatrix2
: 第二个视角的投影矩阵(3x4),描述了从三维空间到第二视角图像的映射关系。projPoints1
: 第一个视角图像中的点坐标集合,类型通常为cv::Mat
,每个点为一个 2D 坐标。大小为2xN
,N 为点的数量。projPoints2
: 第二个视角图像中的点坐标集合,类型与projPoints1
相同,大小也为2xN
。points4D
: 输出的四维点集合,类型为cv::Mat
。每个点表示为四维齐次坐标(X, Y, Z, W)
,其中W
通常是 1。大小为4xN
,N 为点的数量。
使用示例
以下是一个使用 cv::triangulatePoints
的示例:
cpp
#include <opencv2/opencv.hpp>
int main() {
// 第一个视角的投影矩阵(示例值)
cv::Mat projMatrix1 = (cv::Mat_<double>(3, 4) <<
1000, 0, 320, 0,
0, 1000, 240, 0,
0, 0, 1, 0);
// 第二个视角的投影矩阵(示例值)
cv::Mat projMatrix2 = (cv::Mat_<double>(3, 4) <<
1000, 0, 320, -100,
0, 1000, 240, 0,
0, 0, 1, 0);
// 第一个视角中的点
cv::Mat projPoints1 = (cv::Mat_<double>(2, 2) <<
100, 150,
200, 250);
// 第二个视角中的点
cv::Mat projPoints2 = (cv::Mat_<double>(2, 2) <<
110, 160,
210, 260);
// 输出的四维点
cv::Mat points4D;
// 执行三角测量
cv::triangulatePoints(projMatrix1, projMatrix2, projPoints1, projPoints2, points4D);
// 打印三维点
for (int i = 0; i < points4D.cols; ++i) {
cv::Mat point = points4D.col(i);
double X = point.at<double>(0) / point.at<double>(3);
double Y = point.at<double>(1) / point.at<double>(3);
double Z = point.at<double>(2) / point.at<double>(3);
std::cout << "3D Point: (" << X << ", " << Y << ", " << Z << ")\n";
}
return 0;
}
使用细节
- 投影矩阵 :
projMatrix1
和projMatrix2
是 3x4 的矩阵,通常由相机的内参矩阵和外参矩阵组合得到。它们表示从三维空间到两个视角图像的映射关系。 - 点的格式 :
projPoints1
和projPoints2
必须是相同大小的点集合,每个点都是二维坐标(x, y)
。 - 四维点 :
points4D
输出的点是四维齐次坐标,其中最后一维W
通常是 1。计算实际的三维点坐标时,需要将齐次坐标除以W
。
2. 由K[R|t] 得到映射矩阵P
要将相机投影矩阵 P P P写成 K [ R ∣ t ] \mathbf{K}[\mathbf{R} | \mathbf{t}] K[R∣t]的形式,并将其变换为一个 3 × 4 3 \times 4 3×4的矩阵,我们需要分别处理相机的内参矩阵 K \mathbf{K} K和外参矩阵 [ R ∣ t ] [\mathbf{R} | \mathbf{t}] [R∣t]。
1. 相机内参矩阵 K \mathbf{K} K
相机内参矩阵 K \mathbf{K} K是一个 3 × 3 3 \times 3 3×3的矩阵,描述相机的内部参数:
K = [ f x 0 c x 0 f y c y 0 0 1 ] \mathbf{K} = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} K= fx000fy0cxcy1
其中:
- f x f_x fx和 f y f_y fy是焦距,单位通常是像素。
- c x c_x cx和 c y c_y cy是主点(光心)的坐标。
2. 相机外参矩阵 [ R ∣ t ] [\mathbf{R} | \mathbf{t}] [R∣t]
相机外参矩阵由旋转矩阵 R \mathbf{R} R和平移向量 t \mathbf{t} t组成,它是一个 3 × 4 3 \times 4 3×4的矩阵:
- 旋转矩阵 R \mathbf{R} R 是一个 3 × 3 3 \times 3 3×3的矩阵,用于将三维点从世界坐标系旋转到相机坐标系:
R = [ R 11 R 12 R 13 R 21 R 22 R 23 R 31 R 32 R 33 ] \mathbf{R} = \begin{bmatrix} R_{11} & R_{12} & R_{13} \\ R_{21} & R_{22} & R_{23} \\ R_{31} & R_{32} & R_{33} \end{bmatrix} R= R11R21R31R12R22R32R13R23R33
- 平移向量 t \mathbf{t} t 是一个 3 × 1 3 \times 1 3×1的向量,用于将旋转后的点从世界坐标系平移到相机坐标系:
t = [ t x t y t z ] \mathbf{t} = \begin{bmatrix} t_x \\ t_y \\ t_z \end{bmatrix} t= txtytz
- 组合外参矩阵 :将 R \mathbf{R} R和 t \mathbf{t} t组合为一个 3 × 4 3 \times 4 3×4的矩阵:
[ R ∣ t ] = [ R 11 R 12 R 13 t x R 21 R 22 R 23 t y R 31 R 32 R 33 t z ] [\mathbf{R} | \mathbf{t}] = \begin{bmatrix} R_{11} & R_{12} & R_{13} & t_x \\ R_{21} & R_{22} & R_{23} & t_y \\ R_{31} & R_{32} & R_{33} & t_z \end{bmatrix} [R∣t]= R11R21R31R12R22R32R13R23R33txtytz
3. 组合内参和外参矩阵
相机投影矩阵 P P P是内参矩阵 K \mathbf{K} K和外参矩阵 [ R ∣ t ] [\mathbf{R} | \mathbf{t}] [R∣t]的乘积,结果是一个 3 × 4 3 \times 4 3×4的矩阵:
P = K [ R ∣ t ] \mathbf{P} = \mathbf{K}[\mathbf{R} | \mathbf{t}] P=K[R∣t]
将它们进行矩阵乘法:
P = [ f x 0 c x 0 f y c y 0 0 1 ] [ R 11 R 12 R 13 t x R 21 R 22 R 23 t y R 31 R 32 R 33 t z ] \mathbf{P} = \begin{bmatrix} f_x & 0 & c_x \\ 0 & f_y & c_y \\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} R_{11} & R_{12} & R_{13} & t_x \\ R_{21} & R_{22} & R_{23} & t_y \\ R_{31} & R_{32} & R_{33} & t_z \end{bmatrix} P= fx000fy0cxcy1 R11R21R31R12R22R32R13R23R33txtytz
通过矩阵乘法,可以得到:
P = [ f x R 11 + c x R 31 f x R 12 + c x R 32 f x R 13 + c x R 33 f x t x + c x t z f y R 21 + c y R 31 f y R 22 + c y R 32 f y R 23 + c y R 33 f y t y + c y t z R 31 R 32 R 33 t z ] \mathbf{P} = \begin{bmatrix} f_x R_{11} + c_x R_{31} & f_x R_{12} + c_x R_{32} & f_x R_{13} + c_x R_{33} & f_x t_x + c_x t_z \\ f_y R_{21} + c_y R_{31} & f_y R_{22} + c_y R_{32} & f_y R_{23} + c_y R_{33} & f_y t_y + c_y t_z \\ R_{31} & R_{32} & R_{33} & t_z \end{bmatrix} P= fxR11+cxR31fyR21+cyR31R31fxR12+cxR32fyR22+cyR32R32fxR13+cxR33fyR23+cyR33R33fxtx+cxtzfyty+cytztz
解释
- 第一行 :表示在 x 方向的投影,结合了 x 焦距 f x f_x fx、主点 c x c_x cx,以及旋转和平移的影响。
- 第二行 :表示在 y 方向的投影,结合了 y 焦距 f y f_y fy、主点 c y c_y cy,以及旋转和平移的影响。
- 第三行:用于齐次坐标的归一化。
总结
通过内参矩阵和外参矩阵的组合,我们得到了用于描述三维点到二维图像平面投影的投影矩阵 P \mathbf{P} P。这个矩阵在多视图几何和计算机视觉的应用中至关重要,特别是在三维重建和相机校准中。