Subversion Repositories seema-scanner

Rev

Rev 120 | Rev 139 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 120 Rev 121
Line 6... Line 6...
6
 
6
 
7
#include <stdio.h>
7
#include <stdio.h>
8
 
8
 
9
namespace cvtools{
9
namespace cvtools{
10
 
10
 
11
// Create a mask for feature matching which disallows matches not satisfying the epipolar constraint.
11
// Removes matches not satisfying the epipolar constraint.
12
// Works like cv::windowedMatchingMask in conjunction with cv::BFMatcher::match().
-
 
13
// F is the fundamental matrix.
12
// F is the fundamental matrix.
14
// maxD is the maximum point to line distance permissible.
13
// Works like cv::correctMatches(), except it removes matches with an error distance greater than maxD.
15
cv::Mat epipolarMatchingMask(const cv::vector<cv::KeyPoint> &keypoints1, const cv::vector<cv::KeyPoint> &keypoints2, cv::Matx33f F, float maxD){
14
void removeIncorrectMatches(const cv::Mat F, const std::vector<cv::Point2f> &q0, const std::vector<cv::Point2f> &q1, const float maxD,
-
 
15
                                std::vector<cv::Point2f> q0Correct, std::vector<cv::Point2f> q1Correct){
16
 
16
 
17
    if(keypoints1.empty() || keypoints2.empty())
17
    int n0 = (int)q0.size(), n1 = (int)q1.size();
18
        return cv::Mat();
18
    q0Correct.reserve(n0);
19
 
-
 
20
    int n1 = (int)keypoints1.size(), n2 = (int)keypoints2.size();
-
 
21
    cv::Mat mask(n1, n2, CV_8UC1);
19
    q1Correct.reserve(n1);
22
 
20
 
23
    // Point to line distance
21
    // Point to line distance
24
//    for( int i = 0; i < n1; i++ ){
22
//    for( int i = 0; i < n1; i++ ){
25
//        cv::Vec3f p1 = cv::Vec3f(keypoints1[i].pt.x, keypoints1[i].pt.y, 1.0);
23
//        cv::Vec3f p0 = cv::Vec3f(q0[i].x, q0[i].y, 1.0);
26
//        // Epipolar line defined by p1
24
//        // Epipolar line defined by p0
27
//        cv::Vec3f l = F*p1;
25
//        cv::Vec3f l = F*p0;
28
//        l /= sqrt(l(0)*l(0) + l(1)*l(1));
26
//        l /= sqrt(l(0)*l(0) + l(1)*l(1));
29
//        for( int j = 0; j < n2; j++ ){
27
//        for( int j = 0; j < n2; j++ ){
30
//            cv::Vec3f p2 = cv::Vec3f(keypoints2[j].pt.x, keypoints2[j].pt.y, 1.0);
28
//            cv::Vec3f p1 = cv::Vec3f(q1[i].x, q1[i].y, 1.0);
31
//            // Signed distance to line
29
//            // Signed distance to line
32
//            float d = l.dot(p2);
30
//            float d = l.dot(p1);
-
 
31
//            if(d < maxD){
-
 
32
//                q0Correct.push_back(q0[i]);
33
//            mask.at<uchar>(i, j) = fabs(d) < maxD;
33
//                q1Correct.push_back(q1[i]);
-
 
34
//            }
34
//        }
35
//        }
35
//    }
36
//    }
36
 
37
 
37
    // Symmetric epipolar distance
38
    // Symmetric epipolar distance
38
    std::vector<cv::Point2f> q1, q2;
-
 
39
    cvtools::keypointsToPoints(keypoints1, q1);
-
 
40
    cvtools::keypointsToPoints(keypoints2, q2);
-
 
41
    std::vector<cv::Point3f> l1, l2;
39
    std::vector<cv::Point3f> l0, l1;
42
    cv::computeCorrespondEpilines(q1, 1, F, l1);
40
    cv::computeCorrespondEpilines(q0, 1, F, l0);
43
    cv::computeCorrespondEpilines(q2, 2, F, l2);
41
    cv::computeCorrespondEpilines(q1, 2, F, l1);
44
 
42
 
45
    for( int i = 0; i < n1; i++ ){
43
    for(int i = 0; i < n0; i++){
46
        cv::Vec3f p1 = cv::Vec3f(q1[i].x, q1[i].y, 1.0);
44
        cv::Vec3f p0 = cv::Vec3f(q0[i].x, q0[i].y, 1.0);
47
        for( int j = 0; j < n2; j++ ){
45
        for(int j = 0; j < n1; j++){
48
            cv::Vec3f p2 = cv::Vec3f(q2[j].x, q2[j].y, 1.0);
46
            cv::Vec3f p1 = cv::Vec3f(q1[j].x, q1[j].y, 1.0);
49
            float d12 = l1[i].dot(p2);
47
            float d01 = l0[i].dot(p1);
50
            float d21 = l2[j].dot(p1);
48
            float d10 = l1[j].dot(p0);
51
            float d = d12*d12 + d21*d21;
49
            float d = d01*d01 + d10*d10;
52
            mask.at<uchar>(i, j) = d < maxD;
50
            if(d < maxD){
-
 
51
                q0Correct.push_back(q0[i]);
-
 
52
                q1Correct.push_back(q1[i]);
-
 
53
            }
53
        }
54
        }
54
    }
55
    }
55
 
56
 
56
//    // Sampson Error (H&Z, p. 287) (expensive...)
57
//    // Sampson Error (H&Z, p. 287) (expensive...)
57
//    std::vector<cv::Point2f> q1, q2;
58
//    std::vector<cv::Point3f> p0, p1;
58
//    cvtools::keypointsToPoints(keypoints1, q1);
-
 
59
//    cvtools::keypointsToPoints(keypoints2, q2);
59
//    cv::convertPointsToHomogeneous(q0, p0);
60
//    std::vector<cv::Point3f> p1, p2;
-
 
61
//    cv::convertPointsToHomogeneous(q1, p1);
60
//    cv::convertPointsToHomogeneous(q1, p1);
62
//    cv::convertPointsToHomogeneous(q2, p2);
-
 
63
//    cv::Mat Fp1Mat = cv::Mat(F)*cv::Mat(p1).reshape(1).t();
61
//    cv::Mat Fp0Mat = cv::Mat(F)*cv::Mat(p0).reshape(1).t();
64
//    cv::Mat FTp2Mat = cv::Mat(F.t())*cv::Mat(p2).reshape(1).t();
62
//    cv::Mat FTp1Mat = cv::Mat(F.t())*cv::Mat(p1).reshape(1).t();
65
//    for( int i = 0; i < n1; i++ ){
63
//    for( int i = 0; i < n1; i++ ){
66
//        cv::Vec3f Fp1 = Fp1Mat.col(i);
64
//        cv::Vec3f Fp0 = Fp0Mat.col(i);
67
//        for( int j = 0; j < n2; j++ ){
65
//        for( int j = 0; j < n2; j++ ){
68
//            cv::Vec3f FTp2 = FTp2Mat.col(j);
66
//            cv::Vec3f FTp1 = FTp1Mat.col(j);
69
//            cv::Matx<float,1,1> p2TFp1 = cv::Matx31f(p2[j]).t()*F*cv::Matx31f(p1[i]);
67
//            cv::Matx<float,1,1> p1TFp0 = cv::Matx31f(p1[j]).t()*F*cv::Matx31f(p0[i]);
70
//            float d = p2TFp1(0)*p2TFp1(0) / (Fp1(0)*Fp1(0) + Fp1(1)*Fp1(1) + FTp2(0)*FTp2(0) + FTp2(1)*FTp2(1));
68
//            float d = p1TFp0(0)*p1TFp0(0) / (Fp0(0)*Fp0(0) + Fp0(1)*Fp0(1) + FTp1(0)*FTp1(0) + FTp1(1)*FTp1(1));
71
//            mask.at<uchar>(i, j) = d < maxD;
69
//            if(d < maxD){
-
 
70
//                q0Correct.push_back(q0[i]);
-
 
71
//                q1Correct.push_back(q1[i]);
-
 
72
//            }
72
//        }
73
//        }
73
//    }
74
//    }
74
 
75
 
75
    return mask;
76
    return;
76
}
-
 
77
 
-
 
78
 
-
 
79
// Remove correspondences which have a distance metric above thresh.
-
 
80
void matchingThreshold(const std::vector<cv::DMatch> &matchesIn, std::vector<cv::DMatch> &matchesOut, float thresh){
-
 
81
 
-
 
82
    int nMatches = matchesIn.size();
-
 
83
    matchesOut.clear();
-
 
84
    matchesOut.reserve(nMatches);
-
 
85
 
-
 
86
    for(int i=0; i<nMatches; i++){
-
 
87
        if(matchesIn[i].distance < thresh)
-
 
88
            matchesOut.push_back(matchesIn[i]);
-
 
89
    }
-
 
90
 
-
 
91
}
77
}
92
 
78
 
93
// Lightly modified OpenCV function which accepts a line width argument
79
// Lightly modified OpenCV function which accepts a line width argument
94
void drawChessboardCorners(cv::InputOutputArray _image, cv::Size patternSize, cv::InputArray _corners, bool patternWasFound, int line_width){
80
void drawChessboardCorners(cv::InputOutputArray _image, cv::Size patternSize, cv::InputArray _corners, bool patternWasFound, int line_width){
95
    cv::Mat corners = _corners.getMat();
81
    cv::Mat corners = _corners.getMat();