Skip to content

Commit 958b8db

Browse files
authored
Merge pull request #55 from oreillymedia/xfeatures2d
Chap16 xfeatures2d
2 parents 5522217 + 7d40ccf commit 958b8db

File tree

4 files changed

+310
-92
lines changed

4 files changed

+310
-92
lines changed

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ add_executable( example_15-04 example_15-04.cpp )
6969
add_executable( example_15-05 example_15-05.cpp )
7070
add_executable( example_15-BackgroundSubtractor example_15-BackgroundSubtractor.cpp )
7171
add_executable( example_16-01 example_16-01.cpp )
72+
add_executable( example_16-02 example_16-02.cpp )
7273
add_executable( example_17-01 example_17-01.cpp )
7374
add_executable( example_17-02 example_17-02.cpp )
7475
add_executable( example_18-01 example_18-01.cpp )
@@ -146,6 +147,7 @@ target_link_libraries( example_15-04 ${OpenCV_LIBS} )
146147
target_link_libraries( example_15-05 ${OpenCV_LIBS} )
147148
target_link_libraries( example_15-BackgroundSubtractor ${OpenCV_LIBS} )
148149
target_link_libraries( example_16-01 ${OpenCV_LIBS} )
150+
target_link_libraries( example_16-02 ${OpenCV_LIBS} )
149151
target_link_libraries( example_17-01 ${OpenCV_LIBS} )
150152
target_link_libraries( example_17-02 ${OpenCV_LIBS} )
151153
target_link_libraries( example_18-01 ${OpenCV_LIBS} )

example_16-01.cpp

Lines changed: 88 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
// Pyramid L-K optical flow example
1+
// Example 16-1. Pyramid L-K optical flow
22
//
3-
#include <opencv2/opencv.hpp>
43
#include <iostream>
5-
6-
using namespace std;
4+
#include <vector>
5+
#include <opencv2/opencv.hpp>
76

87
static const int MAX_CORNERS = 1000;
8+
using std::cout;
9+
using std::endl;
10+
using std::vector;
11+
912

