当前位置: 首页 > news >正文

【三维重建】ePnP

PnP问题应用与一下场景:
已知三维点和对应二维点以及相机相机内参数,可以获取相机外参。请添加图片描述
我们介绍其中的一种算法:ePnP

算法流程

1、ePnP算法首先在世界坐标系内寻找4个控制点,记作 C 1 w , C 2 w , C 3 w , C 4 w C_1^w,C_2^w,C_3^w,C_4^w C1w,C2w,C3w,C4w,使得:
对于世界坐标系内任意一点 P 1 w , P_1^w, P1w,存在对应的 α i = [ α i 1 , α i 2 , α i 3 , α i 4 ] T \alpha_i=[\alpha_{i1},\alpha_{i2},\alpha_{i3},\alpha_{i4}]^T αi=[αi1,αi2,αi3,αi4]T,满足:
P i w = ∑ j = 1 4 α i j C j w , w i t h ∑ j = 1 4 α i j = 1 P_i^w = \sum_{j=1}^4\alpha_{ij}C_j^w, {\kern 20pt} with\sum_{j=1}^4\alpha_{ij}=1 Piw=j=14αijCjw,withj=14αij=1
世界坐标系上的 P w P^w Pw 经过 R , t R,t R,t 变换可以得到相机坐标系下的点 P c P^c Pc :
P i c = R P i w + t = R ( ∑ j = 1 4 α i j C j w ) + t P_i^c = RP_i^w+t=R\left(\sum_{j=1}^4\alpha_{ij}C_j^w\right) + t Pic=RPiw+t=R(j=14αijCjw)+t
由于 ∑ j = 1 4 α i j = 1 \sum_{j=1}^4\alpha_{ij}=1 j=14αij=1,因此 t = ∑ j = 1 4 α i j t t=\sum_{j=1}^4\alpha_{ij}t t=j=14αijt 带入上式得 ( C j w 是世界坐标系下的控制点, C j c 是世界坐标系下的控制点 ) (C_j^w是世界坐标系下的控制点,C_j^c是世界坐标系下的控制点) (Cjw是世界坐标系下的控制点,Cjc是世界坐标系下的控制点):
P i c = ∑ j − 1 4 α i j ( R C j w + t ) = ∑ j − 1 4 α i j C j c , ( C j c = R C j w + t ) P_i^c = \sum_{j-1}^4\alpha_{ij}(RC_j^w + t)= \sum_{j-1}^4\alpha_{ij}C_j^c,{\color{red} \left(C_j^c = RC_j^w+t \right)} Pic=j14αij(RCjw+t)=j14αijCjc,(Cjc=RCjw+t)

