最初にこれを OpenCV フォーラムに投稿しましたが、残念ながら、あまり多くのビューや返信が得られなかったので、誰かが提案する方向性を持っていることを期待してここに投稿していますか?
私は Bumblebee XB3 ステレオ カメラを使用しており、レンズが 3 つあります。約 3 週間かけて、フォーラム、チュートリアル、Learning OpenCV の本、およびステレオ キャリブレーションとステレオ マッチング機能の使用に関する実際の OpenCV ドキュメントを読みました。要約すると、私の問題は、生成された良好な視差マップがありますが、点群が非常に貧弱で、歪んだ/つぶれたように見え、実際のシーンを代表していないことです。
私がこれまでに行ったこと:
OpenCV の stereo_calibration と stereo_matching の例を使用して、次のことを行いました。
チェス盤の画像を使用してステレオ カメラを調整しました
1) 生のシーン画像: http://answers.opencv.org/upfiles/1380850337241986.jpg
2) カメラのキャリブレーション後に行列を使用して、カメラから取得した生の画像を修正しました
: http://answers.opencv.org/upfiles/ 13808502665723237.png
3) ステレオ マッチング (SGBM) を使用して調整された画像から視差画像を生成
: 4) これらの視差を 3D ポイント クラウドに投影
私の問題に対する排除としてこれまでに行ったこと:
- 1 枚目と 2 枚目の画像、次に 2 枚目と 3 枚目のレンズ、最後に 1 枚目と 2 枚目の画像を試しました。
- チェス盤のキャプチャのキャリブレーションを、距離を変えて (近づける/遠ざける) 再実行しました。
- キャリブレーションに 20 を超えるステレオ ペアを使用しました
- さまざまなチェス盤のサイズを使用: キャリブレーションに 9x6 のチェス盤の画像を使用していましたが、代わりに 8x5 の画像を使用するように切り替えました
- ブロック マッチングと SGBM バリアントを使用してみましたが、
比較的似たような結果が得られました。これまでのところ、 SGBM
でより良い結果が得られています。 - 視差の範囲を変更したり、SAD ウィンドウのサイズを変更したりしましたが、ほとんど改善されていません。
問題があると思われるのは次のとおりです。
私の視差画像は比較的許容できるように見えますが、次のステップは、Q 行列を使用して 3D ポイント クラウドに移動することです。正しい Q 行列を生成するためにカメラを正しく調整していないのではないかと思います。残念ながら、より良い Q マトリックスを得るために他に何ができるかを考えるという点で、私は壁にぶつかりました。誰かが今後の方法を提案してもらえますか?
問題があると思われるもう 1 つの点は、cv::stereoCalibrate 関数を使用するときに行っている仮定です。とりあえず、各カメラを個別に調整して、カメラと歪み (cameraMatrix[0]、distCoeffs[0] および cameraMatrix[1]、distCoeffs[1]) 行列を取得し、stereoCalibrate 関数の複雑さを少し簡単にします。
stereoCalibrate(objectPoints, imagePoints[0], imagePoints[1],
cameraMatrix[0], distCoeffs[0],
cameraMatrix[1], distCoeffs[1],
imageSize, R, T, E, F,
TermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, 100, 1e-5),
//CV_CALIB_FIX_ASPECT_RATIO +
//CV_CALIB_ZERO_TANGENT_DIST +
//CV_CALIB_SAME_FOCAL_LENGTH +
CV_CALIB_RATIONAL_MODEL
//CV_CALIB_FIX_K3 + CV_CALIB_FIX_K4 + CV_CALIB_FIX_K5
);
さらに、視差から点群への移行方法について言及することも役立つと思います。OpenCV の cv::reprojectImageTo3D を使用してから、データを PCL ポイント クラウド構造に書き込みます。関連するコードは次のとおりです。
cv::reprojectImageTo3D( imgDisparity16S, reconstructed3D, Q, false, CV_32F);
for (int i = 0; i < reconstructed3D.rows; i++)
{
for (int j = 0; j < reconstructed3D.cols; j++)
{
cv::Point3f cvPoint = reconstructed3D.at<cv::Point3f>(i, j);
//Filling in a PCL structure
pcl::PointXYZRGB point;
point.x = cvPoint.x;
point.y = cvPoint.y;
point.z = cvPoint.z;
point.rgb = rectified_imgRight.at<cv::Vec3b>(i,j)[0]; //Grey information
point_cloud_ptr->points.push_back (point);
}
}
point_cloud_ptr->width = (int) point_cloud_ptr->points.size();
point_cloud_ptr->height = 1;
pcl::io::savePCDFileASCII("OpenCV-PointCloud.pts", *point_cloud_ptr);
PS: これらの画像をアップロードすることにした理由は、シーンにテクスチャがあるためです。そのため、シーンが均質すぎるという返事を期待していました。パーテーションのカバーも椅子も質感豊かです。
いくつかの質問:
点群の一部と思われる画像/視差面を削除するのを手伝ってもらえますか? なぜこうなった?
私が間違っていることは明らかですか?コードを投稿しますが、提供されている OpenCV の例と非常によく似ており、これ以上創造的なことをしているとは思いません。関係があるかもしれない特定のセクションがあれば、私はできます。
私の素朴な意見では、視差画像は問題ないようです。しかし、点群は、比較的まともな視差画像から期待していたものではなく、はるかに悪い.
それが役立つ場合は、カメラのキャリブレーション後に取得した Q マトリックスについて言及しました。これをLearning OpenCVの本と比較すると、露骨に間違っているものはないと思います...
Q: rows: 4
cols: 4
data: [ 1., 0., 0., -5.9767076110839844e+002, 0., 1., 0.,
-5.0785438156127930e+002, 0., 0., 0., 6.8683948509213735e+002, 0.,
0., -4.4965180874519222e+000, 0. ]
読んでくれてありがとう。この時点で何か提案があれば正直に感謝します...