반응형

If we pass the set of points from the target and source images, FindHomography() will find the perspective transformation of that object. Then we can use perspectiveTransform() to find the object. It needs at least four correct points to find the transformation.


<Target>


<Source>



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <opencv2/opencv.hpp>
 
using namespace std;
using namespace cv;
 
int main(int argc, char** argv)
{
    Mat trg = imread("Target.jpg", IMREAD_GRAYSCALE);
    Mat src = imread("Source.jpg", IMREAD_GRAYSCALE);
    
    if (trg.empty() || src.empty()) {
        cerr << "Image load failed!" << endl;
        
        return -1;
    }
 
    Ptr<Feature2D> feature = ORB::create();
    
    vector<KeyPoint> trgKeypoints, srcKeypoints;
    Mat trgDesc, srcDesc;
    feature->detectAndCompute(trg, Mat(), trgKeypoints, trgDesc);
    feature->detectAndCompute(src, Mat(), srcKeypoints, srcDesc);
 
    Ptr<DescriptorMatcher> matcher = BFMatcher::create(NORM_HAMMING);
 
    vector<DMatch> matches;
    matcher->match(trgDesc, srcDesc, matches);
 
    sort(matches.begin(), matches.end());
    vector<DMatch> good_matches(matches.begin(), matches.begin() + 100);
 
    Mat dst;
    drawMatches(trg, trgKeypoints, src, srcKeypoints, good_matches, dst,
        Scalar::all(-1), Scalar(-1), vector<char>(), DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
 
    vector<Point2f> trgPts, srcPts;
    for (size_t i = 0; i < good_matches.size(); i++) {
        trgPts.push_back(trgKeypoints[good_matches[i].queryIdx].pt);
        srcPts.push_back(srcKeypoints[good_matches[i].trainIdx].pt);
    }
 
    Mat H = findHomography(trgPts, srcPts, RANSAC);
    // Finds a perspective transformation between two planes.
 
    vector<Point2f> trgCorners, srcCorners;
    trgCorners.push_back(Point2f(0.f, 0.f));
    trgCorners.push_back(Point2f(trg.cols - 1.f, 0.f));
    trgCorners.push_back(Point2f(trg.cols - 1.f, trg.rows - 1.f));
    trgCorners.push_back(Point2f(0.f, trg.rows - 1.f));
    perspectiveTransform(trgCorners, srcCorners, H);
 
    vector<Point> dstCorners;
    for (Point2f pt : srcCorners) {
        dstCorners.push_back(Point(cvRound(pt.x + trg.cols), cvRound(pt.y)));
        // Move the corners to the right as the width of the Target image.
    }
 
    polylines(dst, dstCorners, true, Scalar(02550), 3, LINE_AA);
 
    imshow("dst", dst);
 
    waitKey();
    
    return 0;
}



Close but not perfect. As mentioned above, it needs correct points to find the transformation.


반응형
Posted by J-sean
: