基于平面 marker 的 Bundle Adjustmet
前言
一个二维的 marker 通常有四个角点,如果把四个角点当做独立的三维特征点去参与BA优化,那么需要十二个参数,并且四个角点之间的约束(边长以及正交)还不好加入优化。这篇博客是将一个marker用6自由度的坐标系进行建模,推导了整个Marker的重投影误差函数和雅克比矩阵,并在g2o中进行了实现和集成。代码会开放在我的github,博客的pdf版本也会在代码对应的note文件夹里(貌似csdn对部分latex支持不友好)。这个工作是17年初的时候做的,笔记在草稿箱中存了差不多两年了,现在开放出来希望能帮到有需要的小伙伴。
另外,基于 marker 的 structure from motion 或者 slam 的工作都有对应论文,google一下很容易找到,在这里推荐比较经典的 Mapping and Localization from Planar Markers.
marker BA 公式推导
李代数求导基础
有四种方式进行李代数的求导: gtsam作者笔记里的推导方式,strasdat博士论文里的推导方式,TUM kerl硕士论文里的推导方式,最后就是barfoot的state esitamtion for robotics一书中的推导了。最直观简介的是gtsam和kerl的推导,最完备最可扩展的推导是barfoot的方式,也就是高翔书上的推导。
目的:空间中一点PwP_wPw,通过TcwT_{cw}Tcw转换到相机坐标系下PcP_cPc,高斯牛顿的时候需要不断调整优化TcwT_{cw}Tcw.
这时就有了两个思路:
- 假设Tc′c=exp(δξ^)T_{c'c}=exp(\hat{\delta\xi})Tc′c=exp(δξ^)是微小增量, Tc′w=exp(δξ^)Tcw=exp(δξ^)exp(ξ^)T_{c'w}=exp(\hat{\delta\xi})T_{cw}=exp(\hat{\delta\xi})exp({\hat\xi})Tc′w=exp(δξ^)Tcw=exp(δξ^)exp(ξ^)。注意小增量是直接放在李代数的。在推导前,先熟悉一个性质,下面公式中粗体P\mathbf{P}P是PPP的齐次坐标形式。
ξ^P=[ω^v00][P1]=[ω×P+v0]=[−P^I300][ωv]\hat\xi \mathbf{P}=\begin{bmatrix} \hat{\mathbf{\omega}}& \mathbf{v}\\ \mathbf{0} & \mathbf{0}\end{bmatrix}\begin{bmatrix}P \\ 1 \end{bmatrix}=\begin{bmatrix} \mathbf{\omega}\times P+\mathbf{v}\\ \mathbf{0}\end{bmatrix}=\begin{bmatrix} -\hat P&&\mathbf{I}_3 \\ \mathbf{0} && \mathbf{0}\end{bmatrix}\begin{bmatrix}\mathbf{\omega}\\\mathbf{v}\end{bmatrix}ξ^P=[ω^0v0][P1]=[ω×P+v0]=[−P^0I30][ωv]
有了这个性质,可以开始推导了,推导过程省略齐次坐标最后一行
∂(Pc′)∂(δξ)=∂(exp(δξ^)TcwPw)∂(δξ)≈∂((I+δξ^)Pc)∂(δξ)=∂(δξ^Pc)∂(δξ)=[[−Pc]×,I3]3×6=(0z−y100−z0x010y−x0001)3×6\begin{aligned} \frac{\partial(P_{c'})}{\partial(\delta\xi)} = & \frac{\partial(exp(\hat{\delta\xi})T_{cw}P_w)}{\partial(\delta\xi)} \\\approx & \frac{\partial((I+\hat{\delta\xi})P_c)}{\partial(\delta\xi)} = \frac{\partial(\hat{\delta\xi}P_c)}{\partial(\delta\xi)}=[[-P_c]_{\times},\mathbf{I}_{3}]_{3\times6} \\=& \begin{pmatrix} 0 & z & -y & 1 & 0 &0 \\ -z & 0 & x & 0 & 1 & 0 \\ y & -x & 0 & 0 & 0 & 1 \end{pmatrix}_{3\times 6} \end{aligned} ∂(δξ)∂(Pc′)=≈=∂(δξ)∂(exp(δξ^)TcwPw)∂(δξ)∂((I+δξ^)Pc)=∂(δξ)∂(δξ^Pc)=[[−Pc]×,I3]3×6⎝⎛0−zyz0−x−yx0100010001⎠⎞3×6
这里 [⋅]×[\cdot]_{\times}[⋅]×和(cdot)^\hat{(cdot)}(cdot)^ 都是表示把向量转换成反对称矩阵,采用两种形式纯粹是为了书写清楚,有的时候式子太长了,用hat括不下。 - 另一个思路是Tc′w=exp([δξ+ξ]×)T_{c'w}=exp([\delta\xi+\xi]_{\times})Tc′w=exp([δξ+ξ]×)。这里是直接在李代数上叠加一个微小变量。
∂(exp(ξ^)Pw)∂(δξ)=limδξ→0exp([δξ+ξ]×)Pw−exp(ξ^)Pwδξ\frac{\partial(exp(\hat\xi)P_w)}{\partial(\delta\xi)}=\lim_{\delta\xi\rightarrow0}\frac{exp([\delta\xi+\xi]_{\times})P_w-exp(\hat\xi)P_w}{\delta\xi}∂(δξ)∂(exp(ξ^)Pw)=δξ→0limδξexp([δξ+ξ]×)Pw−exp(ξ^)Pw
注意分子上面减去的那一部分和δξ\delta\xiδξ没关系,可以直接忽视,问题是
exp([δξ+ξ]×)=exp([δξ]×+[ξ]×)≠exp([δξ]×)exp([ξ]×)exp([\delta\xi+\xi]_{\times})= exp([\delta\xi]_{\times}+[\xi]_{\times})\neq exp([\delta\xi]_{\times})exp([\xi]_{\times})exp([δξ+ξ]×)=exp([δξ]×+[ξ]×)=exp([δξ]×)exp([ξ]×)
这是因为矩阵的幂指数可不能随便展开,需要引入专门解决这个问题的BCH公式:
ln(exp(ξ1^)exp(ξ^2))≈{Jℓ(ξ2)−1ξ1+ξ2ifξ1issmallξ1+Jr(ξ1)−1ξ2ifξ2issmallln(exp(\hat{\xi_1})exp(\hat\xi_2))\approx \{ \begin{matrix} \mathbf{J_\ell}(\xi_2)^{-1}\xi_1 + \xi_2 & if\quad \xi_1 \quad is \quad small \\ \xi_1 + \mathbf{J_r}(\xi_1)^{-1}\xi_2 & if\quad \xi_2 \quad is \quad small \end{matrix}ln(exp(ξ1^)exp(ξ^2))≈{Jℓ(ξ2)−1ξ1+ξ2ξ1+Jr(ξ1)−1ξ2ifξ1issmallifξ2issmall具体参见barfoot书公式(7.80)。上面等式中,不妨假设ξ1=δξ\xi_1=\delta\xiξ1=δξ,则有:
exp(δξ^)exp(ξ^)=exp([ξ+Jℓ(ξ)−1δξ]×)exp(\hat{\delta\xi})exp(\hat\xi)=exp([\xi+\mathbf{J_\ell(\xi)^{-1}\delta\xi}]_{\times})exp(δξ^)exp(ξ^)=exp([ξ+Jℓ(ξ)−1δξ]×)或者
exp([δξ+ξ]×)=exp([Jℓ(ξ)δξ]×)exp(ξ^)exp([\delta\xi+\xi]_{\times})=exp([\mathbf{J_\ell(\xi)\delta\xi}]_{\times})exp(\hat\xi)exp([δξ+ξ]×)=exp([Jℓ(ξ)δξ]×)exp(ξ^)
回到求导的公式:
limδξ→0exp([δξ+ξ]×)Pw−exp(ξ^)Pwδξ=limδξ→0exp([Jℓ(ξ)δξ]×)exp(ξ^)Pwδξ=limδξ→0(I+[Jℓ(ξ)δξ]×)exp(ξ^)Pwδξ=limδξ→0[Jℓ(ξ)δξ]×Pcδξ=[[−Pc]×,I3]3×6Jℓ\begin{aligned} \lim_{\delta\xi\rightarrow0}\frac{exp([\delta\xi+\xi]_{\times})P_w-exp(\hat\xi)P_w}{\delta\xi}=& \lim_{\delta\xi\rightarrow0}\frac{exp([\mathbf{J_\ell}(\xi)\delta\xi]_{\times})exp(\hat\xi)P_w}{\delta\xi} \\= & \lim_{\delta\xi\rightarrow0}\frac{(\mathbf{I}+[\mathbf{J_\ell}(\xi)\delta\xi]_{\times})exp(\hat\xi)P_w}{\delta\xi} \\= & \lim_{\delta\xi\rightarrow0}\frac{[\mathbf{J_\ell}(\xi)\delta\xi]_{\times}P_c}{\delta\xi}=[[-P_c]_{\times},\mathbf{I}_{3}]_{3\times6}\mathbf{J_\ell} \end{aligned} δξ→0limδξexp([δξ+ξ]×)Pw−exp(ξ^)Pw===δξ→0limδξexp([Jℓ(ξ)δξ]×)exp(ξ^)Pwδξ→0limδξ(I+[Jℓ(ξ)δξ]×)exp(ξ^)Pwδξ→0limδξ[Jℓ(ξ)δξ]×Pc=[[−Pc]×,I3]3×6Jℓ
上述两种方式都没问题,相差一个Jℓ\mathbf{J_\ell}Jℓ,但是思路1更简单明了,也是gtsam作者采用的推导方式。
Bundle Adjustment中的雅克比
和上节一样,相机位姿为TcwT_{cw}Tcw,世界坐标系一点PwP_wPw,投影方程为
p=(uv)=π(Pc)=(xfxz+cxyfyz+cy)p=\binom{u}{v}=\pi(P_c)=\binom{\frac{xf_x}{z}+c_x}{\frac{yf_y}{z}+c_y}p=(vu)=π(Pc)=(zyfy+cyzxfx+cx)容易得到
∂p∂Pc=(∂u∂x∂u∂y∂u∂z∂v∂x∂v∂y∂v∂z)2×3=(fxz0−xfxz20fyz−yfyz2)2×3\frac{\partial p}{\partial P_c}=\begin{pmatrix} \frac{\partial u}{\partial x} & \frac{\partial u}{\partial y} & \frac{\partial u}{\partial z}\\ \frac{\partial v}{\partial x} & \frac{\partial v}{\partial y} & \frac{\partial v}{\partial z} \end{pmatrix}_{2\times 3}=\begin{pmatrix} \frac{f_x}{ z} & 0 & \frac{-xf_x}{z^2}\\ 0 & \frac{f_y}{z} & \frac{-yf_y}{z^2} \end{pmatrix}_{2\times 3}∂Pc∂p=(∂x∂u∂x∂v∂y∂u∂y∂v∂z∂u∂z∂v)2×3=(zfx00zfyz2−xfxz2−yfy)2×3
其中Pc=(x,y,z)T\color{red}{P_c=(x,y,z)^T}Pc=(x,y,z)T.
图像坐标误差对相机位姿增量求导
世界坐标系中3d点到像素坐标的转换为:
p=(uv)=π(TcwPw)p=\binom{u}{v}=\pi(T_{cw}P_w)p=(vu)=π(TcwPw)联立上文的两个偏导得
∂p∂(δξ)=∂p∂Pc⋅∂Pc∂(δξ)=(−xyz2fx(1+x2z2)fx−yzfx1zfx0−xz2fx−(1+y2z2)fyxyz2fyxzfy01zfy−yz2fy)2×6(1)\begin{aligned} \frac{\partial p}{\partial(\delta\xi)}=&\frac{\partial p}{\partial P_c}\cdot\frac{\partial P_c}{\partial(\delta\xi)} \\ =& \begin{pmatrix} -\frac{xy}{ z^2}f_x & (1+\frac{x^2}{z^2})f_x & -\frac{y}{z}f_x & \frac{1}{z}f_x & 0 & -\frac{x}{z^2}f_x\\ -(1+\frac{y^2}{z^2})f_y & \frac{xy}{z^2}f_y & \frac{x}{z}f_y & 0 & \frac{1}{z}f_y & -\frac{y}{z^2}f_y\end{pmatrix}_{2\times 6} \end{aligned}\qquad(1)∂(δξ)∂p==∂Pc∂p⋅∂(δξ)∂Pc(−z2xyfx−(1+z2y2)fy(1+z2x2)fxz2xyfy−zyfxzxfyz1fx00z1fy−z2xfx−z2yfy)2×6(1)
图像坐标误差对坐标PwP_wPw求导
Pc=(xyz)=TcwPw=(xwr1+ywr2+zwr3+t1xwr4+ywr5+zwr6+t2xwr7+ywr8+zwr9+t3)P_c =\begin{pmatrix} x\\y \\z \end{pmatrix}= T_{cw}P_w = \begin{pmatrix} x_wr_1+y_wr_2+z_wr_3+t_1 \\x_wr_4+y_wr_5+z_wr_6+t_2\\x_wr_7+y_wr_8+z_wr_9+t_3\end{pmatrix}Pc=⎝⎛xyz⎠⎞=TcwPw=⎝⎛xwr1+ywr2+zwr3+t1xwr4+ywr5+zwr6+t2xwr7+ywr8+zwr9+t3⎠⎞
∂Pc∂Pw=(r1r2r3r4r5r6r7r8r9)=R\frac{\partial P_c}{\partial P_w} = \begin{pmatrix} r_1 & r_2 & r_3 \\r_4 & r_5 & r_6\\ r_7 & r_8 & r_9\end{pmatrix}=\mathbf{R}∂Pw∂Pc=⎝⎛r1r4r7r2r5r8r3r6r9⎠⎞=R
∂p∂(Pw)=∂p∂Pc⋅∂Pc∂(Pw)=(fxz0−xfxz20fyz−yfyz2)2×3⋅R\begin{aligned} \frac{\partial p}{\partial(P_w)}=&\frac{\partial p}{\partial P_c}\cdot\frac{\partial P_c}{\partial(P_w)} \\ =& \begin{pmatrix} \frac{f_x}{ z} & 0 & \frac{-xf_x}{z^2}\\ 0 & \frac{f_y}{z} & \frac{-yf_y}{z^2} \end{pmatrix}_{2\times 3}\cdot\mathbf{R} \end{aligned}∂(Pw)∂p==∂Pc∂p⋅∂(Pw)∂Pc(zfx00zfyz2−xfxz2−yfy)2×3⋅R
注意,上面的导数有的程序里面在前面都多了一个负号,这是由误差向量的定义是e=p−pimge= p - p_{img}e=p−pimg还是e=pimg−pe= p_{img} - pe=pimg−p造成的,其中pimgp_{img}pimg是检测到的图像坐标,ppp是理论计算得到的坐标,上面我们采用的误差向量是e=p−pimge= p - p_{img}e=p−pimg,orbslam中采用的是e=pimg−pe= p_{img} - pe=pimg−p。
marker bundle adjustment中的雅克比
marker作为一个平面,四个角点之间有空间位置的约束,因此不能简单把marker的ba问题当成四个点的ba问题。在这里,ba的时候,我们采用优化调整marker坐标系姿态来调整marker各角点的空间位置,优化变量从角点的位置变成了marker坐标系的6个变量。
marker以marker中心为原点,垂直于纸面向上为z,正对marker水平向右为x轴。marker坐标系到世界坐标系的转换TmwT_{mw}Tmw。
marker边长为size=2ssize=2ssize=2s,四个角点PmiP_{m}^{i}Pmi在marker坐标系中的表示如下图所示。
已知图像某个角点坐标为 pimg=(u,v)Tp_{img}=(u,v)^Tpimg=(u,v)T,为了和orbslam代码统一,这里我们采用 e=pimg−pe= p_{img} - pe=pimg−p。
p=π(TcwTmw−1Pm)p=\pi(T_{cw}T^{-1}_{mw}P_m)p=π(TcwTmw−1Pm)
所以偏导数是两部分,一个是对相机的 TcwT_{cw}Tcw,一个是对marker的 TmwT_{mw}Tmw
角点图像坐标误差对相机位姿增量求导
和之前单点ba中的雅克比推导一样,这里可以直接将角点坐标PmiP_m^{i}Pmi转换到相机坐标系下,Pci=TcmPmi\mathbf{P}_c^i=T_{cm}\mathbf{P}_m^iPci=TcmPmi,雅克比的计算只需要把坐标PciP_c^iPci代入公式1即可,同时由于误差向量多了个负号,所以公式1前面要加一个负号。
角点图像坐标对marker位姿增量的求导
先把求雅克比时最难部分的表达式写出来:
Pc=TcwTmw−1Pm\mathbf{P}_c=T_{cw}T^{-1}_{mw}\mathbf{P}_mPc=TcwTmw−1Pm
δξ=ξm′m→ξm′w=ξmw+δξ\delta\xi=\xi_{m'm}\rightarrow \xi_{m'w}=\xi_{mw}+\delta\xiδξ=ξm′m→ξm′w=ξmw+δξ
有了表达式就可以依葫芦画瓢,跟思路1一样,推导过程如下:不过前面推导的时候,我们省略了齐次坐标的最后一行,这里我们先不省略。
limδξ→0∂Pc∂(δξ)=limδξ→0exp(ξ^cw)[exp(δξ^)exp(ξ^mw)]−1Pm−exp(ξ^cw)[exp(ξ^mw)]−1Pmδξ=limδξ→0exp(ξ^cw)exp(ξ^mw)−1exp(δξ^)−1Pmδξ=limδξ→0TcwTwmexp(−δξ^)Pmδξ=limδξ→0Tcm(I−δξ^)Pmδξ=limδξ→0Tcm(−δξ^)Pmδξ=Tcm∗[[Pm]×−I300]=[Rcmtcm01][[Pm]×−I300]\begin{aligned} \lim_{\delta\xi\rightarrow0}\frac{\partial \mathbf{P_c}}{\partial(\delta\xi)} =& \lim_{\delta\xi\rightarrow0}\frac{exp(\hat{\xi}_{cw})[exp(\hat{\delta\xi})exp(\hat{\xi}_{mw})]^{-1}\mathbf{P_m}-exp(\hat{\xi}_{cw})[exp(\hat{\xi}_{mw})]^{-1}\mathbf{P_m}}{\delta\xi} \\ =& \lim_{\delta\xi\rightarrow0}\frac{exp(\hat{\xi}_{cw})exp(\hat{\xi}_{mw})^{-1}exp(\hat{\delta\xi})^{-1}\mathbf{P_m}}{\delta\xi} \\ =& \lim_{\delta\xi\rightarrow0}\frac{T_{cw}T_{wm}exp(-\hat{\delta\xi})\mathbf{P_m}}{\delta\xi} \\ =& \lim_{\delta\xi\rightarrow0}\frac{T_{cm}(I-\hat{\delta\xi})\mathbf{P_m}}{\delta\xi} \\ =& \lim_{\delta\xi\rightarrow0}\frac{T_{cm}(-\hat{\delta\xi})\mathbf{P_m}}{\delta\xi} \\ =& {T_{cm}*\begin{bmatrix} [P_m]_{\times}&& -\mathbf{I}_{3}\\ \mathbf{0}&& \mathbf{0}\end{bmatrix}} \\=& \begin{bmatrix} \mathbf{R}_{cm} && \mathbf{t}_{cm}\\ \mathbf{0}&& 1\end{bmatrix}\begin{bmatrix} [P_m]_{\times}&& -\mathbf{I}_{3}\\ \mathbf{0}&& \mathbf{0}\end{bmatrix} \end{aligned}δξ→0lim∂(δξ)∂Pc=======δξ→0limδξexp(ξ^cw)[exp(δξ^)exp(ξ^mw)]−1Pm−exp(ξ^cw)[exp(ξ^mw)]−1Pmδξ→0limδξexp(ξ^cw)exp(ξ^mw)−1exp(δξ^)−1Pmδξ→0limδξTcwTwmexp(−δξ^)Pmδξ→0limδξTcm(I−δξ^)Pmδξ→0limδξTcm(−δξ^)PmTcm∗[[Pm]×0−I30][Rcm0tcm1][[Pm]×0−I30]
去掉最后一行对应的齐次坐标,可以得到没有其次坐标时的偏导数如下:
∂Pc∂(δξ)=Rcm[[Pm]×−I3]\frac{\partial P_c}{\partial(\delta\xi)} = \mathbf{R}_{cm}\begin{bmatrix} [P_m]_{\times}&& -\mathbf{I}_{3}\end{bmatrix}∂(δξ)∂Pc=Rcm[[Pm]×−I3]
到这一步就知道为啥不省略齐次坐标最后一行了
∂p∂(δξ)=∂p∂Pc⋅∂Pc∂(δξ)=(fxz0−xfxz20fyz−yfyz2)2×3⋅Rcm⋅(0−zmym−100zm0−xm0−10−ymxm000−1)3×6(2)\begin{aligned} \frac{\partial p}{\partial(\delta\xi)}=&\frac{\partial p}{\partial P_c}\cdot\frac{\partial P_c}{\partial(\delta\xi)} \\ =& \begin{pmatrix} \frac{f_x}{ z} & 0 & \frac{-xf_x}{z^2}\\ 0 & \frac{f_y}{z} & \frac{-yf_y}{z^2} \end{pmatrix}_{2\times 3}\cdot\mathbf{R}_{cm}\cdot\begin{pmatrix} 0 & -z_m & y_m & -1 & 0 &0 \\ z_m & 0 & -x_m & 0 & -1 & 0 \\ -y_m & x_m & 0 & 0 & 0 & -1 \end{pmatrix}_{3\times 6} \end{aligned}\qquad(2)∂(δξ)∂p==∂Pc∂p⋅∂(δξ)∂Pc(zfx00zfyz2−xfxz2−yfy)2×3⋅Rcm⋅⎝⎛0zm−ym−zm0xmym−xm0−1000−1000−1⎠⎞3×6(2)
注意,写到程序里的时候,上面公式(2)也要再取个负号,因为误差向量为e=pimg−pe=p_{img}-pe=pimg−p
基于平面 marker 的 Bundle Adjustmet相关推荐
- 利用计算机绘制地质图的思路和方法,基于平面地质图的三维地质建模方法研究...
摘要: 平面地质图综合了地质野外勘察工作成果与地质专家知识,揭示了地区的岩石.地层和地质构造等信息,是人们了解区域地质最易获取和最直接的数据源.研究基于平面地质图的三维地质体建模方法,能够有效地解决缺 ...
- RP-VIO:面向动态环境的基于平面的鲁棒视惯融合里程计(IROS2021)
RP-VIO: Robust Plane-based Visual-Inertial Odometry for Dynamic Environments 来源:Ram K, Kharyal C, Ha ...
- 基于平面的约束2D激光雷达和相机的联合标定(2D Laser and Camera Calibration )原理及项目代码具体使用——旷视
1 基于平面的约束2D激光雷达和相机的联合标定(2D Laser and Camera Calibration )原理 这是旷视做的一个关于2D激光雷达和相机的联合标定算法,在看这个标定算法之前,你可 ...
- 基于平面标靶的faro点云拼接流程(全站仪或RTK)
基于平面标靶的faro点云拼接流程(全站仪或RTK) 一.主扫描站不布置标靶情况: 1.导入标靶坐标 2.提取主站点标靶 3.利用标靶,使用"基于目标"的拼接方式拼接主站点 固定除 ...
- 基于MATLAB的点云建筑物轮廓提取与基于平面探测法的点云建筑物提取
博客中轮廓提取使用的点云数据 建筑物平面检测使用的点云数据 **两个小的点云处理实验项目,(源码资源****有常(注意目前是有常哦)私我vx:xdsqczkyqs713 ,第一个项目点云建筑物轮廓提取 ...
- 鱼眼相机中基于平面假设的光心偏移校正
这篇文章主要是对 Hugin 开源软件中 <libpano/math.c> 的 plane_transfer_to_camera() 和 plane_transfer_from_camer ...
- ICRA 2021 | π-LSAM:基于平面优化的激光雷达平滑与建图算法
点击上方"3D视觉工坊",选择"星标" 干货第一时间送达 作者丨泡泡机器人 来源丨 泡泡机器人SLAM 标题:π-LSAM: LiDAR Smoothing a ...
- 基于地平面的单目视觉里程计绝对尺度估计
点云PCL免费知识星球,点云论文速读. 文章:Ground Plane based Absolute Scale Estimation for Monocular Visual Odometry 作者 ...
- 29 基于PCL的点云平面分割拟合算法技术路线(针对有噪声的点云数据)
0 引言 最近项目中用到了基于PCL开发的基于平面的点云和CAD模型的配准算法,点云平面提取采用的算法如下. 1 基于PCL的点云平面分割拟合算法 2 参数及其意义介绍 (1)点云下采样 1. 参数: ...
最新文章
- 如果地府需要一个后台管理系统,你会如何设计?
- 解决navicat 导出excel数字为科学计数法问题
- leetcode刷题总结(持续更新)
- MATLAB 的运算符
- PHP中的const
- 如何在SQL Server查询语句(Select)中检索存储过程(Store Procedure)的结果集
- Linux 内核源代码的目录结构
- CSDN博客如何在有序序列中缩进代码段或图片
- java动态数组的实现的_基于Java的动态数组分析与实现
- 2d头发_3D打印毛囊突破性进展!“头发工厂”将成秃顶的救星
- 11.大数据架构详解:从数据获取到深度学习 --- 大数据云化
- linux ssh x11,ssh服务器的x11 forwarding报错的解决
- Windows游戏编程大师技巧第二版学习笔记之第一章
- 《管理的实践》全书结构
- 玉米社:网站打开慢,如何提升网站打开速度?
- Doctype作用?标准模式与兼容模式各有什么区别?
- 两条纵坐标折线图绘制
- ROS2利用cartographer算法进行激光建图
- 盘点互联网大佬背后的女人,最后一个你肯定认识
- 什么是EEPROM?和ROM有区别吗?//2021-2-18