通过内参矩阵,建立相机坐标系下的点 P c P^c Pc 到像素坐标系下的点 p p p 的映射:
p i = s i [ u i v i 1 ] = K P i c = [ f u 0 u c 0 f v v c 0 0 1 ] ∑ j = 1 4 α i j [ C x j c C y j c C z j c ] p_i = s_i\begin{bmatrix}u_i \\ v_i \\ 1 \end{bmatrix} = KP^c_i=\begin{bmatrix}f_u &0 & u_c \\0& f_v & v_c \\ 0&0&1 \end{bmatrix}\sum_{j=1}^4\alpha_{ij}\begin{bmatrix}C_{xj}^c \\C_{yj}^c \\ C_{zj}^c \end{bmatrix} pi=si uivi1 =KPic= fu000fv0ucvc1 j=14αij CxjcCyjcCzjc
将公式展开,可得:
∑ j = 1 4 α i j f u C x j c + α i j ( u c − u i ) C z j c = 0 ∑ j = 1 4 α i j f v C y j c + α i j ( v c − v i ) C z j c = 0 \sum_{j=1}^4\alpha_{ij}f_uC^c_{xj} + \alpha_{ij}(u_c-u_i)C_{zj}^c = 0 \\ \sum_{j=1}^4\alpha_{ij}f_vC^c_{yj} + \alpha_{ij}(v_c-v_i)C_{zj}^c = 0 j=14αijfuCxjc+αij(ucui)Czjc=0j=14αijfvCyjc+αij(vcvi)Czjc=0
对于上述公式 只有相机坐标系下的四个控制点 C j c C_j^c Cjc​ 未知,每个控制点有三个参数,因此一共有12个未知数。每对点能建立两个方程组,所以,至少要6对点才能进行求解。
f u [ α i 1 α i 2 α i 3 α i 4 ] [ C x 1 c C x 2 c C x 3 c C x 4 c ] + ( u c − u i ) [ α i 1 α i 2 α i 3 α i 4 ] [ C z 1 c C z 2 c C z 3 c C z 4 c ] = 0 f v [ α i 1 α i 2 α i 3 α i 4 ] [ C y 1 c C y 2 c C y 3 c C y 4 c ] + ( v c − v i ) [ α i 1 α i 2 α i 3 α i 4 ] [ C z 1 c C z 2 c C z 3 c C z 4 c ] = 0 [ f u α i 1 f u α i 2 f u α i 3 f u α i 4 0 0 0 0 ( u c − u i ) α i 1 ( u c − u i ) α i 2 ( u c − u i ) α i 3 ( u c − u i ) α i 4 0 0 0 0 f v α i 1 f v α i 2 f v α i 3 f v α i 4 ( v c − v i ) α i 1 ( v c − v i ) α i 2 ( v c − v i ) α i 3 ( v c − v i ) α i 4 ] [ C x 1 c C x 2 c C x 3 c C x 4 c C y 1 c C y 2 c C y 3 c C y 4 c C z 1 c C z 2 c C z 3 c C z 4 c ] = 0 f_u \begin{bmatrix} \alpha_{i1} & \alpha_{i2} & \alpha_{i3} & \alpha_{i4} \end{bmatrix}\begin{bmatrix} C_{x1}^c \\ C_{x2}^c \\ C_{x3}^c \\ C_{x4}^c\end{bmatrix} + (u_c-u_i) \begin{bmatrix} \alpha_{i1} & \alpha_{i2} & \alpha_{i3} & \alpha_{i4} \end{bmatrix} \begin{bmatrix} C_{z1}^c \\ C_{z2}^c \\ C_{z3}^c \\ C_{z4}^c\end{bmatrix} =0 \\ f_v \begin{bmatrix} \alpha_{i1} & \alpha_{i2} & \alpha_{i3} & \alpha_{i4} \end{bmatrix}\begin{bmatrix} C_{y1}^c \\ C_{y2}^c \\ C_{y3}^c \\ C_{y4}^c\end{bmatrix} + (v_c-v_i) \begin{bmatrix} \alpha_{i1} & \alpha_{i2} & \alpha_{i3} & \alpha_{i4} \end{bmatrix} \begin{bmatrix} C_{z1}^c \\ C_{z2}^c \\ C_{z3}^c \\ C_{z4}^c\end{bmatrix} =0 \\\\\\ \begin{bmatrix} f_u\alpha_{i1} & f_u\alpha_{i2} & f_u\alpha_{i3} & f_u\alpha_{i4} &0&0&0&0&(u_c-u_i) \alpha_{i1} & (u_c-u_i) \alpha_{i2} & (u_c-u_i) \alpha_{i3} & (u_c-u_i) \alpha_{i4} \\0&0&0&0&f_v\alpha_{i1} & f_v\alpha_{i2} & f_v\alpha_{i3} & f_v\alpha_{i4}& (v_c-v_i) \alpha_{i1} & (v_c-v_i) \alpha_{i2} & (v_c-v_i) \alpha_{i3} & (v_c-v_i) \alpha_{i4} \end{bmatrix}\begin{bmatrix}C_{x1}^c \\ C_{x2}^c \\ C_{x3}^c \\ C_{x4}^c\\C_{y1}^c \\ C_{y2}^c \\ C_{y3}^c \\ C_{y4}^c \\ C_{z1}^c \\ C_{z2}^c \\ C_{z3}^c \\ C_{z4}^c\end{bmatrix} =0 fu[αi1αi2αi3αi4] Cx1cCx2cCx3cCx4c +(ucui)[αi1αi2αi3αi4] Cz1cCz2cCz3cCz4c =0fv[αi1αi2αi3αi4] Cy1cCy2cCy3cCy4c +(vcvi)[αi1αi2αi3αi4] Cz1cCz2cCz3cCz4c =0[fuαi10fuαi20fuαi30fuαi400fvαi10fvαi20fvαi30fvαi4(ucui)αi1(vcvi)αi1(ucui)αi2(vcvi)αi2(ucui)αi3(vcvi)αi3(ucui)αi4(vcvi)αi4] Cx1cCx2cCx3cCx4cCy1cCy2cCy3cCy4cCz1cCz2cCz3cCz4c =0
找到相机坐标系下的控制点后,就能够求得相机外参:
C j c = R C j w + t [ C x j c C y j c C z j c ] = [ r 1 r 2 r 3 r 4 r 5 r 6 r 7 r 8 r 9 ] [ C x j w C y j w C z j w ] + [ t 1 t 2 t 3 ] C x j c = r 1 C x j w + r 2 C y j w + r 3 C z j w + t 1 C y j c = r 4 C x j w + r 5 C y j w + r 6 C z j w + t 2 C z j c = r 7 C x j w + r 8 C y j w + r 9 C z j w + t 3 [ C x 1 c C y 1 c C z 1 c C x 2 c C y 2 c C z 2 c C x 3 c C y 3 c C z 3 c C x 4 c C y 4 c C z 4 c ] = [ C x 1 w C y 1 w C z 1 w 0 0 0 0 0 0 1 0 0 0 0 0 C x 1 w C y 1 w C z 1 w 0 0 0 0 1 0 0 0 0 0 0 0 C x 1 w C y 1 w C z 1 w 0 0 1 C x 2 w C y 2 w C z 2 w 0 0 0 0 0 0 1 0 0 0 0 0 C x 2 w C y 2 w C z 2 w 0 0 0 0 1 0 0 0 0 0 0 0 C x 2 w C y 2 w C z 2 w 0 0 1 C x 3 w C y 3 w C z 3 w 0 0 0 0 0 0 1 0 0 0 0 0 C x 3 w C y 3 w C z 3 w 0 0 0 0 1 0 0 0 0 0 0 0 C x 3 w C y 3 w C z 3 w 0 0 1 C x 4 w C y 4 w C z 4 w 0 0 0 0 0 0 1 0 0 0 0 0 C x 4 w C y 4 w C z 4 w 0 0 0 0 1 0 0 0 0 0 0 0 C x 4 w C y 4 w C z 4 w 0 0 1 ] [ r 1 r 2 r 3 r 4 r 5 r 6 r 7 r 8 r 9 t 1 t 2 t 3 ] \begin{aligned} &C_j^c = RC_j^w+t\\\\ &\begin{bmatrix}C_{xj}^c \\ C_{yj}^c \\ C_{zj}^c \end{bmatrix} = \begin{bmatrix} r_1 & r_2 & r_3 \\ r_4 & r_5 & r_6 \\r_7 & r_8 & r_9 \end{bmatrix}\begin{bmatrix}C_{xj}^w \\ C_{yj}^w \\ C_{zj}^w \end{bmatrix} + \begin{bmatrix} t_1 \\ t_2 \\ t_3\end{bmatrix} \\\\ &C_{xj}^c = r_1C_{xj}^w + r_2C_{yj}^w + r_3C_{zj}^w + t_1\\ &C_{yj}^c = r_4C_{xj}^w + r_5C_{yj}^w + r_6C_{zj}^w + t_2\\ &C_{zj}^c = r_7C_{xj}^w + r_8C_{yj}^w + r_9C_{zj}^w + t_3\\ \\\\ &\begin{bmatrix}C_{x1}^c \\ C_{y1}^c \\C_{z1}^c \\C_{x2}^c \\ C_{y2}^c \\C_{z2}^c \\C_{x3}^c \\ C_{y3}^c \\C_{z3}^c \\C_{x4}^c \\ C_{y4}^c \\C_{z4}^c\end{bmatrix} = \begin{bmatrix} C_{x1}^w & C_{y1}^w & C_{z1}^w&0&0&0&0&0&0&1&0&0 \\ 0&0&0&C_{x1}^w & C_{y1}^w & C_{z1}^w &0&0&0&0&1&0\\ 0&0&0&0&0&0& C_{x1}^w & C_{y1}^w & C_{z1}^w &0&0&1\\ C_{x2}^w & C_{y2}^w & C_{z2}^w&0&0&0&0&0&0&1&0&0 \\ 0&0&0&C_{x2}^w & C_{y2}^w & C_{z2}^w &0&0&0&0&1&0\\ 0&0&0&0&0&0& C_{x2}^w & C_{y2}^w & C_{z2}^w &0&0&1 \\ C_{x3}^w & C_{y3}^w & C_{z3}^w&0&0&0&0&0&0&1&0&0 \\ 0&0&0&C_{x3}^w & C_{y3}^w & C_{z3}^w &0&0&0&0&1&0\\ 0&0&0&0&0&0& C_{x3}^w & C_{y3}^w & C_{z3}^w &0&0&1\\ C_{x4}^w & C_{y4}^w & C_{z4}^w&0&0&0&0&0&0&1&0&0 \\ 0&0&0&C_{x4}^w & C_{y4}^w & C_{z4}^w &0&0&0&0&1&0\\ 0&0&0&0&0&0& C_{x4}^w & C_{y4}^w & C_{z4}^w &0&0&1 \end{bmatrix} \begin{bmatrix}r_1 \\ r_2 \\ r_3 \\ r_4 \\ r_5 \\ r_6 \\ r_7 \\ r_8 \\ r_9 \\t_1\\t_2\\t_3 \end{bmatrix} \end{aligned} Cjc=RCjw+t CxjcCyjcCzjc = r1r4r7r2r5r8r3r6r9 CxjwCyjwCzjw + t1t2t3 Cxjc=r1Cxjw+r2Cyjw+r3Czjw+t1Cyjc=r4Cxjw+r5Cyjw+r6Czjw+t2Czjc=r7Cxjw+r8Cyjw+r9Czjw+t3 Cx1cCy1cCz1cCx2cCy2cCz2cCx3cCy3cCz3cCx4cCy4cCz4c = Cx1w00Cx2w00Cx3w00Cx4w00Cy1w00Cy2w00Cy3w00Cy4w00Cz1w00Cz2w00Cz3w00Cz4w000Cx1w00Cx2w00Cx3w00Cx4w00Cy1w00Cy2w00Cy3w00Cy4w00Cz1w00Cz2w00Cz3w00Cz4w000Cx1w00Cx2w00Cx3w00Cx4w00Cy1w00Cy2w00Cy3w00Cy4w00Cz1w00Cz2w00Cz3w00Cz4w100100100100010010010010001001001001 r1r2r3r4r5r6r7r8r9t1t2t3

