6

現在、X 線画像の 3D 再構成に取り組んでいるため、エピラインを使用していくつかの機能を一致させる前に、2 つのビューの画像を立体補正する必要があります。C++ で OpenCV 2.4 を使用しています。

この目的のために、一連の X 線画像 (コーン ビーム X 線画像、歪みパラメーターまたは実際の焦点距離を備えた実際のカメラはありません) を取得しました。横から見た(胸を横から見た)。使用できる仮想焦点距離 (両方のビューで等しい) などのいくつかのパラメーターを知っており、画像の解像度は 512x512px であるため、画像でのカメラの投影は両方のビューで (255,255) です。また、カメラが垂直であることも知っています。この情報から、回転行列 R と並進ベクトル t を作成しました (どちらも Matlab の 3D プロットを使用して検証しました)。

問題: R と t は実際には OpenCV でのステレオ修正に十分ですが、修正後の結果の画像は黒です。グーグルはステレオレクティファイのバグに私を導きましたが、動作するOpenCVステレオレクティフィケーションの例を実行できるので、それがバグであるとは思えません。Matlab で stereoRectification を試すと、少なくとも歪んだ整流結果が表示されます。

ここに私のC++コードがあります:

float camera_matrix_ap_data[] = {1207*2.0, 0.0, 255.0,
                 0.0, 1207*2, 255.0,
                                 0.0, 0.0, 1.0};
cv::Mat camera_matrix_ap(3, 3, CV_64F, camera_matrix_ap_data);
float camera_matrix_lat_data[] = {1207*2, 0.0, 255.0,
                 0.0, 1207*2, 255.0,
                                 0.0, 0.0, 1.0};
 cv::Mat camera_matrix_lat(3, 3, CV_64F, camera_matrix_lat_data);

 ///
 /// @brief the distortion matrices
 ///
 cv::Mat distortion_ap(4, 1, CV_64F, 0.0);
 cv::Mat distortion_lat(4, 1, CV_64F, 0.0);

 ///
 /// @brief Translation and Rotation matrices
 ///
 float R_data[] = {0.0, 0.0, 1.0,
           0.0, 1.0, 0.0,
           -1.0, 0.0, 0.0};
 float T_data[] = {-(1207.0*2 + 255), 0.0, 1207.0*2 + 255};

 cv::Mat R(3, 3, CV_64F, R_data);
 cv::Mat T(3, 1, CV_64F, T_data);

 for (int i=1; i<=20; i++) {
std::stringstream filenameAP_tmp;
std::stringstream filenameLAT_tmp;
filenameAP_tmp << "imageAP"<< i <<".jpg";
filenameAP = filenameAP_tmp.str();
filenameLAT_tmp << "imageLAT"<< i <<".jpg";
filenameLAT = filenameLAT_tmp.str();

    rectimg_ap = cv::imread(filenameAP);
    rectimg_lat = cv::imread(filenameLAT);
    // Yes, these images are grayscale

    /// Experimental
    /// Stereo rectify both images
 cv::Mat R1(3, 3, CV_64F);
 cv::Mat R2(3, 3, CV_64F);
 cv::Mat P1(3, 4, CV_64F);
 cv::Mat P2(3, 4, CV_64F);
 cv::Mat Q(4, 4, CV_64F);
 cv::Rect validRoi[2];

// buggy?
cv::stereoRectify(camera_matrix_ap, distortion_ap, camera_matrix_lat, distortion_lat, rectimg_ap.size(), R, T, R1, R2, P1, P2, Q, CALIB_ZERO_DISPARITY, 1, rectimg_ap.size(), &validRoi[0], &validRoi[1] );


// Maps for AP View
cv::Mat map1x(rectimg_ap.size(), CV_32FC1, 255.0);
cv::Mat map2x(rectimg_ap.size(), CV_32FC1, 255.0);
// Maps for LAT View
cv::Mat map1y(rectimg_ap.size(), CV_32FC1, 255.0);
cv::Mat map2y(rectimg_ap.size(), CV_32FC1, 255.0);

cv::initUndistortRectifyMap(camera_matrix_ap, distortion_ap, R1, P1, rectimg_ap.size(), CV_32FC1, map1x, map1y);
cv::initUndistortRectifyMap(camera_matrix_lat, distortion_lat, R2, P2, rectimg_lat.size(), CV_32FC1, map2x, map2y);

cv::Mat tmp1, tmp2;
cv::remap(rectimg_ap, tmp1, map1x, map1y, INTER_LINEAR);
cv::remap(rectimg_lat, tmp2, map2x, map2y, INTER_LINEAR);

//findHomography(rectimg_ap, rectimg_lat, CV_RANSAC);

}

リマップ後の整流画像は完全に黒なので、このコードまたは私の行列の何が問題なのか疑問に思っています。OpenCVとMatlabの間で座標系の軸に関する違いはありますか? 私が読んだように、OpenCV では z 軸はイメージ プレーンを指し、Matlab でも同じでした。

誰かが私を助けてくれたらうれしいです。私はこの問題に何週間も悩まされています。どうもありがとうございました!

4

1 に答える 1

1

「float」変数タイプを「double」に変更してみてください。CV_64F は 8 バイト (= 64 ビット) であるため、float ではなく double に対応します。私はあなたのコードを自分の行列値で試しましたが、うまくいきました。

于 2014-02-06T19:06:53.140 に答える