空間内のいくつかのポイントの3D座標を取得しようとしていますが、undistortPoints()
とtriangulatePoints()
の両方から奇妙な結果が得られます。
両方のカメラの解像度が異なるため、別々にキャリブレーションし、RMS _0,34
_と_0,43
_のエラーを取得し、stereoCalibrate()
を使用して詳細を取得しました行列、_0,708
_のRMS)を取得し、stereoRectify()
を使用して残りの行列を取得しました。これを使用して、収集した座標の作業を開始しましたが、奇妙な結果が得られます。
たとえば、入力は_(935, 262)
_であり、undistortPoints()
出力はあるポイントでは_(1228.709125, 342.79841)
_であり、別のポイントではそれぞれ_(934, 176)
_と_(1227.9016, 292.4686)
_です。これらのポイントは両方とも、歪みが最小であるフレームの中央に非常に近いため、これは奇妙です。 300ピクセル移動するとは思っていませんでした。
traingulatePoints()
に渡されると、結果はさらに奇妙になります。実際の3点間の距離を(定規を使用して)測定し、各画像のピクセル間の距離を計算しました。今回はポイントがかなり平坦な平面上にあったため、| AB |/| BC |のように、これら2つの長さ(ピクセルと実数)が一致しました。どちらの場合も約4/9でした。ただし、triangulatePoints()
は、| AB |/| BC |を使用して結果を表示します。 3/2または4/2であること。
これは私のコードです:
_double pointsBok[2] = { bokList[j].toFloat()+xBok/2, bokList[j+1].toFloat()+yBok/2 };
cv::Mat imgPointsBokProper = cv::Mat(1,1, CV_64FC2, pointsBok);
double pointsTyl[2] = { tylList[j].toFloat()+xTyl/2, tylList[j+1].toFloat()+yTyl/2 };
//cv::Mat imgPointsTyl = cv::Mat(2,1, CV_64FC1, pointsTyl);
cv::Mat imgPointsTylProper = cv::Mat(1,1, CV_64FC2, pointsTyl);
cv::undistortPoints(imgPointsBokProper, imgPointsBokProper,
intrinsicOne, distCoeffsOne, R1, P1);
cv::undistortPoints(imgPointsTylProper, imgPointsTylProper,
intrinsicTwo, distCoeffsTwo, R2, P2);
cv::triangulatePoints(P1, P2, imgWutBok, imgWutTyl, point4D);
double wResult = point4D.at<double>(3,0);
double realX = point4D.at<double>(0,0)/wResult;
double realY = point4D.at<double>(1,0)/wResult;
double realZ = point4D.at<double>(2,0)/wResult;
_
ポイント間の角度はちょっと良いですが、通常はそうではありません:
_`7,16816 168,389 4,44275` vs `5,85232 170,422 3,72561` (degrees)
`8,44743 166,835 4,71715` vs `12,4064 158,132 9,46158`
`9,34182 165,388 5,26994` vs `19,0785 150,883 10,0389`
_
フレーム全体でundistort()
を使用しようとしましたが、同じように奇妙な結果が得られました。 BポイントとCポイントの間の距離は常にほとんど変わらないはずですが、それでもこれが私が得たものです。
_7502,42
4876,46
3230,13
2740,67
2239,95
_
フレームごと。
ピクセル距離(下)と実際の距離(上)-非常に似ているはずです:
角度:
また、undistortPoints()
とundistort()
の両方で同じ結果が得られるべきではありませんか(ここに別のビデオセットがあります)。
関数cv :: unConstraintは、歪みの除去と再投影を一度に実行します。次の操作リストを実行します。
行列R1、P1、またはを渡す場合。 cv :: stereoCalibrate()のR2、P2、入力ポイントは歪みがなく、修正されます。整流とは、対応する点が同じy座標を持つように画像が変換されることを意味します。対応するポイントの配置を変更せずに、両方の画像に任意の平行移動またはスケーリングを適用できるため、画像修正のための独自のソリューションはありません。そうは言っても、cv :: stemeoCalibrate()は、投影の中心をかなりシフトする可能性があります(たとえば、300ピクセル)。純粋な歪みをなくしたい場合は、(R1の代わりに)単位行列と(P1の代わりに)元のカメラの行列Kを渡すことができます。これにより、元のピクセル座標と同様のピクセル座標が得られるはずです。