控制点选取

原则上,就是只要选择3个线性无关的点,就可以表示任意一个三维点,但由于方程组是4,如何是3个控制点只能求得最小二乘解。论文中给出了具体的选择方法。 3D参考点集为 { P i w , i = 1 , ⋯ , n } \left\{P^w_i,i=1,\cdots,n \right \} {Piw,i=1,,n}, 选择3D点的中心为第一个控制点:
C 1 w = 1 n ∑ i = 1 n P i w C^w_1=\frac{1}{n}\sum_{i=1}^nP^w_i C1w=n1i=1nPiw
进而得到矩阵:
A = [ ( P 1 w ) T − ( C 1 w ) T ⋯ ( P n w ) T − ( C n w ) T ] A=\begin{bmatrix}{(P_{1}^{w})}^{T} - {(C_{1}^{w})}^{T} \\ \cdots \\ {(P_{n}^{w})}^{T} - {(C_{n}^{w})}^{T} \end{bmatrix} A= (P1w)T(C1w)T(Pnw)T(Cnw)T
A T A A^TA ATA的特征值为 λ i \lambda_i λi, 特征向量为 V i V_i Vi ,那么剩下的三个点为:
C w = C 1 w + λ i 1 2 V i , i = 1 , 2 , 3 C^w = C_1^w +\lambda^{\frac{1}{2}}_iV_i,\ i = 1,2,3 Cw=C1w+λi21Vi, i=1,2,3

