单目矩阵求解修改
- 归一化直接线性变换
- 通过计算一个相似变换T,将质心转换到原点,并缩放到离原点的平均距离为 2 \sqrt{2} 2,将点集合标准化 u i = [ u i ′ , v i ′ ] T ui = [u_i', v_i']^T ui=[ui′,vi′]T
- 同样地,通过计算相似变换T’对点 u ′ = [ u i ′ , v i ′ ] T u' = [u'_i,v'_i]^T u′=[ui′,vi′]T进行归一化
- 对归一化点应用基本的DLT算法,得到单应矩阵H‘
- 去归一化得到单应性: H = T ′ − 1 H ’ T H= T'^{-1}H’T H=T′−1H’T
- 初始 f x , f y f_x,f_y fx,fy求解修改
opencv做了一些简化
内参矩阵 : A = [ α γ u 0 0 β v 0 0 0 1 ] A=\left[\begin{array}{ccc}\alpha & \gamma & u_{0} \\ 0 & \beta & v_{0} \\ 0 & 0 & 1 \end{array}\right] A=⎣⎡α00γβ0u0v01⎦⎤ 图像坐标和像素坐标系存在一个比例关系,设图像x方向每毫米有 α \alpha α个像素,y方向每毫米有 β \beta β个像素,则有 u = u 0 + x ⋅ α u=u_{0}+x \cdot \alpha u=u0+x⋅α, v = v 0 + y ⋅ β v=v_{0}+y \cdot \beta v=v0+y⋅β
- 假设 γ = 0 \gamma=0 γ=0 (因为只需要初始解,不需要那么精确)
- 不直接求解光心位置,而是假设其为图像的一半(将 u 0 u_0 u0, v 0 v_0 v0假设为图片的中心)
见张正友求解内参矩阵部分
B
=
λ
A
−
T
A
−
1
=
λ
[
B
11
B
12
B
13
B
21
B
22
B
23
B
31
B
32
B
33
]
=
λ
[
1
α
2
0
−
u
0
α
2
0
1
β
2
−
v
0
β
2
−
u
0
α
2
−
v
0
β
2
u
0
2
α
2
+
v
0
2
β
2
+
1
]
\begin{aligned} B=\lambda A^{-T} A^{-1} &=\lambda\left[\begin{array}{lll} B_{11} & B_{12} & B_{13} \\ B_{21} & B_{22} & B_{23} \\ B_{31} & B_{32} & B_{33} \end{array}\right] \\ &=\lambda\left[\begin{array}{ccc} \frac{1}{\alpha^{2}} & 0 & \frac{-u_{0}}{\alpha^{2}} \\ 0 & \frac{1}{\beta^{2}} & -\frac{v_{0}}{\beta^{2}} \\ \frac{-u_{0}}{\alpha^{2}} & -\frac{v_{0}}{\beta^{2}} & \frac{u_{0}^{2}}{\alpha^{2}}+\frac{v_{0}^{2}}{\beta^{2}}+1 \end{array}\right] \end{aligned}
B=λA−TA−1=λ⎣⎡B11B21B31B12B22B32B13B23B33⎦⎤=λ⎣⎢⎡α210α2−u00β21−β2v0α2−u0−β2v0α2u02+β2v02+1⎦⎥⎤
由于
u
0
u_0
u0,
v
0
v_0
v0是已知项,这样我们只需要求解两个参数就好
b
=
[
B
11
B
22
]
=
[
1
α
2
1
β
2
]
b=\left[\begin{array}{ll} B_{11} & B_{22} \end{array}\right]=\left[\begin{array}{ll} \frac{1}{\alpha^{2}} & \frac{1}{\beta^{2}} \end{array}\right]
b=[B11B22]=[α21β21]
我们知道,张正友标定法中单应矩阵对应
H
=
A
[
r
1
r
2
t
]
↓
H
=
[
α
0
u
0
0
β
v
0
0
0
1
]
[
r
11
r
21
t
1
r
12
r
22
t
2
r
13
r
23
t
3
]
↓
H
=
[
α
r
11
+
u
0
r
13
α
r
21
+
u
0
r
23
α
t
1
+
u
0
t
3
β
r
12
+
v
0
r
13
β
r
22
+
v
0
r
23
β
t
1
+
v
0
t
3
r
13
r
23
t
3
]
\begin{gathered} H=A\left[r_{1} r_{2} t\right] \\ \downarrow \\ H=\left[\begin{array}{ccc} \alpha & 0 & u_{0} \\ 0 & \beta & v_{0} \\ 0 & 0 & 1 \end{array}\right]\left[\begin{array}{lll} r_{11} & r_{21} & t_{1} \\ r_{12} & r_{22} & t_{2} \\ r_{13} & r_{23} & t_{3} \end{array}\right] \\ \downarrow \\ H=\left[\begin{array}{ccc} \alpha r_{11}+u_{0} r_{13} & \alpha r_{21}+u_{0} r_{23} & \alpha t_{1}+u_{0} t_{3} \\ \beta r_{12}+v_{0} r_{13} & \beta r_{22}+v_{0} r_{23} & \beta t_{1}+v_{0} t_{3} \\ r_{13} & r_{23} & t_{3} \end{array}\right] \end{gathered}
H=A[r1r2t]↓H=⎣⎡α000β0u0v01⎦⎤⎣⎡r11r12r13r21r22r23t1t2t3⎦⎤↓H=⎣⎡αr11+u0r13βr12+v0r13r13αr21+u0r23βr22+v0r23r23αt1+u0t3βt1+v0t3t3⎦⎤
opencv 做了这样一个操作
H[0] -= H[6]*a[2]; // H[6] = r13,a[2] = u0,H[0] = \alpha * r11
H[1] -= H[7]*a[2];
H[2] -= H[8]*a[2];
H[3] -= H[6]*a[5];
H[4] -= H[7]*a[5];
H[5] -= H[8]*a[5];
这里
a
[
2
]
=
u
0
,
a
[
5
]
=
v
0
\begin{aligned} &a[2]=u_{0} , &a[5]=v_{0} \end{aligned}
a[2]=u0,a[5]=v0
经过上面的操作,
H
H
H 变为
H
=
[
α
r
11
α
r
21
α
t
1
β
r
12
β
r
22
β
t
1
r
13
r
23
t
3
]
H=\left[\begin{array}{ccc} \alpha r_{11} & \alpha r_{21} & \alpha t_{1} \\ \beta r_{12} & \beta r_{22} & \beta t_{1} \\ r_{13} & r_{23} & t_{3} \end{array}\right]
H=⎣⎡αr11βr12r13αr21βr22r23αt1βt1t3⎦⎤
修改形式,有
H
=
[
h
v
j
]
=
[
h
0
v
0
j
0
h
1
v
1
j
1
h
2
v
2
j
2
]
=
[
α
r
11
α
r
21
α
t
1
β
r
12
β
r
22
β
t
1
r
13
r
23
t
3
]
H=[h v j]=\left[\begin{array}{lll} h_{0} & v_{0} & j_{0} \\ h_{1} & v_{1} & j_{1} \\ h_{2} & v_{2} & j_{2} \end{array}\right]=\left[\begin{array}{ccc} \alpha r_{11} & \alpha r_{21} & \alpha t_{1} \\ \beta r_{12} & \beta r_{22} & \beta t_{1} \\ r_{13} & r_{23} & t_{3} \end{array}\right]
H=[hvj]=⎣⎡h0h1h2v0v1v2j0j1j2⎦⎤=⎣⎡αr11βr12r13αr21βr22r23αt1βt1t3⎦⎤
d
1
=
h
+
v
2
=
[
α
r
11
+
α
r
21
2
β
r
12
+
β
r
22
2
r
13
+
r
23
2
]
d_{1}=\frac{h+v}{2}=\left[\frac{\alpha r_{11}+\alpha r_{21}}{2} \frac{\beta r_{12}+\beta r_{22}}{2} \frac{r_{13}+r_{23}}{2}\right]
d1=2h+v=[2αr11+αr212βr12+βr222r13+r23]
d
2
=
h
−
v
2
=
[
α
r
11
−
α
r
21
2
β
r
12
−
β
r
22
2
r
13
−
r
23
2
]
d_{2}=\frac{h-v}{2}=\left[\frac{\alpha r_{11}-\alpha r_{21}}{2} \frac{\beta r_{12}-\beta r_{22}}{2} \frac{r_{13}-r_{23}}{2}\right]
d2=2h−v=[2αr11−αr212βr12−βr222r13−r23]
由使用旋转矩阵的正交性(任意两列,任意两行的内积都为0),构建方程组
[
h
0
v
0
h
1
v
1
d
10
d
20
d
11
d
21
]
[
1
α
2
1
β
2
]
=
[
−
h
2
v
2
−
d
12
d
22
]
\left[\begin{array}{cc} h_{0} v_{0} & h_{1} v_{1} \\ d_{10} d_{20} & d_{11} d_{21} \end{array}\right]\left[\begin{array}{c} \frac{1}{\alpha^{2}} \\ \frac{1}{\beta^{2}} \end{array}\right]=\left[\begin{array}{c} -h_{2} v_{2} \\ -d_{12} d_{22} \end{array}\right]
[h0v0d10d20h1v1d11d21][α21β21]=[−h2v2−d12d22]
代入有(目的是构建一个
α
2
\alpha^{2}
α2与
β
2
\beta^{2}
β2相关的函数)
[
α
2
r
11
r
12
β
2
r
12
r
22
α
2
r
11
2
−
α
2
r
21
2
β
2
r
12
2
−
β
2
r
22
2
]
[
1
α
2
1
β
2
]
=
[
r
11
r
21
+
r
12
r
22
r
11
2
−
r
21
2
+
r
12
2
−
r
22
2
]
=
[
−
r
13
r
23
−
(
r
13
2
−
r
23
2
]
\left[\begin{array}{cc} \alpha^{2} r_{11} r_{12} & \beta^{2} r_{12} r_{22} \\ \alpha^{2} r_{11}^{2}-\alpha^{2} r_{21}^{2} & \beta^{2} r_{12}^{2}-\beta^{2} r_{22}^{2} \end{array}\right]\left[\begin{array}{c} \frac{1}{\alpha^{2}} \\ \frac{1}{\beta^{2}} \end{array}\right]=\left[\begin{array}{c} r_{11} r_{21}+r_{12} r_{22} \\ r_{11}^{2}-r_{21}^{2}+r_{12}^{2}-r_{22}^{2} \end{array}\right]=\left[\begin{array}{c} -r_{13} r_{23} \\ -\left(r_{13}^{2}-r_{23}^{2}\right. \end{array}\right]
[α2r11r12α2r112−α2r212β2r12r22β2r122−β2r222][α21β21]=[r11r21+r12r22r112−r212+r122−r222]=[−r13r23−(r132−r232]
求解上述线性方程即可得对应的相机焦距
迭代去畸变
opencv 采用一种迭代的方式来去畸变,其更新公式如下
x
n
+
1
=
f
(
x
n
)
x_{n+1}=f\left(x_{n}\right)
xn+1=f(xn)
DLT算法
不考虑相机畸变,有
s
[
u
v
1
]
=
A
[
R
T
]
[
X
w
Y
W
Z
W
1
]
=
P
3
×
4
[
X
w
Y
W
Z
W
1
]
=
[
p
11
p
12
p
13
p
14
p
21
p
22
p
23
p
24
p
31
p
32
p
33
p
34
0
0
0
1
]
[
X
w
Y
W
Z
W
1
]
s\left[\begin{array}{c} u \\ v \\ 1 \end{array}\right]=\mathbf{A}\left[\begin{array}{ll} R & T \end{array}\right]\left[\begin{array}{c} X_{w} \\ Y_{W} \\ Z_{W} \\ 1 \end{array}\right]=P_{3 \times 4}\left[\begin{array}{c} X_{w} \\ Y_{W} \\ Z_{W} \\ 1 \end{array}\right]=\left[\begin{array}{cccc} p_{11} & p_{12} & p_{13} & p_{14} \\ p_{21} & p_{22} & p_{23} & p_{24} \\ p_{31} & p_{32} & p_{33} & p_{34} \\ 0 & 0 & 0 & 1 \end{array}\right]\left[\begin{array}{c} X_{w} \\ Y_{W} \\ Z_{W} \\ 1 \end{array}\right]
s⎣⎡uv1⎦⎤=A[RT]⎣⎢⎢⎡XwYWZW1⎦⎥⎥⎤=P3×4⎣⎢⎢⎡XwYWZW1⎦⎥⎥⎤=⎣⎢⎢⎡p11p21p310p12p22p320p13p23p330p14p24p341⎦⎥⎥⎤⎣⎢⎢⎡XwYWZW1⎦⎥⎥⎤
同样,我们对上式展开,有
{
s
=
p
31
X
w
+
p
32
Y
w
+
p
33
Z
w
+
p
34
p
11
X
w
+
p
12
Y
w
+
p
13
Z
w
+
p
14
−
p
31
u
X
w
−
p
32
u
Y
w
−
p
33
u
Z
w
−
p
34
u
=
0
p
21
X
w
+
p
22
Y
w
+
p
23
Z
w
+
p
24
−
p
31
v
X
w
−
p
32
v
Y
w
−
p
33
v
Z
w
−
p
34
v
=
0
\left\{\begin{array}{l} s=p_{31} X_{w}+p_{32} Y_{w}+p_{33} Z_{w}+p_{34} \\ p_{11} X_{w}+p_{12} Y_{w}+p_{13} Z_{w}+p_{14}-p_{31} u X_{w}-p_{32} u Y_{w}-p_{33} u Z_{w}-p_{34} u=0 \\ p_{21} X_{w}+p_{22} Y_{w}+p_{23} Z_{w}+p_{24}-p_{31} v X_{w}-p_{32} v Y_{w}-p_{33} v Z_{w}-p_{34} v=0 \end{array}\right.
⎩⎨⎧s=p31Xw+p32Yw+p33Zw+p34p11Xw+p12Yw+p13Zw+p14−p31uXw−p32uYw−p33uZw−p34u=0p21Xw+p22Yw+p23Zw+p24−p31vXw−p32vYw−p33vZw−p34v=0
写成矩阵形式有
[
X
Y
Z
1
0
0
0
0
−
u
X
−
u
Y
−
u
Z
−
u
0
0
0
0
X
Y
Z
1
−
u
X
−
u
Y
−
u
Z
−
u
]
[
p
11
p
12
p
13
p
14
p
21
p
22
p
23
p
24
p
31
p
32
p
33
p
34
]
=
0
\left[\begin{array}{ccccccccccc} X & Y & Z & 1 & 0 & 0 & 0 & 0 & -u X & -u Y & -u Z & -u \\ 0 & 0 & 0 & 0 & X & Y & Z & 1 & -u X & -u Y & -u Z & -u \end{array}\right]\left[\begin{array}{l} p_{11} \\ p_{12} \\ p_{13} \\ p_{14} \\ p_{21} \\ p_{22} \\ p_{23} \\ p_{24} \\ p_{31} \\ p_{32} \\ p_{33} \\ p_{34} \end{array}\right]=0
[X0Y0Z0100X0Y0Z01−uX−uX−uY−uY−uZ−uZ−u−u]⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎢⎡p11p12p13p14p21p22p23p24p31p32p33p34⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎥⎤=0
上式依然使用SVD分解求解即可。
畸变修改
我们之前定义的畸变形式如下
x
distorted
=
x
(
1
+
k
1
r
2
+
k
2
r
4
+
k
3
r
6
)
+
2
p
1
x
y
+
p
2
(
r
2
+
2
x
2
)
y
distorted
=
y
(
1
+
k
1
r
2
+
k
2
r
4
+
k
3
r
6
)
+
p
1
(
r
2
+
2
y
2
)
+
2
p
2
x
y
\begin{aligned} x_{\text {distorted }} &=x\left(1+k_{1} r^{2}+k_{2} r^{4}+k_{3} r^{6}\right)+2 p_{1} x y+p_{2}\left(r^{2}+2 x^{2}\right) \\ y_{\text {distorted }} &=y\left(1+k_{1} r^{2}+k_{2} r^{4}+k_{3} r^{6}\right)+p_{1}\left(r^{2}+2 y^{2}\right)+2 p_{2} x y \end{aligned}
xdistorted ydistorted =x(1+k1r2+k2r4+k3r6)+2p1xy+p2(r2+2x2)=y(1+k1r2+k2r4+k3r6)+p1(r2+2y2)+2p2xy
- 薄透镜畸变
Opencv 增加了薄透樈畸变,其定义如下
δ
x
=
s
1
r
2
+
s
2
r
4
δ
y
=
s
3
r
2
+
s
4
r
4
\begin{aligned} &\delta x=s_{1} r^{2}+s_{2} r^{4} \\ &\delta y=s_{3} r^{2}+s_{4} r^{4} \end{aligned}
δx=s1r2+s2r4δy=s3r2+s4r4
则总畸变形式为
x
distorted
=
x
(
1
+
k
1
r
2
+
k
2
r
4
+
k
3
r
6
)
+
2
p
1
x
y
+
p
2
(
r
2
+
2
x
2
)
+
s
1
r
2
+
s
2
r
4
y
distorted
=
y
(
1
+
k
1
r
2
+
k
2
r
4
+
k
3
r
6
)
+
p
1
(
r
2
+
2
y
2
)
+
2
p
2
x
y
+
s
3
r
2
+
s
4
r
4
\begin{aligned} &x_{\text {distorted }}=x\left(1+k_{1} r^{2}+k_{2} r^{4}+k_{3} r^{6}\right)+2 p_{1} x y+p_{2}\left(r^{2}+2 x^{2}\right)+s_{1} r^{2}+s_{2} r^{4} \\ &y_{\text {distorted }}=y\left(1+k_{1} r^{2}+k_{2} r^{4}+k_{3} r^{6}\right)+p_{1}\left(r^{2}+2 y^{2}\right)+2 p_{2} x y+s_{3} r^{2}+s_{4} r^{4} \end{aligned}
xdistorted =x(1+k1r2+k2r4+k3r6)+2p1xy+p2(r2+2x2)+s1r2+s2r4ydistorted =y(1+k1r2+k2r4+k3r6)+p1(r2+2y2)+2p2xy+s3r2+s4r4
- Tilted Model
理想成像平面和实际成像平面的倾斜
为了描述安装平面和成像平面可能存在的倾斜, opencv 也增加了倾斜模型,其使用绕 x \mathrm{x} x 、y轴的两个旋 转角 θ x θ y \theta_{x} \theta_{y} θxθy 来描述理想图像坐标系到实际图像坐标系之间 (和像素坐标系贴合)投影的结果,作用在我们 上述的畸变之后,其定义如下
opencv使用了\taox,\taoy,而不是 θ x θ y \theta_{x} \theta_{y} θxθy。注意这里的正负号
mat
Rot
X
=
[
1
0
0
0
cos
θ
x
sin
θ
x
0
−
sin
θ
x
cos
θ
x
]
matRot
Y
=
[
cos
θ
y
0
−
sin
θ
y
0
1
0
sin
θ
y
0
cos
θ
y
]
\begin{aligned} \operatorname{mat} \operatorname{Rot} \mathrm{X} &=\left[\begin{array}{ccc} 1 & 0 & 0 \\ 0 & \cos \theta_{x} & \sin \theta_{x} \\ 0 & -\sin \theta_{x} & \cos \theta_{x} \end{array}\right] \\ \operatorname{matRot} \mathrm{Y} &=\left[\begin{array}{ccc} \cos \theta_{y} & 0 & -\sin \theta_{y} \\ 0 & 1 & 0 \\ \sin \theta_{y} & 0 & \cos \theta_{y} \end{array}\right] \end{aligned}
matRotXmatRotY=⎣⎡1000cosθx−sinθx0sinθxcosθx⎦⎤=⎣⎡cosθy0sinθy010−sinθy0cosθy⎦⎤
需要注意的是,这里的角度和我们常规定义是相反的,因为该模型定义是从畸变成像到理想像面的变换,因此我们投影时用的是其逆矩阵。按照先Y后X的顺序,我们有总的旋转矩阵
R
=
[
cos
θ
y
sin
θ
y
sin
θ
x
−
sin
θ
y
cos
x
0
cos
θ
x
sin
θ
x
sin
θ
y
−
cos
θ
y
sin
θ
x
cos
θ
x
cos
θ
y
]
R=\left[\begin{array}{ccc} \cos \theta_{y} & \sin \theta_{y} \sin \theta_{x} & -\sin \theta_{y} \cos x \\ 0 & \cos \theta_{x} & \sin \theta_{x} \\ \sin \theta_{y} & -\cos \theta_{y} \sin \theta_{x} & \cos \theta_{x} \cos \theta_{y} \end{array}\right]
R=⎣⎡cosθy0sinθysinθysinθxcosθx−cosθysinθx−sinθycosxsinθxcosθxcosθy⎦⎤
那么对于点
[
0
,
0
,
1
]
[0,0,1]
[0,0,1] 其旋转后点为
[
R
02
R
12
R
22
]
\left[R_{02} R_{12} R_{22}\right]
[R02R12R22], 我们希望投影后其在新的坐标系下依然为
[
0
,
0
,
1
]
[0,0,1]
[0,0,1], 因 此构建了一个投影矩阵
matProj
Z
=
[
R
22
0
−
R
02
0
R
22
−
R
12
0
0
1
]
\operatorname{matProj} \mathbf{Z}=\left[\begin{array}{ccc} R_{22} & 0 & -R_{02} \\ 0 & R_{22} & -R_{12} \\ 0 & 0 & 1 \end{array}\right]
matProjZ=⎣⎡R22000R220−R02−R121⎦⎤
那么总的投影矩阵为
P
=
[
cos
θ
x
0
0
−
sin
θ
x
sin
θ
y
cos
θ
y
0
sin
θ
y
−
cos
θ
y
sin
θ
x
cos
θ
x
cos
θ
y
]
P=\left[\begin{array}{ccc} \cos \theta_{x} & 0 & 0 \\ -\sin \theta_{x} \sin \theta_{y} & \cos \theta_{y} & 0 \\ \sin \theta_{y} & -\cos \theta_{y} \sin \theta_{x} & \cos \theta_{x} \cos \theta_{y} \end{array}\right]
P=⎣⎡cosθx−sinθxsinθysinθy0cosθy−cosθysinθx00cosθxcosθy⎦⎤
- 罗德里格斯形式变换
已知R求罗德里格斯旋转表达形式
sin
θ
[
0
−
k
z
k
y
k
z
0
−
k
x
−
k
y
k
x
0
]
=
R
−
R
T
2
\sin \theta\left[\begin{array}{ccc} 0 & -k_{z} & k_{y} \\ k_{z} & 0 & -k_{x} \\ -k_{y} & k_{x} & 0 \end{array}\right]=\frac{R-R^{T}}{2}
sinθ⎣⎡0kz−ky−kz0kxky−kx0⎦⎤=2R−RT
// 旋转矩阵R——>罗德里格斯
Point3d r(R(2, 1) - R(1, 2), R(0, 2) - R(2, 0), R(1, 0) - R(0, 1));
多相机标定
-
单目相机标定流程
1.不同角度拍摄棋盘格
2.将坐标系固定在棋盘格上,计算3D坐标
3.计算相机内参矩阵
4.计算每个棋盘格和相机的相对旋转和平移
5.优化每个棋盘格到相机的姿态以及相机内参 -
双目相机标定流程
1.不同角度拍摄棋盘格,需要保证两个相机拍到完整的棋盘格,以方便后续点对应
2.每个相机单独标定,分别计算相机的内参以及每个棋盘格到相机的旋转和平移
3.由于每个姿态的棋盘格在左右相机中是一一对应的,根据每个姿态每个棋盘格到相机的相对旋
转,计算两个相机的相对旋转
4.将优化目标设置为每个棋盘格到左相机的旋转矩阵,以及使用左相机到右相机的相对旋转和平
移进行姿态传递,进行全局优化
MARKER
Random Pattern
这种标志物的思路来自特征匹配,我们知道特征点,比如经典的sift有128维的特征描述子,可以表征每个特征自己的性质。也就是说,对于一些特定的标志物,我们完全可以使用特征点作为其角点进行匹配。Opencv 提供了一种方式,就是Random Pattern。
chAruco/aprilgrid
apriltag 和 arUco 都是使用一定的编码方式来保证其检测鲁棒性的标志物,我们可以使用预先定义的marker来确定检测的角点具体是什么位置上的
opencv 本身集成了 ArUco 的实现,也在 contrib模块中。
- 生成ChArUco的代码
const char* keys =
"{@outfile |<none> | Output image }"
"{w | | Number of squares in X direction }"
"{h | | Number of squares in Y direction }"
"{sl | | Square side length (in pixels) }"
"{ml | | Marker side length (in pixels) }"
"{d | | dictionary: DICT_4X4_50=0, DICT_4X4_100=1,
DICT_4X4_250=2,"
"DICT_4X4_1000=3, DICT_5X5_50=4, DICT_5X5_100=5, DICT_5X5_250=6,
DICT_5X5_1000=7, "
"DICT_6X6_50=8, DICT_6X6_100=9, DICT_6X6_250=10,
DICT_6X6_1000=11, DICT_7X7_50=12,"
"DICT_7X7_100=13, DICT_7X7_250=14, DICT_7X7_1000=15,
DICT_ARUCO_ORIGINAL = 16}"
"{m | | Margins size (in pixels). Default is
(squareLength-markerLength) }"
"{bb | 1 | Number of bits in marker borders }"
"{si | false | show generated image }";
}
int main(int argc, char *argv[]) {
CommandLineParser parser(argc, argv, keys);
parser.about(about);
if(argc < 7) {
parser.printMessage();
return 0;
}
int squaresX = parser.get<int>("w");
int squaresY = parser.get<int>("h");
int squareLength = parser.get<int>("sl"); //黑色格子的边长
int markerLength = parser.get<int>("ml"); //白色格子中ArUco的边长
int dictionaryId = parser.get<int>("d"); // 字典族的名字
int margins = squareLength - markerLength;
if(parser.has("m")) {
margins = parser.get<int>("m");
}
int borderBits = parser.get<int>("bb");
bool showImage = parser.get<bool>("si");
String out = parser.get<String>(0);
if(!parser.check()) {
parser.printErrors();
return 0;
}
//生成图片的字典族
Ptr<aruco::Dictionary> dictionary =
aruco::getPredefinedDictionary(aruco::PREDEFINED_DICTIONARY_NAME(dictio
naryId));
Size imageSize;
imageSize.width = squaresX * squareLength + 2 * margins;
imageSize.height = squaresY * squareLength + 2 * margins;
//创建chAruco
Ptr<aruco::CharucoBoard> board =
aruco::CharucoBoard::create(squaresX, squaresY, (float)squareLength,
(float)markerLength, dictionary);
// show created board
Mat boardImage;
board->draw(imageSize, boardImage, margins, borderBits);
if(showImage) {
imshow("board", boardImage);
waitKey(0);
}
imwrite(out, boardImage);
return 0;
}