使用OpenCV进行摄像机标定

2023-05-16

Cv照相机定标和三维重建

目录

  [隐藏]
  • 1 针孔相机模型和变形
  • 2 照相机定标
    • 2.1 ProjectPoints2
    • 2.2 FindHomography
    • 2.3 CalibrateCamera2
    • 2.4 FindExtrinsicCameraParams2
    • 2.5 Rodrigues2
    • 2.6 Undistort2
    • 2.7 InitUndistortMap
    • 2.8 FindChessboardCorners
    • 2.9 DrawChessBoardCorners
  • 3 姿态估计
    • 3.1 CreatePOSITObject
    • 3.2 POSIT
    • 3.3 ReleasePOSITObject
    • 3.4 CalcImageHomography
  • 4 对极几何(双视几何)
    • 4.1 FindFundamentalMat
    • 4.2 ComputeCorrespondEpilines
    • 4.3 ConvertPointsHomogenious

[ 编辑]

针孔相机模型和变形

这一节里的函数都使用针孔摄像机模型,这就是说,一幅视图是通过透视变换将三维空间中的点投影到图像平面。投影公式如下:

s \cdot m' = A\cdot[R|t] \cdot M'或者

s\cdot  \begin{bmatrix} u \\ v \\ 1 \end{bmatrix} = \begin{bmatrix} fx & 0 & cx \\ 0 & fy & cy \\ 0 & 0 & 1 \end{bmatrix} \cdot \begin{bmatrix} r_{11} & r_{12} & r_{13} & t_{1} \\ r_{21} & r_{22} & r_{23} & t_{2} \\ r_{31} & r_{32} & r_{33} & t_{3} \end{bmatrix} \cdot \begin{bmatrix} X \\ Y \\ Z \\ 1 \end{bmatrix}

这里(X, Y, Z)是一个点的世界坐标,(u, v)是点投影在图像平面的坐标,以像素为单位。A被称作摄像机矩阵,或者内参数矩阵。(cx, cy)是基准点(通常在图像的中心),fx, fy是以像素为单位的焦距。所以如果因为某些因素对来自于摄像机的一幅图像升采样或者降采样,所有这些参数(fx, fy, cx和cy)都将被缩放(乘或者除)同样的尺度。内参数矩阵不依赖场景的视图,一旦计算出,可以被重复使用(只要焦距固定)。旋转-平移矩阵[R|t]被称作外参数矩阵,它用来描述相机相对于一个固定场景的运动,或者相反,物体围绕相机的的刚性运动。也就是[R|t]将点(X, Y, Z)的坐标变换到某个坐标系,这个坐标系相对于摄像机来说是固定不变的。上面的变换等价与下面的形式(z≠0):

\begin{bmatrix}x \\ y \\z \end{bmatrix} = R \cdot \begin{bmatrix}X \\ Y \\Z \end{bmatrix} + t

x' = x / z

y' = y / z

u=fx \cdot x' + cx

v=fy \cdot y' + cy

真正的镜头通常有一些形变,主要的变形为径向形变,也会有轻微的切向形变。所以上面的模型可以扩展为:

\begin{bmatrix}x \\ y \\z \end{bmatrix} = R \cdot \begin{bmatrix}X \\ Y \\Z \end{bmatrix} + t

x' = x / z

y' = y / z

x'' = x' \cdot (1 + k_1 \cdot r^2 + k_2 \cdot r^4) + 2 \cdot p_1 \cdot x'\cdot y' + p_2 \cdot (r^2+2x'^2)

y'' = y' \cdot (1 + k_1 \cdot r^2 + k_2 \cdot r^4) + p_1 \cdot (r^2+2 \cdot y'^2) + 2 \cdot p_2 \cdot x'\cdot y'

这里 r2 = x'2 + y'2

u = fx \cdot x'' + cx

v = fy \cdot y'' + cy

k1k2是径向形变系数,p1p1是切向形变系数。OpenCV中没有考虑高阶系数。形变系数跟拍摄的场景无关,因此它们是内参数,而且与拍摄图像的分辨率无关。

后面的函数使用上面提到的模型来做如下事情:

  • 给定内参数和外参数,投影三维点到图像平面。
  • 给定内参数、几个三维点坐标和其对应的图像坐标,来计算外参数。
  • 根据已知的定标模式,从几个角度(每个角度都有几个对应好的3D-2D点对)的照片来计算相机的外参数和内参数。
[ 编辑]

照相机定标

[ 编辑]

ProjectPoints2

投影三维点到图像平面


void cvProjectPoints2( const CvMat* object_points, const CvMat* rotation_vector,
                       const CvMat* translation_vector, const CvMat* intrinsic_matrix,
                       const CvMat* distortion_coeffs, CvMat* image_points,
                       CvMat* dpdrot=NULL, CvMat* dpdt=NULL, CvMat* dpdf=NULL,
                       CvMat* dpdc=NULL, CvMat* dpddist=NULL );
  
object_points
物体点的坐标,为3xN或者Nx3的矩阵,这儿N是视图中的所有所有点的数目。
rotation_vector
旋转向量,1x3或者3x1。
translation_vector
平移向量,1x3或者3x1。
intrinsic_matrix
摄像机内参数矩阵A: \begin{bmatrix}fx & 0 & cx\\ 0 & fy & cy\\ 0&0&1\end{bmatrix}
distortion_coeffs
形变参数向量,4x1或者1x4,为 [k1,k2,p1,p2]。如果是NULL,所有形变系数都设为0。
image_points
输出数组,存储图像点坐标。大小为2xN或者Nx2,这儿N是视图中的所有点的数目。
dpdrot
可选参数,关于旋转向量部分的图像上点的导数,Nx3矩阵。
dpdt
可选参数,关于平移向量部分的图像上点的导数,Nx3矩阵。
dpdf
可选参数,关于fx和fy的图像上点的导数,Nx2矩阵。
dpdc
可选参数,关于cx和cy的图像上点的导数,Nx2矩阵。
dpddist
可选参数,关于形变系数的图像上点的导数,Nx4矩阵。

函数cvProjectPoints2通过给定的内参数和外参数计算三维点投影到二维图像平面上的坐标。另外,这个函数可以计算关于投影参数的图像点偏导数的雅可比矩阵。雅可比矩阵可以用在cvCalibrateCamera2和cvFindExtrinsicCameraParams2函数的全局优化中。这个函数也可以用来计算内参数和外参数的反投影误差。 注意,将内参数和(或)外参数设置为特定值,这个函数可以用来计算外变换(或内变换)。

[ 编辑]

FindHomography

计算两个平面之间的透视变换


void cvFindHomography( const CvMat* src_points,
                       const CvMat* dst_points,
                       CvMat* homography );
  
src_points
原始平面的点坐标,大小为2xN,Nx2,3xN或者 Nx3矩阵(后两个表示齐次坐标),这儿N表示点的数目。
dst_points
目标平面的点坐标大小为2xN,Nx2,3xN或者 Nx3矩阵(后两个表示齐次坐标)。
homography
输出的3x3的homography矩阵。

函数cvFindHomography计算源平面和目标平面之间的透视变换H=\begin{bmatrix}h_{ij}\end{bmatrix}_{i,j}.

s_i \begin{bmatrix}x'_i \\ y'_i \\ 1\end{bmatrix}  \approx  H  \begin{bmatrix}x_i \\ y_i \\ 1\end{bmatrix}

使得反投影错误最小:

\sum_i((x'_i-\frac{h_{11}x_i + h_{12}y_i + h_{13}}{h_{31}x_i + h_{32}y_i + h_{33}})^2+          (y'_i-\frac{h_{21}x_i + h_{22}y_i + h_{23}}{h_{31}x_i + h_{32}y_i + h_{33}})^2)

这个函数可以用来计算初始的内参数和外参数矩阵。由于Homography矩阵的尺度可变,所以它被规一化使得h33 = 1

[ 编辑]

CalibrateCamera2

利用定标来计算摄像机的内参数和外参数


void cvCalibrateCamera2( const CvMat* object_points, const CvMat* image_points,
                         const CvMat* point_counts, CvSize image_size,
                         CvMat* intrinsic_matrix, CvMat* distortion_coeffs,
                         CvMat* rotation_vectors=NULL,
                         CvMat* translation_vectors=NULL,
                         int flags=0 );
  
object_points
定标点的世界坐标,为3xN或者Nx3的矩阵,这里N是所有视图中点的总数。
image_points
定标点的图像坐标,为2xN或者Nx2的矩阵,这里N是所有视图中点的总数。
point_counts
向量,指定不同视图里点的数目,1xM或者Mx1向量,M是视图数目。
image_size
图像大小,只用在初始化内参数时。
intrinsic_matrix
输出内参矩阵(A)  \begin{bmatrix}fx & 0 & cx\\ 0 & fy & cy \\ 0&0&1\end{bmatrix},如果指定CV_CALIB_USE_INTRINSIC_GUESS和(或)CV_CALIB_FIX_ASPECT_RATION,fx、 fy、 cx和cy部分或者全部必须被初始化。
distortion_coeffs
输出大小为4x1或者1x4的向量,里面为形变参数[k1, k2, p1, p2]。
rotation_vectors
输出大小为3xM或者Mx3的矩阵,里面为旋转向量(旋转矩阵的紧凑表示方式,具体参考函数cvRodrigues2)
translation_vectors
输出大小为3xM或Mx3的矩阵,里面为平移向量。
flags
不同的标志,可以是0,或者下面值的组合:
  • CV_CALIB_USE_INTRINSIC_GUESS - 内参数矩阵包含fx,fy,cx和cy的初始值。否则,(cx, cy)被初始化到图像中心(这儿用到图像大小),焦距用最小平方差方式计算得到。注意,如果内部参数已知,没有必要使用这个函数,使用cvFindExtrinsicCameraParams2则可。
  • CV_CALIB_FIX_PRINCIPAL_POINT - 主点在全局优化过程中不变,一直在中心位置或者在其他指定的位置(当CV_CALIB_USE_INTRINSIC_GUESS设置的时候)。
  • CV_CALIB_FIX_ASPECT_RATIO - 优化过程中认为fx和fy中只有一个独立变量,保持比例fx/fy不变,fx/fy的值跟内参数矩阵初始化时的值一样。在这种情况下, (fx, fy)的实际初始值或者从输入内存矩阵中读取(当CV_CALIB_USE_INTRINSIC_GUESS被指定时),或者采用估计值(后者情况中fx和fy可能被设置为任意值,只有比值被使用)。
  • CV_CALIB_ZERO_TANGENT_DIST – 切向形变参数(p1, p2)被设置为0,其值在优化过程中保持为0。