求解 α \alpha α

联立方程组:
P i w = α i 1 C 1 w + α i 2 C 2 w + α i 3 C 3 w + α i 4 C 4 w [ x i y i z i ] = α i 1 [ C x 1 w C y 1 w C z 1 w ] + α i 2 [ C x 2 w C y 2 w C z 2 w ] + α i 3 [ C x 3 w C y 3 w C z 3 w ] + α i 4 [ C x 4 w C y 4 w C z 4 w ] \begin{aligned} &P_i^w = \alpha_{i1}C_1^w+\alpha_{i2}C_2^w+\alpha_{i3}C_3^w+\alpha_{i4}C_4^w \\\\ &\begin{bmatrix} x_i \\y_i\\z_i\end{bmatrix} = \alpha_{i1}\begin{bmatrix} C_{x1}^w \\C_{y1}^w\\C_{z1}^w\end{bmatrix}+\alpha_{i2}\begin{bmatrix} C_{x2}^w \\C_{y2}^w\\C_{z2}^w\end{bmatrix}+\alpha_{i3}\begin{bmatrix} C_{x3}^w \\C_{y3}^w\\C_{z3}^w\end{bmatrix}+\alpha_{i4}\begin{bmatrix} C_{x4}^w \\C_{y4}^w\\C_{z4}^w\end{bmatrix} \end{aligned} Piw=αi1C1w+αi2C2w+αi3C3w+αi4C4w xiyizi =αi1 Cx1wCy1wCz1w +αi2 Cx2wCy2wCz2w +αi3 Cx3wCy3wCz3w +αi4 Cx4wCy4wCz4w
每个点可以得到4个方程组:
x i = α i 1 C x 1 w + α i 2 C x 2 w + α i 3 C x 3 w + α i 4 C x 4 w y i = α i 1 C y 1 w + α i 2 C y 2 w + α i 3 C y 3 w + α i 4 C y 4 w z i = α i 1 C z 1 w + α i 2 C z 2 w + α i 3 C z 3 w + α i 4 C z 4 w 1 = α i 1 + α i 2 + α i 3 + α i 4 x_i=\alpha_{i1}C_{x1}^w+\alpha_{i2}C_{x2}^w+\alpha_{i3}C_{x3}^w+\alpha_{i4}C_{x4}^w\\ y_i=\alpha_{i1}C_{y1}^w+\alpha_{i2}C_{y2}^w+\alpha_{i3}C_{y3}^w+\alpha_{i4}C_{y4}^w\\ z_i=\alpha_{i1}C_{z1}^w+\alpha_{i2}C_{z2}^w+\alpha_{i3}C_{z3}^w+\alpha_{i4}C_{z4}^w\\ 1= \alpha_{i1}+\alpha_{i2}+\alpha_{i3}+\alpha_{i4} xi=αi1Cx1w+αi2Cx2w+αi3Cx3w+αi4Cx4wyi=αi1Cy1w+αi2Cy2w+αi3Cy3w+αi4Cy4wzi=αi1Cz1w+αi2Cz2w+αi3Cz3w+αi4Cz4w1=αi1+αi2+αi3+αi4
用矩阵的方式可表示为:
[ x i y i z i 1 ] = [ C x 1 w C x 2 w C x 3 w C x 4 w C y 1 w C y 2 w C y 3 w C y 4 w C z 1 w C z 2 w C z 3 w C z 4 w 1 1 1 1 ] [ α i 1 α i 2 α i 3 α i 4 ] ⟶ [ C x 1 w C x 2 w C x 3 w C x 4 w C y 1 w C y 2 w C y 3 w C y 4 w C z 1 w C z 2 w C z 3 w C z 4 w 1 1 1 1 ] − 1 [ x i y i z i 1 ] = [ α i 1 α i 2 α i 3 α i 4 ] \begin{bmatrix} x_i \\ y_i \\ z_i \\ 1 \end{bmatrix} = \begin{bmatrix} C_{x1}^w &C_{x2}^w &C_{x3}^w &C_{x4}^w \\ C_{y1}^w &C_{y2}^w &C_{y3}^w &C_{y4}^w \\ C_{z1}^w &C_{z2}^w &C_{z3}^w &C_{z4}^w \\ 1&1&1&1 \end{bmatrix} \begin{bmatrix} \alpha_{i1} \\ \alpha_{i2} \\ \alpha_{i3} \\ \alpha_{i4}\end{bmatrix} \longrightarrow \begin{bmatrix} C_{x1}^w &C_{x2}^w &C_{x3}^w &C_{x4}^w \\ C_{y1}^w &C_{y2}^w &C_{y3}^w &C_{y4}^w \\ C_{z1}^w &C_{z2}^w &C_{z3}^w &C_{z4}^w \\ 1&1&1&1 \end{bmatrix} ^{-1}\begin{bmatrix} x_i \\ y_i \\ z_i \\ 1 \end{bmatrix} = \begin{bmatrix} \alpha_{i1} \\ \alpha_{i2} \\ \alpha_{i3} \\ \alpha_{i4}\end{bmatrix} xiyizi1 = Cx1wCy1wCz1w1Cx2wCy2wCz2w1Cx3wCy3wCz3w1Cx4wCy4wCz4w1 αi1αi2αi3αi4 Cx1wCy1wCz1w1Cx2wCy2wCz2w1Cx3wCy3wCz3w1Cx4wCy4wCz4w1 1 xiyizi1 = αi1αi2αi3αi4

