OpenCV 3.0.0.devで使用されている魚眼カメラモデルと格闘しています。私はこの リンク のドキュメントを数回読みました。特に"詳細な説明"の部分と魚眼レンズの歪みをモデル化した式を読みました。今までに私は2つの懸念を持っています:
リストされている投影モデルに基づいて ここ および "魚眼レンズモデルの精度"の概念的な説明に基づいて、ヒューズによって、私はどれを理解することができません投影modelはOpenCVの実装で使用されています。
説明が非常に簡潔なので、OpenCV開発者が魚眼名前空間を実装するために使用する主な参考資料を知っておく必要があります。そうすれば、私は真剣に取り組んで詳細を知ることができます。 P.S. OpenCV 3.0.0-devのドキュメントを確認しましたが、何も役に立ちませんでした。
OpenCV 3.0.0 Fisheyeカメラモデルは、Brownモデルも、OPがPanotoolsから参照するモデルも使用せず、JuhoKannalaとSamiS.Brandtによる汎用カメラモデルを使用します。
Cfrが彼の答えを指摘しているように、 このコメント (OpenCVで魚眼モデルを実装した)Ilya Krylovから、 Jean-Yves BouguetのMatlab用のカメラキャリブレーションツールボックス:
Jean-Yves BouguetのWebサイト( リンク )は、次に、論文 従来型、広角、魚眼レンズの一般的なカメラモデルとキャリブレーション方法 、および言う:
キャリブレーションツールボックスに含まれる「文書化されていない」魚眼モデルは、この非常に優れた論文の式(3)で説明されている等距離投影モデルに従います。歪みモデルは、k1 = 1(それ以外の場合はfと区別できません)を除いて、式(6)に従います。
私の意見では、式(3)と式(6)は異なるモデルに対応しているため、誤解を招く記述または明白な誤解です。式(6)は、著者が汎用カメラモデル(したがって、論文の名前)。より正確には、式(6)はカメラモデルとして使用され、式(8)および(9)はこのモデルからの「歪み」または偏差として使用されることを意図していました。
しかし、オデッセイは終わっていません。 OpenCVの実装( ドキュメント による)は、最初にピンホール投影を計算して、視野角(3Dポイント、投影の中心、および光軸の間の角度)を見つけます。 これは、魚眼モデルを使用して90ºで光線を投影できないことを意味します(または0で除算します)または90ºに近い(zが十分に小さい場合、オーバーフローなどの数値安定性の問題が発生する可能性があります)。さらに、90º以上の光線で機能するかどうかはわかりません。これらすべてが、魚眼レンズまたは広角レンズ用の魚眼カメラモデルの「有用性」を本当に不思議に思っています。
あなたがそれについて懐疑的であるならば、あなたはOpenCVのソースコードを見ることができます、具体的には sources\modules\calib3d\src\fisheye.cpp (私はいくつかのコメントを追加しました)
void cv::fisheye::projectPoints(InputArray objectPoints, OutputArray imagePoints, InputArray _rvec,
InputArray _tvec, InputArray _K, InputArray _D, double alpha, OutputArray jacobian)
{
...
Rodrigues(om, R, dRdom);
Affine3d aff(om, T);
...
Vec3d Xi = objectPoints.depth() == CV_32F ? (Vec3d)Xf[i] : Xd[i];
Vec3d Y = aff*Xi; /* To transform to camera reference frame*/
Vec2d x(Y[0]/Y[2], Y[1]/Y[2]); /* <- The root of all evil (division by z) */
double r2 = x.dot(x);
double r = std::sqrt(r2);
// Angle of the incoming ray:
double theta = atan(r);
double theta2 = theta*theta, theta3 = theta2*theta, theta4 = theta2*theta2, theta5 = theta4*theta,
theta6 = theta3*theta3, theta7 = theta6*theta, theta8 = theta4*theta4, theta9 = theta8*theta;
double theta_d = theta + k[0]*theta3 + k[1]*theta5 + k[2]*theta7 + k[3]*theta9;
double inv_r = r > 1e-8 ? 1.0/r : 1;
double cdist = r > 1e-8 ? theta_d * inv_r : 1;
Vec2d xd1 = x * cdist;
Vec2d xd3(xd1[0] + alpha*xd1[1], xd1[1]);
Vec2d final_point(xd3[0] * f[0] + c[0], xd3[1] * f[1] + c[1]);
...
}
Update: This プルリクエストは、角度が90°以上の光線の問題を修正します。 2018年4月の時点では、まだマスターにマージされていませんが、OpenCV 4.xで検討されています キャリブレーションモジュール (チェック キャリブレーションモジュールの説明 も)
何時間も読んだ後、OpenCVの魚眼ドキュメントの式θ= atan(r)は、ピンホール投影に関連するr = f *tanθの正規化された逆関数であり、したがって、上記のリンクはOpenCVで使用されます。
また、歪曲モデルについては、2001年の論文「多面幾何とレンズ歪みの連立線形推定」のフィッツギボンの分割モデルが使われていると思います。ヒューズの2008年の論文「魚眼カメラの幾何学的歪み補正のレビュー」によると、他の選択肢の中には「奇数多項式モデル」と「多項式魚眼変換」があります。彼の論文の2ページで、彼は次のように書いています。
"(1)(これは奇数多項式モデルを参照)および(3)(これは分割モデルを参照します。 OpenCVで使用されているもの)は、標準の非魚眼レンズの歪みを説明するために使用できますが、これらの多項式モデルは、魚眼レンズによって導入される歪みのレベルを説明するには不十分であると一般に考えられています。ShahとAggarwalは、 [9](歪みモデルと精度推定を備えた高歪み魚眼レンズカメラの固有パラメータキャリブレーション手順)7次を使用する場合でも魚眼の放射状歪みをモデル化するための(1)のバージョン、かなりの歪みが残っています、より自由度の高いモデルを使用する必要がある範囲で、したがって奇数係数と偶数係数の両方を使用する多項式(代わりに)単にどちらか一方の)を使用して、放射状歪みの導入をモデル化できます魚眼レンズで撮影」
結局のところ、OpenCVの魚眼モデルは適用範囲が非常に限られており、歪みモデルと投影モデルの観点からはるかに強化できると結論付けています。魚眼名前空間を実装するためにOpenCV開発者がどの論文を使用したかを知る必要があることを再度強調したいと思います。
これについてのコメントをいただければ幸いです。
bouguetのcalib_toolコード「project_points_fisheye.m」によると
%Definitions:
%Let P be a point in 3D of coordinates X in the world reference frame (stored in the matrix X)
%The coordinate vector of P in the camera reference frame is: Xc = R*X + T
%where R is the rotation matrix corresponding to the rotation vector om: R = rodrigues(om);
%call x, y and z the 3 coordinates of Xc: x = Xc(1); y = Xc(2); z = Xc(3);
%The pinehole projection coordinates of P is [a;b] where a=x/z and b=y/z.
%call r^2 = a^2 + b^2,
%call theta = atan(r),
%Fisheye distortion -> theta_d = theta * (1 + k(1)*theta^2 + k(2)*theta^4 + k(3)*theta^6 + k(4)*theta^8)
%
%The distorted point coordinates are: xd = [xx;yy] where:
%
%xx = (theta_d / r) * x
%yy = (theta_d / r) * y
%
%Finally, convertion into pixel coordinates: The final pixel coordinates vector xp=[xxp;yyp] where:
%
%xxp = f(1)*(xx + alpha*yy) + c(1)
%yyp = f(2)*yy + c(2)
Brown-Conradyモデル 、 Matlabのカメラキャリブレーションツールボックス リファレンスで言及されています。このホワイトペーパーで説明: D。C. Brown「近距離カメラキャリブレーション」 。
また、現在のOpenCVモデルは接線方向の歪みを無視しているようです(P(r)
)。
これを参照してください コメント 。