2017-01-20 6 views
3

カメラから画像を取得すると(レンズの歪みがないように)、長方形のオブジェクトを検出する必要があります。マーカーが良い例です。マーカーについては、コーナーカウント、最小サイズ、ボードのコントラストと凸凹をチェックします。私は、大量の偽の矩形がある場合にこれを改善する方法について考えました。通常、これらのすべてが原因視点は、形状のこれらの種類を許可する場合、我々は判断できないカメラについては何も知らなくても、有効な遠近法で長方形のオブジェクト品質を見つける

image

: は、ここでは例の画像です。私は実際の長方形のサイズ(または少なくとも比率)を知っています。だから私は、それらを再投影してエラーをチェックするだけで、これらの形の多くを無視できるはずだという考えがありました。 solvePnPRansacを使用している場合と同様に、形状が不可能な場合は収束できません。それが収束しなければ私はそれを無視します。悲しいことに、OpenCVの解決関数のどれもエラーやコンバージェンスをチェックすることはできません。私は実際にはいくつかの比率や品質が必要です。なぜなら、いくつかの長方形が重なる可能性があるからです。 3の

overlap image

一つは、実際に正しいか、または少なくとも「最良の」:例えば、私のオブジェクトのファインダーには、これらの矩形を識別します。しかし、それがどれであるかを知るには何らかの方法が必要です。私はカメラの視点のために線の長さのようなものを使用することはできません。だから私はちょうど私が解決でき、どれが最小のエラーを持っているかを知ることができると思った。

画像にレンズの歪みはありませんが、solvePnPがあっても通常はDを渡すことができます。 これも可能ですか、何か不足していますか? 私はsolvePnPRansacをハッキングしてコンバージェンスを返すことができると思いますが、もっと簡単な方法がありますか?

+0

これは本当にクールな質問ですが、私はそれが少しあまりにも理論だとちょっと議論を必要とするので、それがスタック交換フォーマットに適合疑います。あなたは本当に他の人との問題について話すためにいくつかのCVフォーラムを試してください。 –

+0

投影された矩形の縦横比を計算することができます(http://stackoverflow.com/questions/38285229/counting-aspect-ratio-of-perspective-transform-destination-image/38402378#38402378を参照)。アスペクト比をすでに知っている場合は、次のことができます。コーナーに基づいてアスペクト比を推定し、それが知っている比率に一致するかどうかを確認します。 – y300

+0

TomášZato - 私はanswers.opencv.orgに投稿したいと思っていましたが、以前はあまり投稿していないので、写真を投稿(またはリンク)できませんでした。私は自分のカルマを上げなければならない。 – user1214513

答えて

0

私はグリッドで校正中に何かすることができると思った。私は再投影誤差を計算することができます。ですからまず、変換行列を得るために解いてください。次に、変換行列を使用して3次元で点を変換し、その後、projectPointsを使用して2次元で投影します。次に、オリジナルの2D点と投影された2D点の間の距離をチェックします。これは、品質のために使用することができます。可能でないオブジェクトは、画像に再投影エラーが100ピクセル以上あることがよくありますが、オブジェクトのサイズが20ピクセル未満です。だから私はちょうど25ピクセルのカットオフを行い、それは正常に動作するようです。

私はより多くの変換が可能であることに注意してください。私の元の画像では、私の現在のカメラでは2つが可能ではないかもしれませんが、それでも多くの偽物を拒否しました。

他に誰も考えられない人がいる場合は、これを回答として受け入れます。ここで

は、私が使用する方法についていくつかのコードです:

//This is the object in 3D 
    double width = 50.0; //Object is 50mm wide 
    double height = 30.0; //Object is 30mm tall 
    cv::Mat object_points(4,3,CV_64FC1); 
    object_points.at<double>(0,0)=0; 
    object_points.at<double>(0,1)=0; 
    object_points.at<double>(0,2)=0; 
    object_points.at<double>(1,0)=width; 
    object_points.at<double>(1,1)=0; 
    object_points.at<double>(1,2)=0; 
    object_points.at<double>(2,0)=width; 
    object_points.at<double>(2,1)=height; 
    object_points.at<double>(2,2)=0; 
    object_points.at<double>(3,0)=0; 
    object_points.at<double>(3,1)=height; 
    object_points.at<double>(3,2)=0; 

    //Check all rectangles for error 
    cv::Mat image_points(4,2,CV_64FC1); 
    for (size_t i = 0; i < rectangles_to_test.size(); i++) { 
    // Get rectangle points 
    for (size_t c = 0; c < 4; ++c) { 
     image_points.at<double>(c,0) = (rectangles_to_test[i].points[c].x); 
     image_points.at<double>(c,1) = (rectangles_to_test[i].points[c].y); 
    } 

    // Calculate transformation matrix 
    cv::Mat rvec, tvec; 
    cv::solvePnP(object_points, image_points, M1, D1, rvec, tvec); 

    cv::Mat rotation; 
    Matrix4<double> transform; 
    transform.init_identity(); 
    cv::Rodrigues(rvec, rotation); 

    for(size_t row = 0; row < 3; ++row) { 
     for(size_t col = 0; col < 3; ++col) { 
     transform.set(row, col, rotation.at<double>(row, col)); 
     } 
     transform.set(row, 3, tvec.at<double>(row, 0)); 
    } 

    // Calculate projection 
    std::vector<cv::Point3f> p3(4); 
    std::vector<cv::Point2f> p2; 
    Vector4<double> p = transform * Vector4<double>(0, 0, 0, 1); 
    p3[0] = cv::Point3f((float)p.x, (float)p.y, (float)p.z); 
    p = transform * Vector4<double>(width, 0, 0, 1); 
    p3[1] = cv::Point3f((float)p.x, (float)p.y, (float)p.z); 
    p = transform * Vector4<double>(width, height, 0, 1); 
    p3[2] = cv::Point3f((float)p.x, (float)p.y, (float)p.z); 
    p = transform * Vector4<double>(0, height, 0, 1); 
    p3[3] = cv::Point3f((float)p.x, (float)p.y, (float)p.z); 

    cv::projectPoints(p3, cv::Mat::zeros(1, 3, CV_64FC1), cv::Mat::zeros(1, 3, CV_64FC1), M1, D1, p2); 

    // Calculate reprojection error 
    rectangles_to_test[i].reprojection_error = 0.0; 
    for (size_t c = 0; c < 4; ++c) { 
     double dx = p2[c].x - rectangles_to_test[i].points[c].x; 
     double dy = p2[c].y - rectangles_to_test[i].points[c].y; 
     rectangles_to_test[i].reprojection_error += std::sqrt(dx*dx + dy*dy); 
    } 
    if (rectangles_to_test[i].reprojection_error > reprojection_error_threshold) { 
     //rectangle is no good 
    } 
    } 
関連する問題