void Rebuild::ePnP(const std::vector<Eigen::Vector3d> &p3ds, const std::vector<Eigen::Vector2d> &p2ds, Camera &camera) {auto blog = _blog;blog->write("ePnP:");/**寻找4个控制点**///求取重心Eigen::Vector3d center = Eigen::Vector3d::Zero();std::vector<Eigen::Vector3d> control_points_w(4);for (int i = 0; i < p3ds.size(); i++) {center(0) += p3ds[i](0);center(1) += p3ds[i](1);center(2) += p3ds[i](2);}center(0) /= p3ds.size();center(1) /= p3ds.size();center(2) /= p3ds.size();control_points_w[0] = center;blog->write("center:");blog->write(center);blog->write("");//构建矩阵Eigen::MatrixXd A = Eigen::MatrixXd::Zero(p3ds.size(), 3);for (int i = 0; i < p3ds.size(); i++) {A(i, 0) = p3ds[i](0) - center(0);A(i, 1) = p3ds[i](1) - center(1);A(i, 2) = p3ds[i](2) - center(2);}Eigen::MatrixXd M = A.transpose() * A;Eigen::EigenSolver<Eigen::MatrixXd> solver(M);Eigen::VectorXd eigenValues = solver.eigenvalues().real();Eigen::MatrixXd eigenVectors = solver.eigenvectors().real();blog->write("eigenValues:");blog->write(eigenValues);blog->write("");blog->write("eigenVectors:");blog->write(eigenVectors);blog->write("");for (int i = 1; i < 4; i++) {control_points_w[i] = control_points_w[0] + sqrt(eigenValues(i - 1)) * eigenVectors.col(i - 1);}blog->write("control_points_w:");for (int i = 0; i < 4; i++) {blog->write(control_points_w[i]);}blog->write("");/**求解alpha**/Eigen::MatrixXd C_w = Eigen::MatrixXd::Zero(4, 4);for (int i = 0; i < 4; i++) {double x = control_points_w[i](0);double y = control_points_w[i](1);double z = control_points_w[i](2);C_w(0, i) = x;C_w(1, i) = y;C_w(2, i) = z;C_w(3, i) = 1;}Eigen::MatrixXd C_w_inv = C_w.inverse();blog->write("C_w:");blog->write(C_w);blog->write("");blog->write("C_w_inv:");blog->write(C_w_inv);blog->write("");double fu = camera._K(0, 0);double fv = camera._K(1, 1);double uc = camera._K(0, 2);double vc = camera._K(1, 2);Eigen::MatrixXd D =Eigen::MatrixXd::Zero(int(2 * p3ds.size()), 12);for (int i = 0; i < p3ds.size(); i++) {Eigen::Vector3d p3d = p3ds[i];Eigen::Vector2d p2d = p2ds[i];Eigen::Vector4d b;b << p3d(0), p3d(1), p3d(2), 1;Eigen::Vector4d alpha = C_w_inv * b;D(i * 2, 0) = fu * alpha(0);D(i * 2, 1) = fu * alpha(1);D(i * 2, 2) = fu * alpha(2);D(i * 2, 3) = fu * alpha(3);D(i * 2, 8) = (uc - p2d(0)) * alpha(0);D(i * 2, 9) = (uc - p2d(0)) * alpha(1);D(i * 2, 10) = (uc - p2d(0)) * alpha(2);D(i * 2, 11) = (uc - p2d(0)) * alpha(3);D(i * 2 + 1, 4) = fv * alpha(0);D(i * 2 + 1, 5) = fv * alpha(1);D(i * 2 + 1, 6) = fv * alpha(2);D(i * 2 + 1, 7) = fv * alpha(3);D(i * 2 + 1, 8) = (vc - p2d(1)) * alpha(0);D(i * 2 + 1, 9) = (vc - p2d(1)) * alpha(1);D(i * 2 + 1, 10) = (vc - p2d(1)) * alpha(2);D(i * 2 + 1, 11) = (vc - p2d(1)) * alpha(3);if(i == 0){blog->write("alpha:");blog->write(alpha);blog->write("");}}blog->write("D:");blog->write(D);blog->write("");Eigen::JacobiSVD<Eigen::MatrixXd> svd(D, Eigen::ComputeFullV | Eigen::ComputeFullU);auto V = svd.matrixV();std::vector<Eigen::Vector3d> control_points_c(4);blog->write("control_points_c:");for (int i = 0; i < 4; i++) {double x = V(i);double y = V(i + 4);double z = V(i + 8);Eigen::Vector3d p3d(x, y, z);control_points_c[i] = p3d;blog->write(p3d);}blog->write("");Eigen::MatrixXd Q = Eigen::MatrixXd::Zero(12, 12);Eigen::VectorXd C_c = Eigen::VectorXd::Zero(12);for (int i = 0; i < 4; i++) {C_c(i * 3) = control_points_c[i](0);C_c(i * 3 + 1) = control_points_c[i](1);C_c(i * 3 + 2) = control_points_c[i](2);Q(i * 3, 0) = control_points_w[i](0);Q(i * 3, 1) = control_points_w[i](1);Q(i * 3, 2) = control_points_w[i](2);Q(i * 3, 9) = 1;Q(i * 3 + 1, 3) = control_points_w[i](0);Q(i * 3 + 1, 4) = control_points_w[i](1);Q(i * 3 + 1, 5) = control_points_w[i](2);Q(i * 3 + 1, 10) = 1;Q(i * 3 + 2, 6) = control_points_w[i](0);Q(i * 3 + 2, 7) = control_points_w[i](1);Q(i * 3 + 2, 8) = control_points_w[i](2);Q(i * 3 + 2, 11) = 1;}blog->write("Q:");blog->write(Q);blog->write("");blog->write("C_c:");blog->write(C_c);blog->write("");Eigen::MatrixXd Q_inv = Q.inverse();blog->write("Q_inv:");blog->write(Q_inv);blog->write("");Eigen::VectorXd ans = Eigen::VectorXd::Zero(12);ans = Q_inv * C_c;blog->write("ans:");blog->write(ans);blog->write("");camera._R(0, 0) = ans(0);camera._R(0, 1) = ans(1);camera._R(0, 2) = ans(2);camera._R(1, 0) = ans(3);camera._R(1, 1) = ans(4);camera._R(1, 2) = ans(5);camera._R(2, 0) = ans(6);camera._R(2, 1) = ans(7);camera._R(2, 2) = ans(8);camera._t(0) = ans(9);camera._t(1) = ans(10);camera._t(2) = ans(11);
}

