カメラのキャリブレーションの原理を簡単に理解する

重要な注意事項: この記事はオンライン情報から編集されたものであり、ブロガーが関連する知識ポイントを学習するプロセスを記録しているだけであり、削除されていません。

1. 参考資料

WeChat パブリック アカウント: Computer Vision Life コラム: #cameracalibration

カメラ キャリブレーション
カメラ キャリブレーションと 3D 再構成
張正佑キャリブレーション方法 - 完全な学習メモ - 原理から実践まで
カメラ キャリブレーションの原理と 4 つの座標系の関係

2. カメラキャリブレーションの概要

1. 透視図法

中心投影法は、投影面に物体を投影することで、より視覚効果に近い片面投影画像が得られる、近くと遠くの景色が見える映像手法です。

2. カメラキャリブレーションの概念

簡単に言うと、カメラ キャリブレーションはワールド座標系からピクセル座標系に変換するプロセスであり、このプロセスには、カメラ画像の幾何学モデルの確立とレンズの歪みの補正という 2 つの段階が含まれます。

カメラ画像幾何学モデルの確立: オブジェクトを 3 次元世界からカメラ画像面にマッピングするプロセスで幾何学モデルを確立します。最も重要な部分は、カメラの内部パラメータ外部パラメータを取得することです。

レンズの歪みの補正:レンズの製造工程上、様々な歪みが発生します。歪みを除去するために、歪み係数が計算され、撮影後の画像が現実世界のシーンと一致するように収差を補正するために使用されます。

3. 4 つの主要な座標系

