12

これらの各カメラのビューからオブジェクトの写真がある場合、OpenCV を使用して各カメラの回転行列、平行移動ベクトル、およびおそらくいくつかのスケーリング係数を取得するにはどうすればよいですか? すべての写真について、いくつかの特徴点の画像座標があります。すべての写真にすべての特徴点が表示されているわけではありません。オブジェクトの特徴点の計算された 3D 座標をわずかに異なるオブジェクトにマッピングして、2 番目のオブジェクトの形状を最初のオブジェクトに揃えたいと考えています。

使えると聞いたのですがcv::calibrateCamera(...)、なかなか使いこなせません...

誰かがそのような問題を経験したことがありますか?

4

2 に答える 2

12

OpenCVであなたと同じ問題に直面しました。ステレオ画像のペアがあり、カメラの外部パラメーターとすべての観測点の世界座標を計算したいと考えていました。この問題はここで扱われています:

ベルトルトKPホーン。相対的な方向性が再検討されました。ベルトルトKPホーン。人工知能研究所、マサチューセッツ工科大学、545 テクノロジー ...

http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.64.4700

しかし、この問題の適切な実装を見つけることができませんでした (おそらく見つかるでしょう)。時間の制約により、この論文のすべての数学を理解して自分で実装する時間がありませんでした。私はそれを解決するために何をしたかを説明します:

2 台のカメラがあり、最初のカメラには外部パラメータ RT = Matx::eye()があると仮定します。次に、2 番目のカメラの回転 R について推測します。両方の画像で観測された画像ポイントのすべてのペアについて、対応する光線の方向をワールド座標で計算し、それらを 2 次元配列dirsに格納します(編集: 内部カメラ パラメーターは既知であると想定されます)。すべてのカメラの向きを知っていると仮定しているため、これを行うことができます。ここで、過決定線形システムAC = 0を構築します。ここで、C は 2 番目のカメラの中心です。A を計算する関数を提供します。

Mat buildA(Matx<double, 3, 3> &R, Array<Vec3d, 2> dirs)
{
    CV_Assert(dirs.size(0) == 2);
    int pointCount = dirs.size(1);
    Mat A(pointCount, 3, DataType<double>::type);
    Vec3d *a = (Vec3d *)A.data;
    for (int i = 0; i < pointCount; i++)
    {
        a[i] = dirs(0, i).cross(toVec(R*dirs(1, i)));
        double length = norm(a[i]);
        if (length == 0.0)
        {
            CV_Assert(false);
        }
        else
        {
            a[i] *= (1.0/length);
        }
    }
    return A;
}

次にcv::SVD::solveZ(A)を呼び出すと、このシステムのノルム 1 の最小二乗解が得られます。このようにして、2 番目のカメラの回転と移動を取得します。ただし、2 番目のカメラの回転について推測したので、その回転についていくつかの推測を行い (cv::Rodrigues を使用して回転行列を計算する 3x1 ベクトル オメガを使用してパラメーター化)、次にこの推測を次のように絞り込みます。システム AC = 0 をレーベンバーグ・マルカート オプティマイザーで数値ヤコビアンで繰り返し解く。それは私にとってはうまくいきますが、少し汚いので、時間があれば、論文で説明されていることを実装することをお勧めします.

編集:

以下は、留数のベクトルを評価するための Levenberg-Marquardt オプティマイザのルーチンです。

void Stereo::eval(Mat &X, Mat &residues, Mat &weights)
{

        Matx<double, 3, 3> R2Ref = getRot(X); // Map the 3x1 euler angle to a rotation matrix
        Mat A = buildA(R2Ref, _dirs); // Compute the A matrix that measures the distance between ray pairs
        Vec3d c;
        Mat cMat(c, false);
        SVD::solveZ(A, cMat); // Find the optimum camera centre of the second camera at distance 1 from the first camera
        residues = A*cMat; // Compute the  output vector whose length we are minimizing
    weights.setTo(1.0);
}

ところで、インターネットでもう少し検索したところ、カメラ間の相対的な向きを計算するのに役立つ他のコードが見つかりました。私はまだコードを試していませんが、役に立ちそうです:

http://www9.in.tum.de/praktika/ppbv.WS02/doc/html/reference/cpp/toc_tools_stereo.html

http://lear.inrialpes.fr/people/triggs/src/

http://www.maths.lth.se/vision/downloads/

于 2011-11-19T08:10:25.753 に答える
2

これらの静的カメラは、ステレオ ペアとして将来使用するために調整したいですか? この場合、cv::stereoCalibrate()関数を使用します。OpenCV にはいくつかのサンプル コードが含まれており、そのうちの 1 つが stereo_calib.cpp です。

于 2011-11-18T14:09:26.273 に答える