相关文章:

【三维重建】ePnP

PnP问题应用与一下场景&#xff1a; 已知三维点和对应二维点以及相机相机内参数&#xff0c;可以获取相机外参。 我们介绍其中的一种算法&#xff1a;ePnP 算法流程 1、ePnP算法首先在世界坐标系内寻找4个控制点&#xff0c;记作 C 1 w , C 2 w , C 3 w , C 4 w C_1^w,C_2^w,…...

C++进阶之路:何为运算符重载、赋值运算符重载与前后置++重载(类与对象_中篇)

✨✨ 欢迎大家来访Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭❤&#xff5e;✨✨ &#x1f31f;&#x1f31f; 欢迎各位亲爱的读者&#xff0c;感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢&#xff0c;在这里我会分享我的知识和经验。&am…...

8、python基础知识图谱

...

智慧校园建设规划方案

在信息化浪潮的推动下&#xff0c;智慧校园的建设已成为教育现代化的必然趋势。以创新科技赋能教育&#xff0c;打造智慧校园&#xff0c;旨在提升教学品质&#xff0c;优化管理流程&#xff0c;增强学生体验。构建智慧校园需要具有前瞻性的规划方案&#xff0c;它将以教育为核…...

【深度学习实战—8】:基于MediaPipe的人脸检测