函数cvCalibrateCamera2从每个视图中估计相机的内参数和外参数。3维物体上的点和它们对应的在每个视图的2维投影必须被指定。这些可以通过使用一个已知几何形状且具有容易检测的特征点的物体来实现。这样的一个物体被称作定标设备或者定标模式,OpenCV有内建的把棋盘当作定标设备方法(参考cvFindChessboardCorners)。目前,传入初始化的内参数(当CV_CALIB_USE_INTRINSIC_GUESS不被设置时)只支持平面定标设备(物体点的Z坐标必须为全0或者全1)。不过3维定标设备依然可以用在提供初始内参数矩阵情况。在内参数和外参数矩阵的初始值都计算出之后,它们会被优化用来减小反投影误差(图像上的实际坐标跟cvProjectPoints2计算出的图像坐标的差的平方和)。

[ 编辑]

FindExtrinsicCameraParams2

计算指定视图的摄像机外参数


void cvFindExtrinsicCameraParams2( const CvMat* object_points,
                                   const CvMat* image_points,
                                   const CvMat* intrinsic_matrix,
                                   const CvMat* distortion_coeffs,
                                   CvMat* rotation_vector,
                                   CvMat* translation_vector );
  
object_points
定标点的坐标,为3xN或者Nx3的矩阵,这里N是视图中的个数。
image_points
定标点在图像内的坐标,为2xN或者Nx2的矩阵,这里N是视图中的个数。
intrinsic_matrix
内参矩阵(A)  \begin{bmatrix}fx & 0 & cx\\ 0 & fy & cy \\ 0&0&1\end{bmatrix}
distortion_coeffs
大小为4x1或者1x4的向量,里面为形变参数 [k1,k2,p1,p2]。如果是NULL,所有的形变系数都为0。
rotation_vector
输出大小为3x1或者1x3的矩阵,里面为旋转向量(旋转矩阵的紧凑表示方式,具体参考函数cvRodrigues2)。
translation_vector
大小为3x1或1x3的矩阵,里面为平移向量。

函数cvFindExtrinsicCameraParams2使用已知的内参数和某个视图的外参数来估计相机的外参数。3维物体上的点坐标和相应的2维投影必须被指定。这个函数也可以用来最小化反投影误差。

[ 编辑]

Rodrigues2

进行旋转矩阵和旋转向量间的转换


int  cvRodrigues2( const CvMat* src, CvMat* dst, CvMat* jacobian=0 );
  
src
输入的旋转向量(3x1或者1x3)或者旋转矩阵(3x3)。
dst
输出的旋转矩阵(3x3)或者旋转向量(3x1或者1x3)
jacobian
可选的输出雅可比矩阵(3x9或者9x3),关于输入部分的输出数组的偏导数。

函数转换旋转向量到旋转矩阵,或者相反。旋转向量是旋转矩阵的紧凑表示形式。旋转向量的方向是旋转轴,向量的长度是围绕旋转轴的旋转角。旋转矩阵R,与其对应的旋转向量r,通过下面公式转换:

\theta \leftarrow norm(r)

r \leftarrow r/\theta

R = \cos(\theta)I + (1-\cos(\theta))rr^T + \sin(\theta) \begin{bmatrix}0&-r_z&r_y\\ r_z&0&-r_x\\ -r_y&r_x&0\end{bmatrix}

反变换也可以很容易的通过如下公式实现:

\sin(\theta) \begin{bmatrix}0&-r_z&r_y\\ r_z&0&-r_x\\ -r_y&r_x&0\end{bmatrix} = \frac{R-R^T}{2}

旋转向量是只有3个自由度的旋转矩阵一个方便的表示,这种表示方式被用在函数cvFindExtrinsicCameraParams2和cvCalibrateCamera2内部的全局最优化中。

[ 编辑]

Undistort2

校正图像因相机镜头引起的变形


void cvUndistort2( const CvArr* src, CvArr* dst,
                   const CvMat* intrinsic_matrix,
                   const CvMat* distortion_coeffs );
  
