1 #include <iostream>
2 #include <opencv2/core.hpp>
3 #include <opencv2/imgproc.hpp>
4 #include <opencv2/calib3d.hpp>
5 #include <opencv2/highgui.hpp>
6 
7 using namespace std;
8 using namespace cv;
9 
10 namespace
11 {
12 enum Pattern { CHESSBOARD, CIRCLES_GRID, ASYMMETRIC_CIRCLES_GRID };
13 
randomColor(RNG & rng)14 Scalar randomColor( RNG& rng )
15 {
16   int icolor = (unsigned int) rng;
17   return Scalar( icolor & 255, (icolor >> 8) & 255, (icolor >> 16) & 255 );
18 }
19 
perspectiveCorrection(const string & img1Path,const string & img2Path,const Size & patternSize,RNG & rng)20 void perspectiveCorrection(const string &img1Path, const string &img2Path, const Size &patternSize, RNG &rng)
21 {
22     Mat img1 = imread( samples::findFile(img1Path) );
23     Mat img2 = imread( samples::findFile(img2Path) );
24 
25     //! [find-corners]
26     vector<Point2f> corners1, corners2;
27     bool found1 = findChessboardCorners(img1, patternSize, corners1);
28     bool found2 = findChessboardCorners(img2, patternSize, corners2);
29     //! [find-corners]
30 
31     if (!found1 || !found2)
32     {
33         cout << "Error, cannot find the chessboard corners in both images." << endl;
34         return;
35     }
36 
37     //! [estimate-homography]
38     Mat H = findHomography(corners1, corners2);
39     cout << "H:\n" << H << endl;
40     //! [estimate-homography]
41 
42     //! [warp-chessboard]
43     Mat img1_warp;
44     warpPerspective(img1, img1_warp, H, img1.size());
45     //! [warp-chessboard]
46 
47     Mat img_draw_warp;
48     hconcat(img2, img1_warp, img_draw_warp);
49     imshow("Desired chessboard view / Warped source chessboard view", img_draw_warp);
50 
51     //! [compute-transformed-corners]
52     Mat img_draw_matches;
53     hconcat(img1, img2, img_draw_matches);
54     for (size_t i = 0; i < corners1.size(); i++)
55     {
56         Mat pt1 = (Mat_<double>(3,1) << corners1[i].x, corners1[i].y, 1);
57         Mat pt2 = H * pt1;
58         pt2 /= pt2.at<double>(2);
59 
60         Point end( (int) (img1.cols + pt2.at<double>(0)), (int) pt2.at<double>(1) );
61         line(img_draw_matches, corners1[i], end, randomColor(rng), 2);
62     }
63 
64     imshow("Draw matches", img_draw_matches);
65     waitKey();
66     //! [compute-transformed-corners]
67 }
68 
69 const char* params
70     = "{ help h         |       | print usage }"
71       "{ image1         | left02.jpg | path to the source chessboard image }"
72       "{ image2         | left01.jpg | path to the desired chessboard image }"
73       "{ width bw       | 9     | chessboard width }"
74       "{ height bh      | 6     | chessboard height }";
75 }
76 
main(int argc,char * argv[])77 int main(int argc, char *argv[])
78 {
79     cv::RNG rng( 0xFFFFFFFF );
80     CommandLineParser parser(argc, argv, params);
81 
82     if (parser.has("help"))
83     {
84         parser.about("Code for homography tutorial.\n"
85             "Example 2: perspective correction.\n");
86         parser.printMessage();
87         return 0;
88     }
89 
90     Size patternSize(parser.get<int>("width"), parser.get<int>("height"));
91     perspectiveCorrection(parser.get<String>("image1"),
92                           parser.get<String>("image2"),
93                           patternSize, rng);
94 
95     return 0;
96 }
97