を使用すると、画像平面上のピクセル単位で画像点があるとすべてのcv::Vec2d imagePoint(u, v);
まず、カメラ座標系でこの点を変換すべきです。カメラの組み込み関数のパラメータ(カメラ行列とレンズ歪み係数)が既知であると仮定すると、あなたの観察imagePoint
の理想(u', v')
座標を計算することができる:
u'' = (u - cx)/fx
v'' = (v - cy)/fy
(u', v') = undistort(u'', v'', distCoeffs)
cx
とcy
を主点の座標がされています通常はイメージセンターの周りにあり、さらにfx
とfy
はピクセル単位の焦点距離です(カメラマトリックスから取得できます)。 distCoeffs
には半径方向/接線方向の歪み係数が含まれています。これもまたcv::calibrateCamera(...)
の結果です。 cv::undistortPoints(...)
がないか、既定R
とP
パラメータを持つ関数を呼び出すことによってこれを行いますので、
とにかく、あなたは、手動で(u', v')
を計算するべきではありません。
カメラ座標系におけるimagePoint
のポイントは以下の通りです:
cv::Mat camToWorld = cv::Mat::eye(4, 4, CV_64FC1);
// Fill camToWorld with [R^T|-R^T*t]
// ...
cameraPt.push_back(1.0);
cv::Mat worldPt = camToWorld * cameraPt;
:この時点で
std::vector<cv::Vec2d> imagePts;
std::vector<cv::Vec2d> idealPts;
imagePts.push_back(imagePoint);
cv::undistortPoints(imagePts, idealPts, cameraMatrix, distCoeffs);
const double lambda = 1.0;
cv::Mat cameraPt(3, 1, CV_64F);
cameraPt.at<double>(0) = idealPts[0][0] * lambda;
cameraPt.at<double>(1) = idealPts[1][1] * lambda;
cameraPt.at<double>(2) = lambda;
、あなたはワールド座標系でcameraPt
を表現するためにワールド変換行列にカメラを必要とします
これまでのところ、worldPt
は、imagePoint
に対応するワールド座標系のレイを定義しています。つまり、線/線の各点は同じimagePoint
に投影することができるので、同じimagePoint
に属する世界の点数は無限にあります。しかし、例えば、Möller-Trumbore ray-triangle intersectionアルゴリズムでは、世界の平面上の1つの3D点を決定することができます。
solvePnPからのオブジェクトポイントに、回転と平行移動の合成変換を乗算してください。 – Micka
わかりましたが、私は確信しています。私はsolvePnPを使用しません。私は他のライブラリを使って(x、y)を得る。私は画像座標(ピクセル)で(x、y)座標を持っています。次に、逆回転行列でこの点を掛ける必要があります。それから、R^-1 * tを引く必要があります。私がよく考えると、元の座標は同次座標でなければなりませんか?私は正しい? –
ポイントを変換しないで、オブジェクトの基本3Dポイント(重心など)を変換します。たぶん私たちはさまざまなことについて話しています。あなたの質問にあなたが何を持っているのか、どのような回転と平行移動を意味し、どのように計算したのでしょうか? – Micka