src
原始图像(已经变形的图像)。只能变换32fC1的图像。
dst
结果图像(已经校正的图像)。
intrinsic_matrix
相机内参数矩阵,格式为  \begin{bmatrix}fx & 0 & cx\\ 0 & fy & cy\\ 0&0&1\end{bmatrix}
distortion_coeffs
四个变形系数组成的向量,大小为4x1或者1x4,格式为 [k1,k2,p1,p2]

函数cvUndistort2对图像进行变换来抵消径向和切向镜头变形。相机参数和变形参数可以通过函数cvCalibrateCamera2取得。使用本节开始时提到的公式,对每个输出图像像素计算其在输入图像中的位置,然后输出图像的像素值通过双线性插值来计算。如果图像得分辨率跟定标时用得图像分辨率不一样,fx、fy、cx和cy需要相应调整,因为形变并没有变化。

[ 编辑]

InitUndistortMap

计算形变和非形变图像的对应(map)


void cvInitUndistortMap( const CvMat* intrinsic_matrix,
                         const CvMat* distortion_coeffs,
                         CvArr* mapx, CvArr* mapy );
  
intrinsic_matrix
摄像机内参数矩阵(A) [fx 0 cx; 0 fy cy; 0 0 1].
distortion_coeffs
形变系数向量[k1, k2, p1, p2],大小为4x1或者1x4。
mapx
x坐标的对应矩阵。
mapy
y坐标的对应矩阵。

函数cvInitUndistortMap预先计算非形变对应-正确图像的每个像素在形变图像里的坐标。这个对应可以传递给cvRemap函数(跟输入和输出图像一起)。

[ 编辑]

FindChessboardCorners

寻找棋盘图的内角点位置


int cvFindChessboardCorners( const void* image, CvSize pattern_size,
                             CvPoint2D32f* corners, int* corner_count=NULL,
                             int flags=CV_CALIB_CB_ADAPTIVE_THRESH );
  
image
输入的棋盘图,必须是8位的灰度或者彩色图像。
pattern_size
棋盘图中每行和每列角点的个数。
corners
检测到的角点
corner_count
输出,角点的个数。如果不是NULL,函数将检测到的角点的个数存储于此变量。
flags
各种操作标志,可以是0或者下面值的组合:
  • CV_CALIB_CB_ADAPTIVE_THRESH - 使用自适应阈值(通过平均图像亮度计算得到)将图像转换为黑白图,而不是一个固定的阈值。
  • CV_CALIB_CB_NORMALIZE_IMAGE - 在利用固定阈值或者自适应的阈值进行二值化之前,先使用cvNormalizeHist来均衡化图像亮度。
  • CV_CALIB_CB_FILTER_QUADS - 使用其他的准则(如轮廓面积,周长,方形形状)来去除在轮廓检测阶段检测到的错误方块。

函数cvFindChessboardCorners试图确定输入图像是否是棋盘模式,并确定角点的位置。如果所有角点都被检测到且它们都被以一定顺序排布(一行一行地,每行从左到右),函数返回非零值,否则在函数不能发现所有角点或者记录它们地情况下,函数返回0。例如一个正常地棋盘图右8x8个方块和7x7个内角点,内角点是黑色方块相互联通地位置。这个函数检测到地坐标只是一个大约地值,如果要精确地确定它们的位置,可以使用函数cvFindCornerSubPix。

[ 编辑]

DrawChessBoardCorners

绘制检测到的棋盘角点


void cvDrawChessboardCorners( CvArr* image, CvSize pattern_size,
                              CvPoint2D32f* corners, int count,
                              int pattern_was_found );
  
image
结果图像,必须是8位彩色图像。
pattern_size
每行和每列地内角点数目。
corners
检测到地角点数组。
count
角点数目。
pattern_was_found
指示完整地棋盘被发现(≠0)还是没有发现(=0)。可以传输cvFindChessboardCorners函数的返回值。

当棋盘没有完全检测出时,函数cvDrawChessboardCorners以红色圆圈绘制检测到的棋盘角点;如果整个棋盘都检测到,则用直线连接所有的角点。

[ 编辑]

姿态估计

[ 编辑]

CreatePOSITObject

初始化包含对象信息的结构


CvPOSITObject* cvCreatePOSITObject( CvPoint3D32f* points, int point_count );
  
points
指向三维对象模型的指针
point_count
对象的点数

函数 cvCreatePOSITObject 为对象结构分配内存并计算对象的逆矩阵。

预处理的对象数据存储在结构CvPOSITObject中,只能在OpenCV内部被调用,即用户不能直接读写数据结构。用户只可以创建这个结构并将指针传递给函数。

对象是在某坐标系内的一系列点的集合,函数 cvPOSIT计算从照相机坐标系中心到目标点points[0] 之间的向量。

一旦完成对给定对象的所有操作,必须使用函数cvReleasePOSITObject释放内存。

[ 编辑]

POSIT

执行POSIT算法