1013
void help( char** argv ) {
1114
cout << "\nExample 16-1: Pyramid L-K optical flow example.\n" << endl;
@@ -15,90 +18,90 @@ void help( char** argv ) {
1518
}
1619

1720
int main(int argc, char** argv) {
21+
if (argc != 3) {
22+
help(argv);
23+
exit(-1);
24+
}
25+
// Initialize, load two images from the file system, and
26+
// allocate the images and other structures we will need for
27+
// results.
28+
//
29+
cv::Mat imgA = cv::imread(argv[1], CV_LOAD_IMAGE_GRAYSCALE);
30+
cv::Mat imgB = cv::imread(argv[2], CV_LOAD_IMAGE_GRAYSCALE);
31+
cv::Size img_sz = imgA.size();
32+
int win_size = 10;
33+
cv::Mat imgC = cv::imread(argv[2], CV_LOAD_IMAGE_UNCHANGED);
34+
// The first thing we need to do is get the features
35+
// we want to track.
36+
//
37+
vector< cv::Point2f > cornersA, cornersB;
38+
const int MAX_CORNERS = 500;
39+
cv::goodFeaturesToTrack(
40+
imgA, // Image to track
41+
cornersA, // Vector of detected corners (output)
42+
MAX_CORNERS, // Keep up to this many corners
43+
0.01, // Quality level (percent of maximum)
44+
5, // Min distance between corners
45+
cv::noArray(), // Mask
46+
3, // Block size
47+
false, // true: Harris, false: Shi-Tomasi
48+
0.04 // method specific parameter
49+
);
1850

19-
if( argc != 3 ) { help( argv ); exit( -1 ); }
20-
21-
// Initialize, load two images from the file system, and
22-
// allocate the images and other structures we will need for
23-
// results.
24-
//
25-
cv::Mat imgA = cv::imread( argv[1], CV_LOAD_IMAGE_GRAYSCALE );
26-
cv::Mat imgB = cv::imread( argv[2], CV_LOAD_IMAGE_GRAYSCALE );
27-
cv::Size img_sz = imgA.size();
28-
29-
int win_size = 10;
30-
cv::Mat imgC = cv::imread( argv[2], CV_LOAD_IMAGE_UNCHANGED );
31-
32-
// The first thing we need to do is get the features
33-
// we want to track.
34-
//
35-
vector< cv::Point2f > cornersA, cornersB;
36-
const int MAX_CORNERS = 500;
37-
cv::goodFeaturesToTrack(
38-
imgA, // Image to track
39-
cornersA, // Vector of detected corners (output)
40-
MAX_CORNERS, // Keep up to this many corners
41-
0.01, // Quality level (percent of maximum)
42-
5, // Min distance between corners
43-
cv::noArray(), // Mask
44-
3, // Block size
45-
false, // true: Harris, false: Shi-Tomasi
46-
0.04 // method specific parameter
47-
);
48-
49-
cv::cornerSubPix(
50-
imgA, // Input image
51-
cornersA, // Vector of corners (input and output)
52-
cv::Size(win_size, win_size), // Half side length of search window
53-
cv::Size(-1,-1), // Half side length of dead zone (-1=none)
54-
cv::TermCriteria(
55-
cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS,
56-
20, // Maximum number of iterations
57-
0.03 // Minimum change per iteration
58-
)
59-
);
60-
61-
// Call the Lucas Kanade algorithm
62-
//
63-
vector<uchar> features_found;
64-
cv::calcOpticalFlowPyrLK(
65-
imgA, // Previous image
66-
imgB, // Next image
67-
cornersA, // Previous set of corners (from imgA)
68-
cornersB, // Next set of corners (from imgB)
69-
features_found, // Output vector, each is 1 for tracked
70-
cv::noArray(), // Output vector, lists errors (optional)
71-
cv::Size( win_size*2+1, win_size*2+1 ), // Search window size
72-
5, // Maximum pyramid level to construct
73-
cv::TermCriteria(
74-
cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS,
75-
20, // Maximum number of iterations
76-
0.3 // Minimum change per iteration
77-
)
78-
);
51+
cv::cornerSubPix(
52+
imgA, // Input image
53+
cornersA, // Vector of corners (input and output)
54+
cv::Size(win_size, win_size), // Half side length of search window
55+
cv::Size(-1, -1), // Half side length of dead zone (-1=none)
56+
cv::TermCriteria(
57+
cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS,
58+
20, // Maximum number of iterations
59+
0.03 // Minimum change per iteration
60+
)
61+
);
7962

80-
// Now make some image of what we are looking at:
81-
// Note that if you want to track cornersB further, i.e.
82-
// pass them as input to the next calcOpticalFlowPyrLK,
83-
// you would need to "compress" the vector, i.e., exclude points for which
84-
// features_found[i] == false.
85-
for( int i = 0; i < (int)cornersA.size(); i++ ) {
86-
if( !features_found[i] )
87-
continue;
88-
line(
89-
imgC, // Draw onto this image
90-
cornersA[i], // Starting here
91-
cornersB[i], // Ending here
92-
cv::Scalar(0,255,0), // This color
93-
2, // This many pixels wide
94-
cv::LINE_AA // Draw line in this style
63+
// Call the Lucas Kanade algorithm
64+
//
65+
vector<uchar> features_found;
66+
cv::calcOpticalFlowPyrLK(
67+
imgA, // Previous image
68+
imgB, // Next image
69+
cornersA, // Previous set of corners (from imgA)
70+
cornersB, // Next set of corners (from imgB)
71+
features_found, // Output vector, each is 1 for tracked
72+
cv::noArray(), // Output vector, lists errors (optional)
73+
cv::Size(win_size * 2 + 1, win_size * 2 + 1), // Search window size
74+
5, // Maximum pyramid level to construct
75+
cv::TermCriteria(
76+
cv::TermCriteria::MAX_ITER | cv::TermCriteria::EPS,
77+
20, // Maximum number of iterations
78+
0.3 // Minimum change per iteration
79+
)
9580
);
96-
}
9781

98-
cv::imshow( "ImageA", imgA );
99-
cv::imshow( "ImageB", imgB );
100-
cv::imshow( "LK Optical Flow Example", imgC );
101-
cv::waitKey(0);
82+
// Now make some image of what we are looking at:
83+
// Note that if you want to track cornersB further, i.e.
84+
// pass them as input to the next calcOpticalFlowPyrLK,
85+
// you would need to "compress" the vector, i.e., exclude points for which
86+
// features_found[i] == false.
87+
for (int i = 0; i < static_cast<int>(cornersA.size()); ++i) {
88+
if (!features_found[i]) {
89+
continue;
90+
}
91+
line(
92+
imgC, // Draw onto this image
93+
cornersA[i], // Starting here
94+
cornersB[i], // Ending here
95+
cv::Scalar(0, 255, 0), // This color
96+
1, // This many pixels wide
97+
cv::LINE_AA // Draw line in this style
98+
);
99+
}
100+
101+
cv::imshow("ImageA", imgA);
102+
cv::imshow("ImageB", imgB);
103+
cv::imshow("LK Optical Flow Example", imgC);
104+
cv::waitKey(0);
102105

103-
return 0;
106+
return 0;
104107
}

0 commit comments

Comments
 (0)