✨博客主页&#xff1a;王乐予&#x1f388; ✨年轻人要&#xff1a;Living for the moment&#xff08;活在当下&#xff09;&#xff01;&#x1f4aa; &#x1f3c6;推荐专栏&#xff1a;【图像处理】【千锤百炼Python】【深度学习】【排序算法】 目录 &#x1f63a;一、Med…...

OSCP学习,布置你的Kali Linux

为什么要写这篇文章&#xff1f; 我是一个OSCP学习者&#xff0c;以教促学。同时也能让各位入门的师傅们更好的了解OSCP这门课程。本人文笔不太好&#xff0c;如果有什么写的不对的地方&#xff0c;师傅们多多指正。 参考资料&#xff1a; OSCP 考试电子书 Linux Basics for…...

PWA离线优先策略:提升用户体验的关键步骤

Progressive Web Apps (PWA) 的离线优先策略是通过Service Worker和Cache API实现的&#xff0c;它允许在没有网络连接时仍然可以访问网站的部分或全部内容。 2500G计算机入门到高级架构师开发资料超级大礼包免费送&#xff01; 1. 创建Service Worker注册文件&#xff08;se…...

网页提示“非私密连接”是为什么?

网页提示“非私密连接”&#xff08;英文提示可能是 "Your connection is not private" 或 "Your connection is not secure"&#xff09;主要是因为浏览器无法验证你正试图访问的网站的SSL/TLS证书&#xff0c;或者是证书存在问题&#xff0c;从而无法建立…...

[自动驾驶技术]-8 Tesla自动驾驶方案之硬件(AI Day 2022)

特斯拉在AI Day 2022先介绍了AI编译器&#xff0c;后面又介绍了Dojo的硬件软件&#xff0c;软件部分和AI编译器有部分重叠&#xff0c;本文介绍还是延用AI Day的思路&#xff0c;分为三部分&#xff1a;AI编译和推理&#xff0c;Dojo硬件&#xff0c;Dojo软件。 特斯拉车道检测…...

人力资源管理信息化系统如何支持企业开展管理诊断?

华恒智信人力资源顾问有限公司致力于帮助企业开展人力资源管理方面的各项提升改进工作&#xff0c;在长期的咨询工作中&#xff0c;最常听到企业提到的问题莫过于管理诊断方面的问题&#xff0c;事实上&#xff0c;很多企业在日常工作中&#xff0c;都意识到企业内部存在管理方…...

Cohere继Command-R+之后发布大模型Aya-23,性能超越 Gemma、Mistral 等,支持中文

前言 近年来&#xff0c;多语言大模型&#xff08;MLLM&#xff09;发展迅速&#xff0c;但大多数模型的性能依然存在显著差距&#xff0c;尤其是在非英语语言方面表现不佳。为了推动多语言自然语言处理技术的发展&#xff0c;Cohere团队发布了新的多语言指令微调模型家族——…...

身为UI设计老鸟,不学点3D,好像要被潮流抛弃啦,卷起来吧。

当前3D原则在UI设计中运用的越来越多&#xff0c;在UI设计中&#xff0c;使用3D元素可以为界面带来以下几个价值&#xff1a; 增强视觉冲击力&#xff1a;3D元素可以通过立体感和逼真的效果&#xff0c;为界面增添视觉冲击力&#xff0c;使得设计更加生动、吸引人&#xff0c;并…...