void cvPOSIT( CvPOSITObject* posit_object, CvPoint2D32f* image_points, 
              double focal_length,
              CvTermCriteria criteria, CvMatr32f rotation_matrix, 
              CvVect32f translation_vector );
  
posit_object
指向对象结构的指针
image_points
指针,指向目标像素点在二维平面图上的投影。
focal_length
使用的摄像机的焦距
criteria
POSIT迭代算法程序终止的条件
rotation_matrix
旋转矩阵
translation_vector
平移矩阵.

函数 cvPOSIT 执行POSIT算法。图像坐标在摄像机坐标系统中给出。焦距可以通过摄像机标定得到。算法每一次迭代都会重新计算在估计位置的透视投影。

两次投影之间的范式差值是对应点中的最大距离。如果差值过小,参数criteria.epsilon就会终止程序。

[ 编辑]

ReleasePOSITObject

释放3D对象结构


void cvReleasePOSITObject( CvPOSITObject** posit_object );
  
posit_object
指向 CvPOSIT 结构指针的指针。

函数 cvReleasePOSITObject 释放函数 cvCreatePOSITObject分配的内存。

[ 编辑]

CalcImageHomography

计算长方形或椭圆形平面对象(例如胳膊)的Homography矩阵


void cvCalcImageHomography( float* line, CvPoint3D32f* center,
                            float* intrinsic, float* homography );
  
line
对象的主要轴方向,为向量(dx,dy,dz).
center
对象坐标中心 ((cx,cy,cz)).
intrinsic
摄像机内参数 (3x3 matrix).
homography
输出的Homography矩阵(3x3).

函数 cvCalcImageHomography 为从图像平面到图像平面的初始图像变化(defined by 3D oblong object line)计算Homography矩阵。

[ 编辑]

对极几何(双视几何)

[ 编辑]

FindFundamentalMat

由两幅图像中对应点计算出基本矩阵


int cvFindFundamentalMat( const CvMat* points1,
                          const CvMat* points2,
                          CvMat* fundamental_matrix,
                          int    method=CV_FM_RANSAC,
                          double param1=1.,
                          double param2=0.99,
                          CvMat* status=NULL);
  
points1
第一幅图像点的数组,大小为2xN/Nx2 或 3xN/Nx3 (N 点的个数),多通道的1xN或Nx1也可以。点坐标应该是浮点数(双精度或单精度)。:
points2
第二副图像的点的数组,格式、大小与第一幅图像相同。
fundamental_matrix
输出的基本矩阵。大小是 3x3 或者 9x3 ,(7-点法最多可返回三个矩阵).
method
计算基本矩阵的方法
  • CV_FM_7POINT – 7-点算法,点数目= 7
  • CV_FM_8POINT – 8-点算法,点数目 >= 8
  • CV_FM_RANSAC – RANSAC 算法,点数目 >= 8
  • CV_FM_LMEDS - LMedS 算法,点数目 >= 8
param1
这个参数只用于方法RANSAC 或 LMedS 。它是点到对极线的最大距离,超过这个值的点将被舍弃,不用于后面的计算。通常这个值的设定是0.5 or 1.0 。
param2
这个参数只用于方法RANSAC 或 LMedS 。 它表示矩阵正确的可信度。例如可以被设为0.99 。
status
具有N个元素的输出数组,在计算过程中没有被舍弃的点,元素被被置为1;否则置为0。这个数组只可以在方法RANSAC and LMedS 情况下使用;在其它方法的情况下,status一律被置为1。这个参数是可选参数。

对极几何可以用下面的等式描述:

p_2^T \cdot F \cdot p_1=0

其中 F 是基本矩阵,p1 和 p2 分别是两幅图上的对应点。

函数 FindFundamentalMat 利用上面列出的四种方法之一计算基本矩阵,并返回基本矩阵的值:没有找到矩阵,返回0,找到一个矩阵返回1,多个矩阵返回3。 计算出的基本矩阵可以传递给函数cvComputeCorrespondEpilines来计算指定点的对极线。


例子1:使用 RANSAC 算法估算基本矩阵。
int    numPoints = 100;
CvMat* points1;
CvMat* points2;
CvMat* status;
CvMat* fundMatr;
points1 = cvCreateMat(2,numPoints,CV_32F);
points2 = cvCreateMat(2,numPoints,CV_32F);
status  = cvCreateMat(1,numPoints,CV_32F);

/* 在这里装入对应点的数据... */

fundMatr = cvCreateMat(3,3,CV_32F);
int num = cvFindFundamentalMat(points1,points2,fundMatr,CV_FM_RANSAC,1.0,0.99,status);
if( num == 1 )
     printf("Fundamental matrix was found\n");
else
     printf("Fundamental matrix was not found\n");


例子2:7点算法(3个矩阵)的情况。
CvMat* points1;
CvMat* points2;
CvMat* fundMatr;
points1 = cvCreateMat(2,7,CV_32F);
points2 = cvCreateMat(2,7,CV_32F);

/* 在这里装入对应点的数据... */