世界座標系: 実世界のターゲット オブジェクトの位置を記述するために導入された、3 次元世界のユーザー定義の座標系。単位はメートル、座標系は(X w , Y w , Z w ) (X_w,Y_w,Z_w)です。( XYZ

カメラ座標系: カメラ上に確立された座標系は、カメラの視点からオブジェクトの位置を記述するために定義され、ワー​​ルド座標系と画像/ピクセル座標系の間の中間リンクとして機能します。単位はメートルで、一般にカメラの光軸を Z 軸とし、座標系は( X c , Y c , Z c ) (X_c, Y_c,Z_c)となります。( XcYcZc

画像物理座標系 (画像座標系) : ピクセル座標系での座標の取得を容易にするために、イメージング処理中のカメラ座標系から画像座標系へのオブジェクトの投影と伝達の関係を記述するために導入されました。単位はmm、座標原点はカメラ光軸と画像物理座標系の交点、座標系は(x,y)(x,y)となります。( x ,y

画像ピクセル座標系 (ピクセル座標系) : デジタル画像 (写真) 上の物体の像点の座標を記述するために導入され、実際にカメラから読み取った情報が位置する座標系です。単位はピクセル、座標原点は左上隅、座標系は( u , v ) (u,v)です。(あなたv )

4 つの座標系の関係は次の図に示すようになります。
ここに画像の説明を挿入します

このうち、カメラ座標系のZ軸は光軸と一致し、画像座標系の平面に垂直であり、画像座標系の原点を通り、カメラ座標系と画像座標系との間の距離である。は焦点距離 f (つまり、画像座標系の原点と焦点の重なり) です。ピクセル座標系平面 uv は画像座標系平面 xy と一致しますが、ピクセル座標系の原点は図の左上隅にあります (この定義の理由は、ピクセル座標系の先頭アドレスから読み書きを開始するためです)。保存されている情報)。

4. 4つの座標系の変換

ここに画像の説明を挿入します

4.1 ワールド座標系とカメラ座標系

ワールド座標系はカメラ座標系に変換されます。2 つの座標系間の変換は剛体移動です。オブジェクトは形状を変更せずに、2 つの座標系における空間位置 (平行移動) と方向 (回転) を変更するだけです。それらの間の変換関係は、並進行列 T と回転行列 R によって完成できます。これら 2 つの行列は、ワールド座標系とカメラ座標系の間の変換関係を反映しており、総称して外部パラメータ行列 L w L_w と呼ばれます L外部パラメータ行列が取得され、ワー​​ルド座標系上の点が分かり、変換関係により、カメラ座標系におけるこの点の位置が得られます。

変換行列は、回転行列と並進ベクトルで構成される同次座標系で表されます。
[ x C y C z C 1 ] = [ R t 0 3 T 1 ] [ x W y W z W 1 ] = [ r 1 r 2 r 3 t ] [ x W y W 0 1 ] = [ r 1 r 2 t ] [ x W y W 1 ] \left[\begin{array}{c}x_{C}\\y_ {C} \\z_{C}\\1\end{array}\right]=\left[\begin{array}{cc}R&t\\0_{3}^{T}&1\end{array}\ right]\ left[\begin{array}{c}x_{W}\\y_{W}\\z_{W}\\1\end{array}\right]=\left[\begin{array}{ cc}r_ {1}&r_{2}&r_{3}&t\end{配列}\right]\left[\begin{配列}{c}x_{W}\\y_{W}\\0\\1 \end{ 配列}\right]=\left[\begin{array}{cc}r_{1}&r_{2}&t\end{array}\right]\left[\begin{array}{c}x_{ W}\ \y_{W}\\1\end{配列}\right] バツCyCzC1 =[R03Tt1 バツWyWzW1 =[r1r2r3 バツWyW01 =[r1r2 バツWyW1
このうち、R は回転行列、t は並進ベクトルです。ワールド座標系において、物点が位置する平面がワールド座標系の原点を通り、Z w = 0 Z_w=0に等しいとする。Z=0軸は垂直です。つまり、チェス盤面はX w − Y w X_w - Y_wバツY平面一致の目的は、その後の計算を容易にすることです。このうち、変化行列は次のとおりです:
[ R t 0 3 T 1 ] \begin{bmatrix}R&t\\0_3^T&1\end{bmatrix}[R03Tt1]
次の図は、R と t を使用してワールド座標系をカメラ座標系に変換するプロセスを示しています。
ここに画像の説明を挿入します

4.2 カメラ座標系と画像の物理座標系 (歪みなし)

カメラ座標系から画像物理座標系への変換は、3次元座標系を2次元座標系に変換することであり、投影透視処理である。以下の図に示すように、ピンホール イメージング プロセス: ピンホール面 (カメラ座標系) は画像平面 (画像物理座標系) と物点平面 (チェス盤平面) の間にあり、結果として得られる画像は反転された実像です
ここに画像の説明を挿入します

しかし、数学的にわかりやすく説明するために、カメラ座標系と画像の物理座標系の位置を逆にしています(実際の物理的な意味はなく、計算を容易にするためです)、以下の図に示すように:
ここに画像の説明を挿入します
ここに画像の説明を挿入します

カメラ座標系に点 M があるとすると、相似三角形の原理により、画像物理座標系 (歪みなし) での結像点 P の座標は、 xp = fx M z M 、 yp = fy M となります
。 z M \mathrm{x }_{p}=f\frac{x_{M}}{z_{M}},y_{p}=f\frac{y_{M}}{z_{M}}バツp=fzMバツMyp=fzMyM
方程式を分割して征服しましょう:
z M [ xpyp 1 ] = [ f 0 0 0 0 f 0 0 0 0 1 0 ] [ x M y M z M 1 ] = [ f 0 0 0 f 0 0 0 1 ] [ 1 0 0 0 0 1 0 0 0 0 1 0 ] [ x M y M z M 1 ] z_{M}\left[\begin{array}{c}{x_{p}}\\ {y_{p }}\\{1}\\\end{array}\right]=\left[\begin{array}{ccc}{f}&{0}&{0}&{0}\\ {0}& {f}&{0}&{0}\\{0}&{0}&{1}&{0}\\\end{配列}\right]\left[\begin{配列} {c}{ x_{\mathrm{M}}}\\{y_{\mathrm{M}}}\\{z_{\mathrm{M}}}\\{1}\\\end{array}\ right]=\ left[\begin{array}{ccc}{f}&{0}&{0}\\{0}&{f}&{0}\\{0}&{0}&{1 }\\\ end{array}\right]\left[\begin{array}{ccc}{1}&{0}&{0}&{0}\\{0}&{1}&{0} &{0} \\{0}&{0}&{1}&{0}\\\end{array}\right]\left[\begin{array}{cc}{x_{\mathrm{M} }}\\ {y_{\mathrm{M}}}\\{z_{\mathrm{M}}}\\{1}\\\end{配列}\right]zM バツpyp1 = f000f0001000 バツMyMzM1 = f000f0001 100010001000 バツMyMzM1

4.3 カメラ座標系と画像の物理座標系 (歪みあり)

「カメラの歪みモデル」の章を参照してください。

4.4 画像の物理座標系と画像のピクセル座標系

画像の物理座標系と画像のピクセル座標系の違いを説明するために、鮮明な例を挙げてみましょう。物理座標系は連続的な概念であり、映画館の特定の観客の特定の座標値が (3.4, 5.9) であるのと同じように、ミリメートル単位で測定されますが、ピクセル座標系は離散的な概念であり、測定されます。ピクセル単位で、映画館の特定の観客の位置が (3 行目、6 列目) であるのと同じように、整数値の座標になります。さらに、2 つの座標系の原点位置は同じではないことに注意してください。物理座標系の原点はカメラの光軸と画像の物理座標系の交点であり、通常が、ピクセル座標系はピクセル画像の左上隅を原点とします。

定義された画像ピクセル座標系の原点は画像物理座標系の原点と一致しないため、画像ピクセル座標系における画像物理座標系の原点の座標を(u 0, v とする) 0 ) (u_0、v_0)(あなた0v0)、画像の物理座標系の x 軸および y 軸方向の各ピクセルの寸法は次のとおりです:dx、dy d_x、d_yd×dはい、画像の物理座標系における画像点の座標は(xc, yc) (x_c,y_c)です。( ×cyc)、画像座標系における理想点の座標は次のとおりです:
u = xcdx + u 0 , v = ycdy + v 0 u=\frac{x_{c}}{d_{x}}+u_{0}, \mathbf{v}=\frac{y_{c}}{d_{y}}+\mathbf{v}_{0}あなた=d×バツc+あなた0v=dはいyc+v0
同次座標系への変換形式は次のとおりです:
[ u ν 1 ] = [ 1 / dx 0 u 0 0 1 / dyv 0 0 0 1 ] [ xcyc 1 ] \begin{bmatrix}u\\\nu\\1 \end{bmatrix}=\begin{bmatrix}1/d_x&0&u_0\\0&1/d_y&v_0\\0&0&1\end{bmatrix}\begin{bmatrix}x_c\\y_c\\1\end{bmatrix} あなたn1 = 1/×0001/はい0あなた0v01 バツcyc1

5. カメラの歪みモデル

レンズの歪みは主にラジアル歪みとタンジェンシャル歪み、薄いレンズ歪みなどに分けられますが、ラジアル歪みやタンジェンシャル歪みほど顕著ではないため、一般的にはラジアル歪みkとタンジェンシャル歪みpのみを考慮します。レンズの歪みを記述するには、合計 5 つの歪みパラメータ (k1、k2、k3、p1、p2) が必要です。そのうち、半径方向の歪みには 3 つのパラメータ (k1、k2、k3) があり、接線方向の歪みには 2 つのパラメータ (p1、p2) があります。

5.1 放射状歪み

放射状の歪みはレンズ形状の製造プロセスによって発生し、レンズの端に向かうにつれて放射状の歪みは大きくなります。以下の図は、2 種類の放射状歪み、つまり樽型歪み (k<0) と糸巻き型歪み (k>0) を示しています。
ここに画像の説明を挿入します

  • k>0の場合、rが大きいほど(中心から遠いほど)歪みが大きくなり、rが小さいほど歪みが小さくなり、糸巻き型になります。
  • k<0の場合、rが大きいほど(中心から遠いほど)歪みは小さくなり、rが小さいほど歪みが大きくなり、樽型になります。

実際には、r=0 でのテイラー級数展開の最初の数項は、動径歪みを近似するためによく使用されます。放射状歪みの補正前後の座標関係は次のとおりです。
{ xdistorted = xp ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) ydistorted = yp ( 1 + k 1 r 2 + k 2 r 4 + k 3 r 6 ) \begin{cases}\mathbf{x}_{歪み}=x_p(1+k_1r^2+k_2r^4+k_3r^6)\\y_{歪み}=y_p(1+k_1r^2) +k_2r ^4+k_3r^6)\end{件}{ バツディストまたはテッド_ _ _ _ _=バツp( 1+k1r2+k2r4+k3r6 )yディストまたはテッド_ _ _ _ _=yp( 1+k1r2+k2r4+k3r6 )
放射状歪みの場合、解決する必要がある 3 つの放射状歪みパラメータ (k1、k2、K3) があることがわかります。

研究によると、放射状歪みパラメータは通常 2 または 3 k の値を選択し、より良い結果が得られることがわかりました。これ以上のkが得られても影響は大きくないので無視できますし、結果が悪くなる可能性もあります。

5.2 接線方向の歪み

タンジェンシャル歪みは、レンズとCMOSやCCDの取り付け位置誤差によって発生します。したがって、タンジェンシャル歪みがあると、長方形を撮像面に投影すると台形になりやすい。接線方向の歪みを説明するには、2 つの追加の歪みパラメータ (p1 と p2) が必要です。補正前後の座標関係は次のとおりです: {
xdistorted = xp + [ 2 p 1 xpyp + p 2 ( r 2 + 2 xp 2 ) ] ydistorted = yp + [ p 1 ( r 2 + 2 yp 2 ) + 2 p 2 xpyp ] \begin{cases}\mathbf{x}_{distorted}=x_{p}+[2p_{1}x_{p}y_{p } +p_{2}(r^{2}+2{x_{p}}^{2})]\\\mathbf{y}_{歪んだ}=y_{p}+[p_{1}(r ^ {2}+2{y_{p}}^{2})+2p_{2}x_{p}y_{p}]\end{件}{ バツディストまたはテッド_ _ _ _ _=バツp+[ 2p _1バツpyp+p2( r2+2倍_p2 )]yディストまたはテッド_ _ _ _ _=yp+[ p1( r2+2p2 )+2P _2バツpyp]

6. カメラのキャリブレーションパラメータ

内部参照

  • 焦点距離:fx、fy f_x、f_yf×fはい

  • 主点(光学中心)ピクセル座標:cx、cy c_x、c_yc×cはい

  • 歪み係数: k 1 、 k 2 、 k 3 、 p 1 、 p 2 k_{1}、k_{2}、k_{3}、p_{1,}p_{2}k1k2k3p1p2

カメラ行列 x = [ fx 0 cx 0 fycy 0 0 1 ] Camera\text{matrix}x=\begin{bmatrix}f_x&0&c_x\\0&f_y&c_y\\0&0&1\end{bmatrix};マトリックスください_= f×000fはい0c×cはい1

歪み係数 = ( k 1 k 2 p 1 p 2 k 3 ) 歪み \ 係数 = (k_1 \ k_2 \ p_1 \ p_2 \ k_3)距離係数_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ =( k1 k2 p1 p2 k3

外部参照

  • 回転行列 R;
  • 変換行列 T.

7. ホモグラフィー行列

Zhang Zhengyou のキャリブレーション アルゴリズムの原理の詳細な説明

7.1 はじめに

o'-uv は画像ピクセル座標系、o-XYZ はワールド座標系です。画像上の点の座標を (u, v)、それに対応する 3 次元の点の位置を (x, y, z) とすると、両者の変換関係は [ u ν 1 ] = s となります。 [ fx γ u
0 0 fy ν 0 0 0 1 ] [ r 1 r 2 t ] [ x W y W 1 ] \begin{bmatrix}u\\\nu\\1\end{bmatrix}=s\begin{ bmatrix}f_x&\gamma&u_0 \\0&f_y&\nu_0\\0&0&1\end{bmatrix}\begin{bmatrix}r_1&r_2&t\end{bmatrix}\begin{bmatrix}x_W\\y_W\\1\end{bmatrix} あなたn1 =s f×00cfはい0あなた0n01 [r1r2 バツWyW1
このうち、s はスケールファクターで、カメラの光学中心から出た光線がすべて結像面の同じ点に当たることを意味します。u と v は、画像ピクセル座標系fx 、 fy 、 u 0 、 v 0 、 γ f_x、 f_y、 u_0、 v_0、 \gamma の座標を表します。f×fはいあなた0v0γは 5 つの内部カメラ パラメータを表し、R、t は外部カメラ パラメータを表し、X w 、Y w 、Z w X_w、Y_w、Z_wバツYZワールド座標系の座標を表します。チェス盤面はワールド座標系にありますZ w = 0 Z_w=0Z=0機。

7.2 ホモグラフィーの概念

ホモグラフィー変換は、オブジェクトのワールド座標系と画像ピクセル座標系の間の位置マッピング関係を記述し、この変換行列をホモグラフィー行列と呼びます。上の式では、ホモグラフィ行列は次のように定義されます。
H = s [ fx γ u 0 0 fy ν 0 0 0 1 ] [ r 1 r 2 t ] = s M [ r 1 r 2 t ] H=s \ begin{bmatrix}f_x&\gamma&u_0\\0&f_y&\nu_0\\0&0&1\end{bmatrix}\begin{bmatrix}r_1&r_2&t\end{bmatrix}=sM\begin{bmatrix}r_1&r_2&t\end{bmatrix}H=s f×00cfはい0あなた0n01 [r1r2=M _[r1r2]
このうち、M はカメラ固有パラメータ行列です:
M = [ fx γ u 0 0 fy ν 0 0 0 1 ] M=\left[\begin{array}{ccc}f_x&\gamma&u_0\\0&f_y&\nu_0\\ 0&0&1\end {配列}\right]M= f×00cfはい0あなた0n01
ホモグラフィー行列には、カメラの固有パラメータと外部パラメータの両方が含まれます。

7.3 ホモグラフィーの応用

7.3.1 画像補正

画像修正にホモグラフィー行列を使用するには、少なくとも 4 つの対応点が必要です。
ここに画像の説明を挿入します

7.3.2 視点変換

次の図に示すように、ホモグラフィ行列を使用すると、通常のビューを鳥瞰図に簡単に変換できます。左が通常のビュー、右が鳥瞰図です。
ここに画像の説明を挿入します

7.3.3 画像の貼り合わせ

ホモグラフィー行列は透視変換を実行できるため、異なる角度で撮影された画像を同じ透視に変換することで画像の接合を実現できます。以下の図に示すように、image1 と image2 は両方とも、ホモグラフィー行列 H を通じて同じ平面に変換できます。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

7.3.4 拡張現実 AR

AR 表示には平面 2 次元マーカーがよく使われており、下図に示すように、マーカーのさまざまな視点からの画像をもとに、仮想物体の位置や姿勢を容易に取得・実現できます。
ここに画像の説明を挿入します

7.4 ホモグラフィ行列の原理

2 つの画像内の対応する点の同次座標が( x ' , y ' , 1 ) (x^{\prime},y^{\prime},1) であるとします。( ×「、y「、1 )の場合、ホモグラフィー行列 H は次のように定義されます:
H = [ h 11 h 12 h 13 h 21 h 22 h 23 h 31 h 32 h 33 ] H=\left[\begin{array}{ccc}h_{_{ 11}}&h_{_{12}}&h_{_{13}}\\h_{_{21}}&h_{_{22}}&h_{_{23}}\\h_{_{31}}&h_ {_{32}}&h_{_{33}}\end{配列}\right]H= h11h21h31h12h22h32h13h23h33
有:
[ x ' y ' 1 ] 〜 [ h 11 h 12 h 13 h 21 h 22 h 23 h 31 h 32 h 33 ] [ xy 1 ] \left[\begin{array}{c}x'\\ y'\\1\end{array}\right]\sim\left[\begin{array}{ccc}h_{11}&h_{12}&h_{13}\\h_{21}&h_{22}&h_{ 23}\\h_{31}&h_{32}&h_{33}\end{配列}\right] \begin{bmatrix}x\\y\\1\\\end{bmatrix} バツy1 h11h21h31h12h22h32h13h23h33 バツy1
行列展開後の方程式は 3 つあります。最初の 2 つの方程式に 3 番目の方程式を代入すると、 x ' = h 11 x + h 12 y + h 13 h 31 x + h 32 y + h 33 x'=\frac が得られます
{h_{11}x+h_{12}y+h_{13}}{h_{31}x+h_{32}y+h_{33}}バツ=h31バツ+h32y+h33h11バツ+h12y+h13

y ' = h 21 x + h 22 y + h 23 h 31 x + h 32 y + h 33 y'=\frac{h_{21}x+h_{22}y+h_{23}}{h_{31 }x+h_{32}y+h_{33}}y=h31バツ+h32y+h33h21バツ+h22y+h23

つまり、点ペアは 2 つの方程式に対応します。

H 行列モジュールが 1 になるように H に制約を追加します。つまり、∣ ∣ H ∣ ∣ = 1 ||{H}||=1∣∣ H ∣∣=1、以下:
x ' = h 11 x + h 12 y + h 13 h 31 x + h 32 y + h 33 ( 1 ) x'=\frac{h_{11}x+h_{12}y+h_{ 13}}{h_{31}x+h_{32}y+h_{33}} \quad (1)バツ=h31バツ+h32y+h33h11バツ+h12y+h13( 1 )

y ' = h 21 x + h 22 y + h 23 h 31 x + h 32 y + h 33 ( 2 ) y'=\frac{h_{21}x+h_{22}y+h_{23}}{ h_{31}x+h_{32}y+h_{33}} \quad (2)y=h31バツ+h32y+h33h21バツ+h22y+h23( 2 )

h 11 2 + h 12 2 + h 13 2 + h 21 2 + h 22 2 + h 23 2 + h 31 2 + h 32 2 + h 33 2 = 1 h_{11}^2+h_{12}^2 +h_{13}^2+h_{21}^2+h_{22}^2+h_{23}^2+h_{31}^2+h_{32}^2+h_{33}^2= 1h112+h122+h132+h212+h222+h232+h312+h322+h332=1

上記の式 (1) と (2) に分母を掛けて展開すると、次のようになります:
( h 31 x + h 32 y + h 33 ) x ' = h 11 x + h 12 y + h 13 \left(h_{31} x +h_{32}y+h_{33}\right)x^{\prime}=h_{11}x+h_{12}y+h_{13}( h31バツ+h32y+h33バツ=h11バツ+h12y+h13

( h 31 x + h 32 y + h 33 ) y ' = h 21 x + h 22 y + h 23 \left(h_{31}x+h_{32}y+h_{33}\right)y^{ \プライム}=h_{21}x+h_{22}y+h_{23}( h31バツ+h32y+h33y=h21バツ+h22y+h23

終了後、次の結果が得られます:
h 11 x + h 12 y + h 13 − h 31 xx ′ − h 32 yx ′ − h 33 x ′ = 0 h_{11}x+h_{12}y+h_{13}- h_{ 31}xx^{\prime}-h_{32}yx^{\prime}-h_{33}x^{\prime}=0h11バツ+h12y+h13h31×× _h32y xh33バツ=0

h 21 x + h 22 y + h 23 − h 31 xy ’ − h 32 yy ’ − h 33 y ’ = 0 h_{21}x+h_{22}y+h_{23}-h_{31}xy' -h_{32}yy'-h_{33}y'=0h21バツ+h22y+h23h31h32やあ_h33y=0

2 枚の画像に対応する N 個の点ペア (特徴点マッチング ペア) が得られたとすると、次のような一次方程式が得られます。
ここに画像の説明を挿入します

グラフは次のとおりです:
2 N x 9 9 x 1 2 N x 1 A h = 0 \begin{array}{cccc}\mathbf{2Nx9}&\mathbf{9x1}&&\mathbf{2Nx1}\\\mathbf{A }&\mathbf{h}&=&\mathbf{0}\end{配列}2N×99x1=2N×10
実際のアプリケーションのシナリオでは、計算された点のペアにはノイズが含まれます。例えば、点の位置が数ピクセルずれたり、特徴点ペアの不一致現象が発生したりする場合でも、4つの点ペアだけでホモグラフィ行列を計算すると大きな誤差が発生します。したがって、計算をより正確にするために、ホモグラフィー行列の計算には 4 つよりもはるかに大きな点ペアが一般的に使用されます。なお、上記一次方程式は直接線形解法を採用しており、通常、最適解を求めることは困難であるため、特異値分解やレーベンバーグ・マルコート(LM)アルゴリズムなどの他の最適化手法が用いられます。実際の使用で解決するために一般的に使用されます。

7.5 ホモグラフィ行列の計算過程

ホモグラフィー行列 H は、印刷されたチェス盤の校正図と撮影された写真に基づいて計算されます。一般的なプロセスは次のとおりです。

  1. チェッカーボードのキャリブレーション図面を印刷し、平らなオブジェクトの表面に貼り付けます。

  2. さまざまな方向から一連のチェッカーボード写真を撮影するには、カメラを移動するか、キャリブレーション画像を移動します。

  3. 撮影されたチェス盤の写真ごとに、写真内のすべてのチェス盤の角点が検出されます。

  4. チェス盤のキャリブレーション図面内のすべてのコーナー ポイントのワールド座標は既知であるため、これらのコーナー ポイントに対応する画像ピクセル座標も既知です。対応点ペアが N≧4 であれば、LM などの最適化手法に基づいてホモグラフィ行列 H を求めることができ、対応点ペアが多いほど計算結果はよりロバストになります。ホモグラフィー行列を計算するには、通常、関数を自分で記述する必要はありません。OpenCV で呼び出すことができる既製の関数があります。対応する C++ 関数は次のとおりです。

    Mat findHomography(InputArray srcPoints, InputArray dstPoints, int method=0, double ransacReprojThreshold=3, OutputArray mask=noArray() )
    

    関数的に言えば、対応点ペアを入力し、特定の計算方法を指定すれば、ホモグラフィー行列を求めることができます。

3. 張正佑カメラのキャリブレーション方法

1 はじめに

Zhang Zhengyou 博士は、1999 年にトップ国際会議 ICCV で論文「Flexible Camera Calibration By Viewing a Plane From Unknown Orientations」を発表し、平面チェッカーボードを使用したカメラ キャリブレーションの実用的な方法を提案しました。この方法は、写真キャリブレーション方法と自己キャリブレーション方法の中間に位置し、写真キャリブレーション方法で必要とされる高精度の 3 次元キャリブレーション オブジェクトの欠点を克服するだけでなく、自己キャリブレーション オブジェクトのロバスト性が低いという問題も解決します。校正方法。キャリブレーションプロセスには、印刷されたチェッカーボードと、さまざまな方向から撮影した数枚の画像が必要であり、誰でも自分でキャリブレーションパターンを作成できます。実用的、柔軟、便利であるだけでなく、高精度と優れた堅牢性も備えています。したがって、それはすぐに世界中で広く採用され、実験室から現実世界への 3D コンピュータ ビジョンのプロセスを大きく推進しました。

Zhang Zhengyou キャリブレーション方法は、キャリブレーションに 2 次元の正方形で構成されるキャリブレーション プレートを使用し、さまざまなポーズでキャリブレーション プレートの写真を収集し、写真内の隅の点のピクセル座標を抽出し、内部および外部の初期値を計算します。ホモグラフィ行列を通じてカメラのパラメータを計算し、非線形最小二乗を使用します。歪み係数は乗算的に推定され、最後に最尤推定法を使用してパラメータが最適化されます。この方法は操作が簡単で精度が高く、ほとんどの場合に対応できます。

2. 張正佑の紹介

Zhang Zhengyou 博士は、コンピューター ビジョンとマルチメディア テクノロジの世界的に有名な専門家であり、ACM フェローおよび IEEE フェローです。現在、彼は Microsoft Research のビジュアル コンピューティング グループの上級研究員を務めています。彼は、ステレオ ビジョン、3 次元再構築、動作分析、画像レジストレーション、カメラ キャリブレーションなどの分野で画期的な貢献を行ってきました。

3.チェッカーボード校正ボード

3.1 チェッカーボード校正ボードの概要

チェッカーボード キャリブレーション ボードは、白と黒の正方形の間隔で構成されるキャリブレーション ボードで、カメラのキャリブレーション (現実世界からデジタル画像内のオブジェクトへのマッピング) のキャリブレーション オブジェクトとして使用されます。チェス盤をキャリブレーションオブジェクトとして使用する理由は、複雑な立体物に比べて、平面的なチェス盤パターンの方が加工が容易であるためです。一方、2次元物体は3次元物体に比べて一部の情報が不足しており、より豊富な座標情報を得るためにチェス盤の向きを何度も変えて画像を撮影します。下の図に示すように、これは同じチェッカーボード キャリブレーション プレートを異なる方向からカメラで撮影した画像です。
ここに画像の説明を挿入します

3.2 チェッカーボード校正ボードを入手する

キャリブアイオ

3.2.1 正方形の校正プレート

ダウンロード:グリッド校正プレート

校正プレートのサイズ: w=9、h=6。
ここに画像の説明を挿入します

3.2.2 円形校正プレート

ダウンロード:円形校正プレート

校正プレートのサイズ: w=11、h=4。
ここに画像の説明を挿入します

校正プレートのサイズ: w=17、h=6。
ここに画像の説明を挿入します

3.2.3 ChAruco 校正プレート

  • 7X5 ChAruco ボード;
  • 正方形のサイズ: 30 mm ;
  • マーカーサイズ: 15 mm;
  • アルコ辞書: DICT_5X5_100;
  • ページ幅: 210 mm、ページ高さ: 297 mm。
    ここに画像の説明を挿入します

3.2.4 チェッカーボード校正プレートの生成

キャリブレーションパターンの作成

Python を使用してカスタマイズされたキャリブレーション プレートを生成し、Python スクリプト ファイルgen_pattern.pyをダウンロードします。

3.3 角点

コーナー ポイントは、白と黒のチェッカーボードの交点です。下の図に示すように、中央のマゼンタの円がコーナー ポイントです。
ここに画像の説明を挿入します

下図に示すように、X 方向に 8 つのコーナー点、Y 方向に 3 つのコーナー点があります。
ここに画像の説明を挿入します

3.4 内角点

コーナー点とは黒と白を結ぶ正方形の固定点部分を指し、内コーナー点とは校正板の端に接しない内側のコーナー点を指します。

patternSize:(w,h)、チェス盤の各行と列の内側の角の数。w= チェス盤の 1 行にある黒と白のブロックの数 -1、h= チェス盤の 1 列にある黒と白のブロックの数 -1、たとえば: 9x4 のチェス盤の場合、(w,h)= (8,3)

3.5 チェッカーボード校正ボード座標系

チェッカーボード キャリブレーション ボード座標系は、デフォルトで平面キャリブレーション モードを採用します。つまり、Z 軸はゼロです。

世界座標系Z w = 0 Z_w=0に配置されるチェッカーボード キャリブレーション プレートを定義します。Z=0の平面上では、世界座標系の原点は、下の図の黄色の点など、チェッカーボード キャリブレーション プレートの固定コーナーに位置します。画像のピクセル座標系の原点は、画像の左上隅にあります。
ここに画像の説明を挿入します

座標を書くときは、Z軸が0であることを確認し、小さいものから大きいものへ、Xが変化し、次にYが変化するという順序で書きます。チェス盤キャリブレーション ボードのグリッド サイズが 5 cm の場合、世界座標系の座標は次のように記述できます: (0,0,0)、(5,0,0)、(10,0,0)…(0) 、5、0)、(5、5、0)、(10、5、0)、…

4. 張正佑校正法の計算プロセス

キャリブレーションにチェッカーボード キャリブレーション ボードを使用して、チェッカーボードの内側の角を見つける必要があります。画像ピクセル座標系でのチェッカーボードの内側の角の座標とワールド座標系での各点の座標に従って、複数の画像を撮影します。チェッカーボードの位置と複数のポイント カメラの内部パラメータと外部パラメータを解決します。

OpenCV を使用して Zhang Zhengyou キャリブレーション メソッドを実行する場合、計算プロセスは次のとおりです。

  1. キャリブレーション画像を準備します。理論的には少なくとも 4 枚、通常は複数の角度から収集した約 20 枚の画像です。
  2. 校正板の角点を抽出し、校正板上の角点の座標を計算します 一般に校正板をXY平面とみなし、Zを0とし、校正板上の角点の座標を計算します。
  3. カメラのキャリブレーション、内部パラメータ、外部パラメータ、歪みパラメータは、Zhang Zhengyou キャリブレーション方法によって計算されます。
  4. キャリブレーション結果は、通常、再投影誤差によって評価されます。
  5. キャリブレーションの効果を確認し、キャリブレーション結果を使用してチェッカーボード図を修正します。

5. コア機能

cornerSubPix()

OpenCV での Feature2D 学習 - サブピクセルコーナー検出 (cornerSubPix)

OpenCV3 サブピクセルコーナー検出: CornerSubPix()

機能: サブピクセルレベルのコーナーポイント検出、サブピクセルレベルの精度までの正確な内部コーナーポイント位置。

void cornerSubPix(InputArray image, 
                  InputOutputArray corners, 
                  Size winSize, 
                  Size zeroZone, 
                  TermCriteria criteria);

パラメータの説明

  • image入力パラメータである元のチェス盤キャリブレーション ボード画像 (画像マトリックス) の入力を示します。画像行列は 8 ビット グレースケール イメージまたはカラー イメージである必要があります。通常、画像は関数に渡される前に、グレースケール処理とフィルター操作を受けます。

  • corners入力パラメーターと出力パラメーターの両方である内側のコーナー点の座標を表します。findChessboardCorners()出力内コーナー点をこの関数の入力コーナーとして使用し、サブピクセル レベルの内コーナー点検出後にコーナーを出力します。

  • winSize検索窓の辺の長さの半分を示します。たとえば、winSize= Size(5, 5) の場合、 a のサイズは( 52+1 )( 52+1 )=1111の検索ウィンドウが使用されます。

  • zeroZone検索領域の中央にあるデッド領域の辺の長さの半分を表し、自己相関行列の特異性を回避するために使用される場合があります。値が (-1,-1) に設定されている場合は、そのような領域が存在しないことを意味します。

  • criteriaコーナーポイントのサブピクセルレベルの精度の反復プロセスの終了条件を表します。オプションの値は次のとおりです。

    • cv::TermCriteria::MAX_ITER反復回数が最大数に達すると停止することを示します。
    • cv::TermCriteria::EPSコーナーポイントの位置の変化が最小値に達したときに反復が停止することを示します。

    どちらもcv::TermCriteria()コンストラクターを使用して指定され、組み合わせることができます。

    //指定亚像素计算迭代条件
    cv::TermCriteria criteria = cv::TermCriteria(
        cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS,  // 终止条件
        40,  // 最大次数
        0.01); // 最小值
    

findChessboardCorners()

findChessboardCorners() コーナー検出の詳細な説明

機能: コーナー検出、チェッカーボード キャリブレーション ボードのコーナー ポイントの位置を取得します。

戻り値: すべてのコーナーポイントが検出され、特定の順序で配置され、ゼロ以外の数値が返されます。それ以外の場合は 0 が返されます。

// 函数原型
findChessboardCorners(InputArray image,
                      Size patternSize,
                      OutputArray corners,
                      int flags);

パラメータの説明

  • image入力パラメータである元のチェス盤キャリブレーション ボード画像 (画像マトリックス) の入力を示します。画像行列は 8 ビット グレースケール イメージまたはカラー イメージである必要があります。通常、画像は関数に渡される前に、グレースケール処理とフィルター操作を受けます。

  • patternSize内側のコーナーポイントを表すサイズは入力パラメータです。

    データ型: Size patternSize(w,h)、w、h はそれぞれ、チェス盤の各行と各列の内角の数を表します。

    w=チェッカーボード キャリブレーション ボードの 1 行にある黒と白のブロックの合計数 -1、h=チェッカーボード キャリブレーション ボードの 1 列にある黒と白のブロックの合計数 -1

    例: 10x6 チェッカーボード キャリブレーション ボードの場合、(w,h)=(9,5)。

    :内隅点の大きさに合わせて校正板の向きを決めてください。具体的には、w と h が異なる場合、関数はキャリブレーション プレートの方向を識別できますが、w と h が同じ場合、関数によって描画される角の開始位置が毎回変わり、キャリブレーションに役立ちません。

  • corners検出された内隅点、出力パラメーターを表す出力配列。

    データ型: vector<vector<point2f>>

  • flagsフラグ ビットは入力パラメータであり、デフォルト値があります。

    • CV_CALIB_CB_ADAPTIVE_THRESH:関数のデフォルトモードでは、固定しきい値を使用する代わりに、適応しきい値法を使用して画像を 2 値化します。
    • CV_CALIB_CB_NORMALIZE_IMAGE: 固定しきい値または適応しきい値メソッドを使用して画像を 2 値化する前に、EqualizeHist() 関数を呼び出して画像を正規化し、ヒストグラムを使用して画像を均等化します。
    • CV_CALIB_CB_FILTER_QUADS: 2 値化が完了すると、関数は画像内の四角形 (歪みがあるため、ここでは四角形と呼ぶべきではありません) の位置を特定し始めます。追加の基準 (輪郭領域、周囲長、正方形の形状など) を使用して、輪郭取得段階で抽出された誤った四角形を除外することで、コーナー検出をより正​​確かつ厳密に行うことができます。
    • CALIB_CB_FAST_CHECK: クイック検出オプション。基板のコーナーを見つけるための画像上のクイック検査メカニズムです。コーナーポイントの検出が失敗する可能性が非常に高い状況では、このフラグにより​​関数の効率が向上します。

    知らせ:フラグビットは組み合わせて使用​​できます。CALIB_CB_FAST_CHECKこれは通常、迅速な検出のために使用されますが、特にチェス盤上の光が不均一な場合、検出が成功しない可能性が非常に高くなります。全体として、CV_CALIB_CB_ADAPTIVE_THRESH市松模様のパターンを検出する最も可能性の高い方法です。CV_CALIB_CB_ADAPTIVE_THRESH|CV_CALIB_CB_NORMALIZE_IMAGEデフォルトの方法やこの組み合わせ方法でコーナー点を検出できない場合は、基本的に再撮影が必要となりますので、組み合わせて使用​​することをお勧めします。

この関数の機能は、画像に完全なチェッカーボードが含まれているかどうかを判断し、完全に検出できた場合は、角の位置の順序 (左から右、上から下) を記録し、ゼロ以外の数値を返すことです。それ以外の場合は 0 を返します。ここでのパラメータ要件patternSizeは非常に厳密で、関数はゼロ以外を返す前に同じサイズを検出する必要があり、それ以外の場合は 0 を返します。

cornerSubPix()この関数で検出されたコーナー座標は不正確です。コーナーの正確な座標を取得するには、コーナー サブピクセルを抽出する関数を使用できます。使用方法については、ブログ「コーナー検出と最適化関数の使用法」を参照してください。

drawChessboardCorners()

機能: 検出されたコーナーポイントを元の画像に描画します。

calibrateCamera()

OpenCV関数使用時のcalibrateCamera

機能: カメラのキャリブレーション。

double calibrateCamera(InputArrayOfArrays objectPoints, 
                       InputArrayOfArrays imagePoints,
                       Size imageSize, 
                       InputOutputArray cameraMatrix, 
                       InputOutputArray distCoeffs, 
                       OutputArrayOfArrays rvecs, 
                       OutputArrayOfArrays tvecs, 
                       int flags=0);

パラメータの説明

  • objectPointsワールド座標系の点、つまり 3D 点を表します。

    データ型は次のとおりです。std::vector<std::vector<cv::Point3f>> objectPoints最初のレイヤーのベクトルは各視点 (各ピクチャ) を表し、2 番目のレイヤーのベクトルは各点を表します。

  • imagePoints 対応するイメージ ピクセル座標系の点、つまり 2D 点を表します。この値は、findChessboardCorners()関数を使用して画像から取得できます。

    データ型は次のとおりです。std::vector<std::vector<cv::Point2f>> imagePoints最初のレイヤーのベクトルは各パースペクティブを表し、2 番目のレイヤーのベクトルは各内側のコーナー ポイントを表します。

  • imageSize画像のサイズを表します。これは、カメラの内部パラメータと歪み行列を計算するために必要です。

  • cameraMatrixカメラの固有パラメータ行列を表します。行列サイズは 3x3 です。このマトリックスはカメラのキャリブレーション出力の結果です。

    データ型は次のとおりですcv::Mat cameraMatrix

  • distCoeffs歪み行列を表します。特定のサイズはパラメータによって異なりますflagsこのマトリックスはカメラのキャリブレーション出力の結果です。

    データ型: cv::Mat distCoeffs;

  • rvecsは回転ベクトルを表します。それぞれはvector<Point3f>rvecs を取得します。各 vec は 3x1 であり、Rodrigues()関数を使用して 3x3 回転行列に変換できます。

    データ型: vector<cv::Mat> rvecs;

  • tvecs並進ベクトルを表します。 と同様rvecs、各 vec は 3x1 です。

    データ型: vector<cv::Mat> tvecs;

    パラメータ rvecs および tvecs はカメラの外部パラメータであり、ビューごとにワールド座標系をカメラ座標系に変換できます。

  • flags初期値を使用するかどうかの決定、歪みマトリックスのパラメーターの数など、キャリブレーション中に使用されるパラメーターを示します。次のパラメータがあります。

    • CV_CALIB_USE_INTRINSIC_GUESS: このパラメータを使用する場合、cameraMatrix マトリックスに fx、fy、cx、cy の推定値が存在する必要があります。それ以外の場合、画像の中心点 (cx、cy) が初期化され、最小二乗法を使用して fx、fy が推定されます。
    • CV_CALIB_FIX_PRINCIPAL_POINT:最適化すると光軸点が固定されます。CV_CALIB_USE_INTRINSIC_GUESS パラメータが設定されている場合、光軸点は中心または入力値のままになります。
    • CV_CALIB_FIX_ASPECT_RATIO:fx/fyの比率は固定で、fyのみを最適化計算の変数として使用します。CV_CALIB_USE_INTRINSIC_GUESS が設定されていない場合、fx と fy は無視されます。計算には fx/fy 比率のみが使用されます。
    • CV_CALIB_ZERO_TANGENT_DIST: 接線方向の歪みパラメータ (p1、p2) をゼロに設定します。
    • CV_CALIB_FIX_K1,...,CV_CALIB_FIX_K6: 対応する放射状の歪みは、最適化中に変更されません。
    • CV_CALIB_RATIONAL_MODEL: k4、k5、k6の3つの歪みパラメータを計算します。設定しない場合は、他の 5 つの歪みパラメータのみが計算されます。

6. サンプルコード

OpenCV を使用して Zhang Zhengyou のキャリブレーション プロセスを実現します。

6.1 C++ の実装

Zhang Zhengyou ビジュアル キャリブレーション アルゴリズムの研究ノート

例1

複数のビューを調整します。

#include <iostream>
#include <opencv2/opencv.hpp>
#include  <boost/filesystem.hpp>

std::vector<std::string> get_all_image_file(std::string image_folder_path){
    boost::filesystem::path dirpath = image_folder_path;
    boost::filesystem::directory_iterator end;
    std::vector<std::string> files;
    for (boost::filesystem::directory_iterator iter(dirpath); iter != end; iter++)
    {
        boost::filesystem::path p = *iter;
        files.push_back(dirpath.string()+ "/"+ p.leaf().string());
    }
     std::sort(files.begin(),files.end());
    return files;
}

std::vector<cv::Mat> get_all_iamge(std::string image_folder_path)
{
    std::vector<cv::Mat> images;
    std::vector<std::string> image_files_path = get_all_image_file(image_folder_path);
    for(int i=0; i<  image_files_path.size() ;i++){
        cv::Mat image;
        image = cv::imread(image_files_path[i]);
        images.push_back(image);
    }
    return images;
}

int find_chessboard(cv::Mat image, std::vector<cv::Point2f> &image_points, cv::Size board_size)
{
    if (0 == findChessboardCorners(image, board_size, image_points))
    {
        std::cout<<"can not find chessboard corners!\n";
        return 0;
    }
    else
    {
        cv::Mat view_gray;
        cv::cvtColor(image,view_gray,cv::COLOR_RGB2GRAY);
        //对粗提取的角点进行亚像素精确化
        cv::find4QuadCornerSubpix(view_gray,image_points,cv::Size(11,11)); 
        //int nChessBoardFlags = cv::CALIB_CB_EXHAUSTIVE | cv::CALIB_CB_ACCURACY;
        //bool bFindResult = findChessboardCornersSB(view_gray,board_size,image_points,nChessBoardFlags );   
        //Opencv4 识别棋盘格方法,比opencv3有较大提升
    }
    return 1;
}

int init_chessboard_3dpoints(cv::Size board_size, std::vector<cv::Point3f> &points, float point_size)
{
    cv::Size2f square_size = cv::Size2f(point_size,point_size);
    for (int i=0;i<board_size.height;i++){
        for (int j=0;j<board_size.width;j++){
            cv::Point3f realPoint;
            realPoint.x = j*square_size.width;
            realPoint.y = i*square_size.height;
            realPoint.z = 0;
            points.push_back(realPoint);
        }
    }
    return 0;
}


void calib_monocular(std::vector<cv::Mat> images){
    cv::Size image_size;
    cv::Size board_size(11,4);
    std::vector<cv::Mat> images_tvecs_mat;
    std::vector<cv::Mat> images_rvecs_mat;
    image_size.width = images[0].cols;
    image_size.height = images[0].rows;
    std::vector<std::vector<cv::Point2f> > images_points;
  	// 识别所有图片的棋盘格
    for(int i=0;i<images.size();i++){
        std::vector<cv::Point2f> image_points;
        if(find_chessboard(images[i],image_points,board_size)>0){
             images_points.push_back(image_points);
        }
    }

    std::vector<cv::Point3f> image_points_in3d;
	// 计算棋盘格角点在棋盘格坐标系中的位置
    init_chessboard_3dpoints(board_size,image_points_in3d,0.045);  // 0.045为棋盘格一个格子的大小
    std::vector<std::vector<cv::Point3f> > images_points_in3d;
	// 生成所有识别出的标定板对应在各自棋盘格坐标系中的位置
    for(int i=0;i<images_points.size();i++){
        images_points_in3d.push_back(image_points_in3d);
    }
    cv::Mat intrinsic,distortion;
	// 使用张正友标定法计算内参畸变以及外参
    cv::calibrateCamera(images_points_in3d,
                        images_points,
                        image_size,
                        intrinsic,
                        distortion,
                        images_rvecs_mat,
                        images_tvecs_mat);
}

int main(int argc, char *argv[])
{
    std::string image_file_path = argv[1];
    std::vector<cv::Mat> images = get_all_iamge(image_file_path);
    calib_monocular(images);
    return 0;
}

ここに画像の説明を挿入します

例 2

単一のビューを調整します。

int cols = 10;
int rows = 7;
float distance = 30;    //间距30mm

cv::Size patternSize(cols,rows);
std::vector<cv::Point2f> corners;
std::vector<std::vector<cv::Point2f>> cornersVect;
std::vector<cv::Point3f> worldPoints;
std::vector<std::vector<cv::Point3f>> worldPointsVect;

for (int i=0;i<cols;i++)
{
    for (int j=0;j<rows;j++)
    {
        worldPoints.push_back(cv::Point3f(i*distance,j*distance,0));
    }
}

bool find=cv::findChessboardCorners(image,patternSize,corners);
cv::drawChessboardCorners(image,patternSize,corners,find);
cv::Mat cameraMatirx,distCoeffs;
std::vector<cv::Mat> rvecs,tvecs,rvecs2,tvecs2;
if (find)
{    
    cornersVect.push_back(corners);
    worldPointsVect.push_back(worldPoints);
    cv::calibrateCamera(worldPointsVect,
                        cornersVect,image.size(),
                        cameraMatirx,
                        distCoeffs,
                        rvecs,tvecs);
}

6.2 Pythonの実装

【学習メモ】python-Opencvの基本的な使い方 cv2.findChessboardCorners()

例1

単一のビューを調整します。

import numpy as np
import cv2
import matplotlib.pyplot as plt
import matplotlib.image as mpimg

fname='calibration_test.png'

image=cv2.imread(fname)
# plt.imshow(image)
# plt.show()

gray=cv2.cvtColor(image,cv2.COLOR_RGB2GRAY)
plt.imshow(gray,cmap='gray')
plt.show()

# Find the chessboard corners
nx=8
ny=6
ret, corners = cv2.findChessboardCorners(gray, (nx, ny), None)

print('ret:',ret)
# print(len(corners))

# If found, draw corners
if ret == True:
    # Draw and display the corners
    cv2.drawChessboardCorners(image, (nx, ny), corners, ret)
    plt.imshow(image)

次の図に示すように、9x7 チェッカーボード キャリブレーション ボードの場合、チェッカーボードの 1 行は 9、チェッカーボードの 1 列は 7 であるため、patternSize(w,h)内側のコーナー ポイントでは w=8 および h=6 となります。
ここに画像の説明を挿入します
ここに画像の説明を挿入します
ここに画像の説明を挿入します

例 2

単一のビューを調整します。

import numpy as np
import cv2 as cv
import glob


# termination criteria
# 
criteria = (cv.TERM_CRITERIA_MAX_ITER + cv.TERM_CRITERIA_EPS, 30, 0.001)

# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
"""
objp = 
[[0 0 0], 
[0 0 0],
...,
[0 0 0]], (42, 3)
"""
objp = np.zeros((6*7,3), np.float32)

"""
np.mgrid[0:7,0:6] = array([
[[0, 0, 0, 0, 0, 0],
[1, 1, 1, 1, 1, 1],
[2, 2, 2, 2, 2, 2],
[3, 3, 3, 3, 3, 3],
[4, 4, 4, 4, 4, 4],
[5, 5, 5, 5, 5, 5],
[6, 6, 6, 6, 6, 6]],

[[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5]]]), (2, 7, 6)

objp = array([
[0 0 0], 
[1 0 0], 
[2 0 0],
...,
[6 5 0]], (42, 3)
"""
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)

# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.

images = glob.glob('*.jpg')
for fname in images:
	img = cv.imread(fname)
    gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
    
    # Find the chess board corners
    ret, corners = cv.findChessboardCorners(gray, (7,6), None)
    
    # If found, add object points, image points (after refining them)
    if ret == True:
        objpoints.append(objp)
        corners2 = cv.cornerSubPix(gray,corners, (11,11), (-1,-1), criteria)
        imgpoints.append(corners2)
        
        # Draw and display the corners
        cv.drawChessboardCorners(img, (7,6), corners2, ret)

        cv.imshow('img', img)
        cv.waitKey(500)
cv.destroyAllWindows()

# Calibration
"""
camera matrix: mtx
distortion coefficients: dist
rotation vectors: rvecs
translation vectors: tvecs
"""
ret, mtx, dist, rvecs, tvecs = cv.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)

if ret == True:
    # Re-projection Error
    mean_error = 0
    for i in range(len(objpoints)):
         imgpoints2, _ = cv.projectPoints(objpoints[i], rvecs[i], tvecs[i], mtx, dist)
         error = cv.norm(imgpoints[i], imgpoints2, cv.NORM_L2)/len(imgpoints2)
         mean_error += error
    print( "total error: {}".format(mean_error/len(objpoints)) )

以下の図に示すように、8x7 チェッカーボード キャリブレーション ボードの場合、チェッカーボードの 1 行は 9、チェッカーボードの 1 列は 7 であるため、内側のコーナー ポイントpatternSize(w,h)では w=7 および h=6 となります。
ここに画像の説明を挿入します
ここに画像の説明を挿入します

4. 関連する経験

opencv キャリブレーション実装の概要 (ドット、チェッカーボード、非対称ドット)

おすすめ

転載: blog.csdn.net/m0_37605642/article/details/132484138