线代-向量eg3.1 3.2 3.4

...

【C语言】实现贪吃蛇--项目实践(超详细)

前言&#xff1a; 贪吃蛇游戏大家都玩过吧&#xff1f;这次我们要用C语言来亲手制作一个&#xff01;这个项目不仅能让我们复习C语言的知识&#xff0c;还能了解游戏是怎么一步步做出来的。我们会一起完成蛇的移动、食物的生成&#xff0c;还有碰撞检测等有趣的部分。准备好了…...

Elasticsearch 分析器的高级用法一(同义词,高亮搜索)

Elasticsearch 分析器的高级用法一&#xff08;同义词&#xff0c;高亮搜索&#xff09; 同义词简介分析使用同义词案例 高亮搜索高亮搜索策略unifiedplainvh 同义词 简介 在搜索场景中&#xff0c;同义词用来处理不同的查询词&#xff0c;有可能是想表达相同的搜索目标。 例…...

Python 开心消消乐

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…...

mysql - 索引基本知识梳理

mysql索引基本知识梳理 索引介绍 官方介绍索引是帮助MySQL高效获取数据的数据结构, 原理为以空间换时间, mysql的索引采用的是B树的结构 索引的优缺点 优点&#xff1a; 提高查询效率降低数据库IO成本通过索引对数据进行排序, 降低排序成本, 降低CPU消耗 缺点&#xff1a…...

Nginx SSL/TLS配置:搭建安全的HTTPS网站

随着互联网安全性的日益提升&#xff0c;HTTPS已经成为网站安全通信的标配。Nginx作为一款高性能的HTTP和反向代理服务器&#xff0c;支持SSL/TLS协议&#xff0c;使得我们可以轻松地搭建安全的HTTPS网站。下面&#xff0c;我们将详细介绍如何在Nginx上配置SSL/TLS&#xff0c;…...

echarts 折线图流光效果偏移或不显示

x轴数据需要字符串数组...

Redis数据类型(上篇)

前提&#xff1a;&#xff08;key代表键&#xff09; Redis常用的命令 命令作用keys *查看当前库所有的keyexists key判断某个key是否存在type key查看key是什么类型del key 删除指定的keyunlink key非阻塞删除&#xff0c;仅仅将keys从keyspace元数据中删除&#xff0c;真正的…...

云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好&#xff0c;欢迎来到《云原生核心技术》系列的第七篇&#xff01; 在上一篇&#xff0c;我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在&#xff0c;我们就像一个拥有了一块崭新数字土地的农场主&#xff0c;是时…...

多模态2025:技术路线“神仙打架”,视频生成冲上云霄

文&#xff5c;魏琳华 编&#xff5c;王一粟 一场大会&#xff0c;聚集了中国多模态大模型的“半壁江山”。 智源大会2025为期两天的论坛中&#xff0c;汇集了学界、创业公司和大厂等三方的热门选手&#xff0c;关于多模态的集中讨论达到了前所未有的热度。其中&#xff0c;…...

IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)

文章目录 概述HelloWorld 工程C/C配置编译器主配置Makefile脚本烧录器主配置运行结果程序调用栈 任务管理实验实验结果osal 系统适配层osal_task_create 其他实验实验源码内存管理实验互斥锁实验信号量实验 CMISIS接口实验还是得JlINKCMSIS 简介LiteOS->CMSIS任务间消息交互…...

Java面试专项一-准备篇

一、企业简历筛选规则 一般企业的简历筛选流程&#xff1a;首先由HR先筛选一部分简历后&#xff0c;在将简历给到对应的项目负责人后再进行下一步的操作。 HR如何筛选简历 例如&#xff1a;Boss直聘&#xff08;招聘方平台&#xff09; 直接按照条件进行筛选 例如&#xff1a…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

Typeerror: cannot read properties of undefined (reading ‘XXX‘)

最近需要在离线机器上运行软件&#xff0c;所以得把软件用docker打包起来&#xff0c;大部分功能都没问题&#xff0c;出了一个奇怪的事情。同样的代码&#xff0c;在本机上用vscode可以运行起来&#xff0c;但是打包之后在docker里出现了问题。使用的是dialog组件&#xff0c;…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用&#xff1a; 方法一&#xff1a;使用 Homebrew 安装 Git&#xff08;推荐&#xff09; 步骤如下&#xff1a;打开终端&#xff08;Terminal.app&#xff09; 1.安装 Homebrew…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

微服务通信安全:深入解析mTLS的原理与实践

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言&#xff1a;微服务时代的通信安全挑战 随着云原生和微服务架构的普及&#xff0c;服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...