fundMatr = cvCreateMat(9,3,CV_32F);
int num = cvFindFundamentalMat(points1,points2,fundMatr,CV_FM_7POINT,0,0,0);
printf("Found %d matrixes\n",num);
  
[ 编辑]

ComputeCorrespondEpilines

为一幅图像中的点计算其在另一幅图像中对应的对极线。


void cvComputeCorrespondEpilines( const CvMat* points,
                                  int which_image,
                                  const CvMat* fundamental_matrix,
                                  CvMat* correspondent_lines);
  
points
输入点,是2xN 或者 3xN 数组 (N为点的个数)
which_image
包含点的图像指数(1 or 2)
fundamental_matrix
基本矩阵
correspondent_lines
计算对极点, 3xN数组

函数 ComputeCorrespondEpilines 根据外级线几何的基本方程计算每个输入点的对应外级线。如果点位于第一幅图像(which_image=1),对应的对极线可以如下计算 :

l_2=F \cdot p_1

其中F是基本矩阵,p1 是第一幅图像中的点, l2 - 是与第二幅对应的对极线。如果点位于第二副图像中 which_image=2),计算如下:

l_1=F^T \cdot p_2

其中p2 是第二幅图像中的点,l1 是对应于第一幅图像的对极线,每条对极线都可以用三个系数表示 a, b, c:

a\cdot x + b\cdot y + c = 0

归一化后的对极线系数存储在correspondent_lines 中。

[ 编辑]

ConvertPointsHomogenious

Convert points to/from homogenious coordinates


void cvConvertPointsHomogenious( const CvMat* src, CvMat* dst );
  
src
The input point array, 2xN, Nx2, 3xN, Nx3, 4xN or Nx4 (where N is the number of points). Multi-channel 1xN or Nx1 array is also acceptable.
dst
The output point array, must contain the same number of points as the input; The dimensionality must be the same, 1 less or 1 more than the input, and also within 2..4.

The function cvConvertPointsHomogenious converts 2D or 3D points from/to homogenious coordinates, or simply copies or transposes the array. In case if the input array dimensionality is larger than the output, each point coordinates are divided by the last coordinate:

