カメラキャリブレーション - kinectv1 外部パラメータキャリブレーション (epnp)

説明する

1. kinectv1の外部パラメータキャリブレーション
2. Opencvのepnp関数を利用して実現
3. Pythonプログラミング

1. 校正要件

ピクセル座標 (u, v) は kinectv1 のカラー カメラに従って取得され、カメラ座標系の (u, v) に対応する Zc は kinectv1 の深度カメラを通じて取得され、その後、取得したカメラの内部および外部パラメータに従ってポイントが復元されます。
深度情報がない場合、平面のワールド座標を見つけることしかできず、実際の Z 値を復元することはできません。カメラ キャリブレーションの原理と、関係する各座標系の関係と実際的な意味が含まれるこのブログをお読みください。校正中。

2. カメラの紹介

キネクトカメラの紹介

奥行き情報の実際の意味は、点からカメラ光軸面までの垂直距離、つまりカメラ座標系における Zc 値です。

3. 内部基準校正


実際に使用するカラーキャリブレーションファイルを使用して、Kinectカメラの内部パラメータのキャリブレーションを行うことができます。

4. 校正方法

1. 原理と実践関連記事

キャリブレーションには pnp 法を使用します。インターネット上には pnp キャリブレーションの原理が多数あります。この記事の原理は非常に優れており、この記事の応用は非常に優れていると思います。
次のカタログ:
「カメラ ポーズ推定 0: PNP 問題の解決方法の基本原理」
「カメラ ポーズ推定 1: 4 つの特徴点に基づくカメラ ポーズの推定」
「カメラ ポーズ推定 1_1: OpenCV:solvePnP の二次パッケージングとパフォーマンス テスト」
「カメラ ポーズ推定 2: [アプリケーション] リアルタイムの姿勢推定と 3D 再構成カメラの姿勢」
「カメラの姿勢推定 3: 2 枚の画像の姿勢推定結果に基づいて点の世界座標を求める」
pnp ソリューションは何のためにありますか? 4 つのペアが必要です座標:最も一般的な幾何学的な画像解釈方法

2. opencv の pnp キャリブレーション関数solvepnp

retval1, rvec1, tvec1=cv.solvePnP(world_point,pixel_point,K,distortion_coefficients)

この関数のパラメータは、ワールド座標、ピクセル座標、内部参照行列、歪み行列、反復回数の順に入力され、メソッドの最後のパラメータは以下の 3 種類があり、ブロガーは反復解法と epnp を使用しています
。メソッドは世界座標を復元できますが、違いはそれほど大きくありません。

ここに画像の説明を挿入

5. 校正実験

カメラの高さは天板から1m、光軸面と天板は一定の傾斜角を持ち、市松模様の各格子は4cmです。

1. ポイントの選択

デフォルトの方法を使用する場合は、下図の四隅をキャリブレーション点として選択します。
epnp キャリブレーションを使用する場合、
1 番目の制御点として下図の水色の点を選択し、
2 番目の制御点として青の点を選択し、
3 番目の制御点として赤い点を選択し、
4 番目の制御点として緑の点を選択します。

ワールド座標の方向、
垂直デスクトップが上向きが Z 軸の正の方向、
青い点から赤い点までが Y 軸の負の方向、
青い点から緑の点が Y 軸の正の方向です。 X軸
ここに画像の説明を挿入

2.epnp関数呼び出しコード(Python)

# encoding: utf-8
import cv2 as cv
import numpy as np
import yaml
import os
import io
with open("file/rgb_A22593W01131223A.yaml", 'rb') as f:   #写入正确的文件路径
    data = yaml.load(f)
    camera_matrix = data['camera_matrix']['data']
    distortion_coefficients = data['distortion_coefficients']['data']

distortion_coefficients=np.array(distortion_coefficients)


K= np.zeros([3, 3], dtype=float)
# K=np.mat(K)

K[0,0]=camera_matrix[0]
K[0,1]=camera_matrix[1]
K[0,2]=camera_matrix[2]

K[1,0]=camera_matrix[3]
K[1,1]=camera_matrix[4]
K[1,2]=camera_matrix[5]
#
K[2,0]=camera_matrix[6]
K[2,1]=camera_matrix[7]
K[2,2]=camera_matrix[8]



pixel_point= np.array([
    [328.0, 172.0],
    [158.0, 58.0],
    [137.0, 310.0],
    [508.0, 55.0]
                            ])
world_point= np.array([
                            [360.0, -280.0, 90.0],
                             [0.0, 0.0, 0.0],
                             [0.0, -520.0, 0.0],
                            [720.0, 0.0, 0.0]
                            ])

retval1, rvec1, tvec1=cv.solvePnP(world_point,pixel_point,K,distortion_coefficients, useExtrinsicGuess=1, flags=cv.SOLVEPNP_EPNP)
r1 = cv.Rodrigues(rvec1,jacobian=0)
print(r1[0])
print(tvec1)

3. 結果の分析

(1) ピクセル座標と実際の座標

pixel_point= np.array([
    [328.0, 172.0],
    [158.0, 58.0],
    [137.0, 310.0],
    [508.0, 55.0]
                            ])
world_point= np.array([
                            [360.0, -280.0, 90.0],
                             [0.0, 0.0, 0.0],
                             [0.0, -520.0, 0.0],
                            [720.0, 0.0, 0.0]
                            ])

(2) 外部パラメータマトリクス

[[ 9.98539408e-01  1.49732959e-02 -5.19119596e-02 -3.28108974e+02]
 [ 3.34250968e-03 -9.76109922e-01 -2.17251577e-01 -3.78811896e+02]
 [-5.39247510e-02  2.16760745e-01 -9.74734272e-01  1.18536981e+03]
 [ 0.00000000e+00  0.00000000e+00  0.00000000e+00  1.00000000e+00]]

(3) 計算結果

4 つの制御点と 2 つの任意の点の検証では、カメラ自体によって取得される深度値を 7 cm 補正します。
任意の2点の座標

720,-520, 0
200,-80,25

結果

[[ 3.59876941e+02 -5.67379331e-01 -7.67101745e+00  7.19528649e+02 7.25095153e+02  2.00069031e+02]
 [-2.80541796e+02  7.66719036e-01 -5.24430480e+02 -7.01423857e-01 -5.22356724e+02 -8.39731426e+01]
 [ 9.35158355e+01  1.39182581e+01 -6.04520752e+00  8.63555196e+00 -9.18937150e+00  2.29591386e+01]
 [ 1.00000000e+00  1.00000000e+00  1.00000000e+00  1.00000000e+00 1.00000000e+00  1.00000000e+00]]

誤差は1センチ以内です

おすすめ

転載: blog.csdn.net/puqian13/article/details/108504193