OpenCV-Python(9ポイントキャリブレーション方法)に基づくロボットのハンドアイキャリブレーションと再投影
記事のディレクトリ
序文:
前回の記事を転載し、9点校正の原理を書きました。
この記事は、キャリブレーションの方法を記録し、キャリブレーションパラメーターと再投影精度を計算することです。
中国のコミュニティでは、「9点キャリブレーション」と「再投影」の関連キーワードを検索していないようです。
しかし、張正陽の校正方法には、再投影誤差の概念があります。
計算された変換行列Mは、変換式に代入されて、新しいターゲット座標と元の座標の間の誤差が計算されます。
次の式で表されます。
new_target_pos = origin_pos * M
e = MSE(new_target_pos、target_pos)
直感的には、キャリブレーションパラメータがすべてのサンプルをカバーし、最小二乗法で適合している場合、得られる誤差は比較的小さいはずです。
そこで、一般的に使用されている深層学習の方法を借りて、トレーニングセットとテストセットを分けました。
また、さまざまなトレーニングサンプルが結果に与える影響をテストしました。
結果は素晴らしいです!
- 実際、この関数は3点で使用できますが、1点には2つの方程式があり、6つの未知数があるため、少なくとも3点が必要です。
データセットにいくつかの異常点がある可能性があり、異常点は結果に大きな影響を与えます! - 適切なデータポイントが見つかる限り、最適化が最適化されていない場合、結果はより良くなります。
- 特に大きなエラーがある場合は、もう少しデータを使用すると、効果も良好です。
- 再投影誤差は0.4mmまたは0.4ピクセルです。
実験プロセス:
アイツーハンドキャリブレーション:
カメラは固定されており、ロボットのベース座標系に対する相対位置は変更されません。そして、ロボットの端は固定平面上を移動します。つまり、ホモグラフィ行列の変換関係のみが必要です。
実験プロセスは次のとおりです。
- ハンドアイシステムのシーンを設定します。カメラは固定されており、ロボットアームが針先を駆動して固定平面上を移動します。
- キャリブレーションサンプルコレクション。カメラ画像の取得、および対応するロボットの関節構成の取得を含みます。–calibration_data_collected_main.py
- 画像処理により、キャリブレーション針先を抽出し、ロボット座標系で針先の座標を計算します。各ロケーションポイントの先端ピクセル座標、先端ワールド座標、および終了座標を記録します
- キャリブレーションパラメータ行列M--calibration_class.pyを計算します
- 再投影エラーavg_e--calibration_class.pyを計算します
キャリブレーション実験で使用される主な環境構成とツールは次のとおりです。
-
オペレーティングシステム:Windows 764ビット
-
画像処理ツール:OpenCV-Python 3.4。*インストールできない場合、バージョンは4. *以上で、estimated2DAffineが機能しているようです。テストしていません。
-
ロボットとカメラ:Siasun SCR5 7自由度の協調型ロボットアーム、Hikvision産業用カメラMV-CA013-21UC
calibration_class.pyは単独で使用できます。独立したキャリブレーションポイントのセットがある限り。
次に、コードに移動しますか?
コード:
最初に私のgithubリンクを掛けてください、このコードは少し多すぎます。
https://github.com/kaixindelele/Eye-to-Hand-Calibration
役立つ場合は、スターを注文することを忘れないでください〜
コアコード:
変換行列mを計算します
def get_m(self,
origin_points_set,
target_points_set):
# 确保两个点集的数量级不要差距过大,否则会输出None,看到这个输出,我直接好家伙。
# 明明回家前,还能输出一个好的转换矩阵,为什么一回家就报错?我错哪儿了...
m = cv2.estimateRigidTransform(origin_points_set,
target_points_set,
fullAffine=True)
return m
再投影エラーの計算:
def reproject(self,
origin_points_set,
target_points_set,
m):
error_list = []
for index in range(len(origin_points_set)):
p_origin = list(origin_points_set[index])
p_origin.append(1)
p_origin = np.array(p_origin)
p_tar = target_points_set[index]
new_tar = np.dot(m, p_origin)
error = np.linalg.norm(new_tar-p_tar[:2])
error_list.append(error)
print("avg_e:", np.mean(np.array(error_list)))
return np.mean(np.array(error_list))
再射影エラートレーニングサンプル数テスト:
データ分析:
横軸は9から始まり29で終わるトレーニングサンプルの数であり、合計サンプルサイズは37です。
縦軸はエラーサイズ(ミリメートル単位)です。
タイトルの説明:xyは針先の座標です。 uvは針のピクセルピクセル座標です。xy2uvは、9ポイントのキャリブレーションによってuv = m xyのmを計算し、テストサンプルにmを代入して、新しいuv_pred_test = m xy_testを計算し、計算エラーe = mse( uv_pred、uv_origin_test)
mtの場合、次のようになります
。uv= m * xyでmを計算した後、次のような線形方程式のシステムを使用します。t_rx=(A * t_px)+ B * t_py + C);
t_ry =(D * t_px)+ E * t_py + F);
mtをxy = mt * uvで解きます。次に、再投影エラーを計算します。
結果は序文で分析されています。
総括する:
実際、非常に多くのレコードがあるため、コアコンテンツは革新的なものではありません。
9点校正の再投影誤差については、19年後にICRAに実際に使用された記事があることがわかりました。
しかし、それらは目を合わせた構造になっています。2つのロボットアームは、構造と原理が私のものよりもはるかに複雑です...
私の小さなプロジェクトでは1週間近くかかりました。時間はどこに行きましたか?
私はそれをレビューしました:
1つはキャリブレーションプロセス全体についての疑問です。私はこの種の手と目の構造をキャリブレーションしたことはなく、既製のツールキットも見つけていません。
情報の流れ全体を理解していなかったので、最初はどのデータを収集すればよいのかさえわかりませんでした。
2つ目は、キャリブレーションボードがないことです。特徴点の検出には、自分で作成した先端検出プログラムを使用する必要があります。このプログラムを長い間調整してきました。最後に、シーン情報を使用して、最適化されたより優れた検出モジュール。0.04秒で完了します。1フレームの速度で、2ピクセル以内のエラーが発生します。
次に、このごみのOpenCVバージョンの問題があります。4を超えるバージョンにはcv2.estimateRigidTransformがありません。3.4バージョンしか見つかりません。
最後に、ピクセル座標の範囲が0〜280であり、初期の針点座標の範囲が0〜0.8であり、3桁の差があるため、浮動小数点数の精度の問題があります。ポイントセットは次のとおりです。直接関数に取り込まれます。コンピューターが異なれば戻り値はハードウェアごとに異なります。デスクトップコンピューターで非常に小さい値の行列mを取得できますが、ラップトップでは、同じコードとデータで戻り値がNoneになりますか?私のラップトップが壊れているのではないかと思いました。
テストを行う:
Googleのコラボでテストします。最大精度はfloat128です。
テストスクリプトは非常に単純です。
import numpy as np
print(np.finfo(np.longdouble))
out:Machine parameters for float128
---------------------------------------------------------------
precision = 18 resolution = 1e-18
machep = -63 eps = 1.084202172485504434e-19
negep = -64 epsneg = 5.42101086242752217e-20
minexp = -16382 tiny = 3.3621031431120935063e-4932
maxexp = 16384 max = 1.189731495357231765e+4932
nexp = 15 min = -max
そして、私のノートブックの最大精度はfloat64です。興味深いことに、このピットは、おそらくこのことによってピットされるときに覚えておく必要があります。
Machine parameters for float64
---------------------------------------------------------------
precision = 15 resolution = 1.0000000000000001e-15
machep = -52 eps = 2.2204460492503131e-16
negep = -53 epsneg = 1.1102230246251565e-16
minexp = -1022 tiny = 2.2250738585072014e-308
maxexp = 1024 max = 1.7976931348623157e+308
nexp = 11 min = -max