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