(x,y[,z],w) -> (x',y'[,z'])
其中
x' = x/w
y' = y/w
z' = z/w (if output is 3D)

If the output array dimensionality is larger, an extra 1 is appended to each point.

(x,y[,z]) -> (x,y[,z],1)

Otherwise, the input array is simply copied (with optional tranposition) to the output. Note that, because the function accepts a large variety of array layouts, it may report an error when input/output array dimensionality is ambiguous. It is always safe to use the function with number of points N>=5, or to use multi-channel Nx1 or 1xN arrays.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用OpenCV进行摄像机标定 的相关文章

  • 基于 SpringBoot + Vue 实现的可视化拖拽编辑的大屏项目

    一个基于 SpringBoot 43 Vue 实现的可视化拖拽编辑的大屏项目 AJ Report AJ Report由 安吉加加 开源的一个BI平台 xff0c 酷炫大屏展示 xff0c 能随时随地掌控业务动态 xff0c 让每个决策都有数
  • 汇编语言总结笔记

    汇编语言初识 xff08 一 xff09 开始学习汇编语言 xff0c 对相关的所学知识做个总结 xff0c 希望对自己可以有所提高 1 在计算机中数的表示方式 因为计算机中只能存储二进制数 xff0c 所以一般都是通过二进制直接进行存储
  • Ubuntu18.04重启后无法进入图形化界面

    如果你没有瞎卸载很多东西的话 xff0c 先在字符界面输入你的用户名和密码 xff0c 先尝试这个命令 xff1a sudo systemctl isolate graphical target 不行的话 xff0c 我的解决办法 xff1
  • STM32按键外部中断控制LED流水灯-HAL库

    续上一篇 基于HAL库的32流水灯 http t csdn cn 30QT4 一 硬件选用上 xff0c 我们增加一个四角按键 二 原理图设计 xff0c 上也增加一个开关 LED0 LED2 gt PA0 PA2引脚 KEY1 gt PA
  • Linux系统下定时关机命令shutdown

    接触过linux系统的都知道shutdown命令用于安全的关闭 重启计算机 xff0c 用决定命令shutdown不仅可以实现定时关机 xff0c 还可以由用户自己决定关机时的参数 xff1a 以下简单了解一下同样的功能在linux下使用s
  • 解决Ubuntu 显卡驱动升级导致的 显卡驱动和内核版本不匹配的问题

    解决Ubuntu 显卡驱动升级导致的 显卡驱动和内核版本 xff08 同时内核存在问题 xff09 不匹配的问题 不要轻易升级显卡驱动版本 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xf
  • Nginx+Consul_Upsyc动态切换配置实现动态流量切换

    Nginx 43 Consul Upsyc动态切换配置 大纲 基础概念安装流程测试例子 基础概念 动态配置可以让nginx在不停机的情况下 xff0c 实现动态的切换后端负载的服务器 xff0c 为各种发布方式提供基础的流量切换工作 htt
  • [AHK]实现Word保存前先更新目录

    重新定义热键Ctrl 43 s 用AHK重新定义Ctrl 43 s热键 xff0c 实现当按Ctrl 43 s后 xff0c 会先更新Word中插入的目录 AHK源代码 span class token punctuation span 作
  • win10把中文用户名改为英文用户名的两种方法

    电脑安装好win10系统后后创建了一个中文名的账户 xff0c 进入系统发现C User下的文件夹是中文名 xff0c 虽然中文名方便识别 xff0c 但是这样有一个很不好的地方 xff0c 那就是很多软件安装在个路径下 xff0c 有些软
  • [QMT]08-从本地行情数据解析历史K线信息

    用python解析QMT本地数据 获取本地行情数据 get local data field list 61 stock code 61 period 61 39 1d 39 start time 61 39 39 end time 61
  • Nginx+keepalived实现nginx高可用

    提前备好两台服务器 xff08 主 xff1a 192 168 2 34 xff0c 备 xff1a 192 168 2 24 xff09 xff0c 并安装好nginx xff0c nginx安装此文不做赘述 1 下载keepAlived
  • 提取括号中的内容

    正则能解决不嵌套的括号内容提取问题 遇到一个问题 xff0c 就是需要提取字符串中每一个中括号里的内容 xff0c 在网上搜了一下 xff0c 发现用正则表达式 可以提取中括号中的内容 xff0c 以下面文本为匹配对象 xff1a Perf
  • [AHK]将字符转换成莫尔斯电码

    这个程序可以在记事本中使用 当用户按下空格键时 xff0c 程序会获取当前选中的文本 xff0c 并将其转换为莫尔斯电码播放出来 如果用户选中的文本包含非摩尔斯电码字符 xff0c 程序会自动忽略它们 将字符转换成莫尔斯电码 这个程序可以在
  • 开放原子训练营(第二季)RT-Thread Nano学习营刘玉宽

    目录 前言 RT Thread简介 搭建开发环境 实验过程 1 LED 使用示例 2 按键使用示例 3 自动化执行的示例 4 自定义 msh 命令 5 多线程示例 6 定时器示例 7 消息队列示例 8 摩斯电码使用 实验总结 前言 4月22
  • 关于主机远程唤醒(WOL,Wake on Lan)的几种方法

    WOL 网络唤醒功能非常实用 xff0c 譬如可以用手机遥控电脑开机 xff0c 开启其他房间里的电脑或 NAS xff0c 控制办公室多台电脑批量开关机等 虽然 WOL 主要是在局域网使用 xff0c 但如果配置好公网访问 xff0c 还
  • 双拼和简拼兼容的方案

    双拼和简拼兼容的方案 http wubi sogou com bbs viewthread php tid 61 155980 作者 xff1a Thunk 在双拼状态下 xff0c 如果提供简拼输入 xff0c 往往会增加重码 xff0c
  • cmd /c和cmd /k

    cmd c和cmd k http leaning javaeye com blog 380810 java的Runtime getRuntime exec commandStr 可以调用执行cmd指令 cmd c dir 是执行完dir命令
  • 9 种流行的文件、文件夹比较工具点评 (转贴)

    1 FCU 推荐 xff1a 主页 xff1a http fcu smibe com 功能 xff1a 目录比较 xff0c 文件比较 特点 xff1a 文件比较以三个窗口显示 上部分的左侧窗口和右侧窗口为原始比较文件 xff0c 不同部分
  • 64位windows10,打不chm文件问题,终于解决了。。。

    公司新给配了一台win10笔记本 xff0c 发现打不开chm文件 xff0c 度娘给的方案都是修改文件属性解除锁定之类的 xff0c 根本解决不了问题 经过几天研究 xff0c 发现将chm文件拖放到 SysWOW64中的hh exe可以
  • 蓝牙键盘无法连接 ,win10要求输入pin码可是却不显示pin码

    解决方案 xff1a 打开 设备和打印机 xff0c 切换到在设备上输入密码就可以显示PIN码

随机推荐

  • Vue3-使用axios发起网络请求

    即使是小型项目也会涉及到请求后端API xff0c 除非你的网站展示的是一些不需要维护的静态数据 xff0c 第三篇文章我们来给Vue项目搞上axios 何为Axios xff1f 请看官方对Axios的描述 xff0c 传送门 官方文档
  • linux查看防火墙,开放端口

    1 查看防火墙状态 xff1a active running 即是开启状态 systemctl status firewalld 2 如果不是显示active状态 xff0c 需要打开防火墙 systemctl start firewall
  • UOS 欢迎信息

    赛题 2 操作系统配置 所处区域 CST 8 系统环境语言 English US UTF 8 键盘 English US 注意 当任务是配置TLS 请把根证书或者自签名证书添加到受信任区 控制台登陆后不管是网络登录还是本地登录 都按下方欢迎
  • Vue3-浏览器兼容性 IE篇

    在前端做适配的时候有些客户使用了比较旧的浏览器如IE8 9等 xff0c 前端技术栈中有些功能会出现异常或者无法显示页面 xff0c 记录几个常用的方法对不兼容的浏览器抛出友好异常 检测是否为IE浏览器 span class token k
  • HTTPS-自签证书macOS必须使用thisisunsafe

    HTTPS是站点部署的发展趋势 xff0c 由于HTTP的一系列安全问题 例如网络嗅探时数据报文默认是明文传输 xff0c 容易遭受MitM攻击篡改数据等等 什么是MITM 中间人攻击 xff1f 在内网环境部署站点的时候 xff0c HT
  • Linux-SMTP中继服务器搭建

    本文介绍使用Linux搭建SMTP服务器 xff0c 通过搭配DNS记录修改达到SPF认证的目的 本文参考 xff1a SMTP搭建教程 硬件要求 CPU span class token punctuation span 2C4T 主存
  • Swift5-引入SnapKit

    适用于因网络情况 xff0c 按照SnapKit官方手册引入失败或下载过慢的情况 请先核对Xcode和Swift版本 Xcode Version span class token operator span Version span cla
  • Vue3-减少应用部署打包体积的N种方式【持续更新】

    Vue3默认支持OptionsAPI和Composition API 混编的方式进行开发 xff0c 如果在新系统建设过程中完全抛弃了OptionsAPI方式 xff0c 可以使用vite定义全局变量来告诉Vue关闭对OptionsAPI的
  • Golang-简单-找不同

    题 xff1a 给定两个字符串 s 和 t xff0c 它们只包含小写字母 字符串 t 由字符串 s 随机重排 xff0c 然后在随机位置添加一个字母 请找出在 t 中被添加的字母 示例 1 xff1a 输入 xff1a s 61 abcd
  • Golang-简单-判断子序列

    题 xff1a 给定字符串 s 和 t xff0c 判断 s 是否为 t 的子序列 字符串的一个子序列是原始字符串删除一些 xff08 也可以不删除 xff09 字符而不改变剩余字符相对位置形成的新字符串 xff08 例如 xff0c 34
  • Android NDK开发基础

    文章目录 cmake语法基础cmake添加日志 xff1a cmake增加宏字符串比较cmake在build gradle中传递编译参数到cmake 通过javah生成native对应的c 43 43 头文件jni和java之间字符串的相互
  • iOS 使用科大讯飞技术实现语音转文字(语音听写)

    本文主要介绍的是利用科大讯飞技术实现语音转文字的功能 语音听写 首先 注册讯飞账号 xff0c 申请APPID 然后 下载科大讯飞SDK将开发工具包中lib目录下的iflyMSC framework添加到新建工程中 按下图添加 SDK 所需
  • Pycharm的汉化方法(pycharm改为中文版)

    很多开始接触python的朋友都会用到一款工具 xff1a pycharm xff0c 但默认是英文版的不知从何下手 xff0c 本文介绍两种不同的pycharm汉化方法 xff0c 将其变为中文版的界面 xff08 对于windows电脑
  • ubuntu14.04服务器版本搭建OpenStack+附上资源链接(稳成功的那种)

    ubuntu14 04服务器版本搭建OpenStack 43 附上资源链接 xff08 稳成功的那种 xff09 一 想必大家在搭建过程中 xff0c 遇见了很多的困难是吗 xff1f 没事 xff0c 今天小编就带你搭建属于你自己的Ope
  • 部署taokeeper

    环境 span class hljs title wget span https mirrors tuna tsinghua edu cn apache tomcat tomcat span class hljs number 7 span
  • 字符串排序(C语言实现)

    习题8 7 字符串排序 xff08 C语言实现 xff09 方法一 xff1a 选择排序 span class token macro property span class token directive keyword include
  • DVWA简介

    DVWA部署完成后通过默认账号密码 xff08 admin password xff09 进入欢迎界面 xff08 Home页面 xff09 xff0c 欢迎页面对DVWA平台做了简单的介绍 xff0c 如果需要对DVWA平台有一个更加深入
  • ios 导航控制器(navigationController)代码方式创建

    NavigationCOntroller 使用 BooL application UIApplication application didFinishLaunchingWithOptions NSDictionary launchOpti
  • ansible 简介和基本安装

    目录 ansible 简介和基本安装 自动化运维 运维的自动化发展历程运维工程师的职能划分自动化运维的应用场景企业实际应用场景分析 Dev开发环境测试环境发布环境生产环境 灰度环境 生产环境的一部分 常用的自动化运维工具ansible基本介
  • 使用OpenCV进行摄像机标定

    Cv照相机定标和三维重建 目录 隐藏 1 针孔相机模型和变形 2 照相机定标 2 1 ProjectPoints2 2 2 FindHomography 2 3 CalibrateCamera2 2 4 FindExtrinsicCamer