Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/samples/tapi/pyrlk_optical_flow.cpp
16337 views
1
#include <iostream>
2
#include <vector>
3
#include <iomanip>
4
5
#include "opencv2/core/utility.hpp"
6
#include "opencv2/imgcodecs.hpp"
7
#include "opencv2/videoio.hpp"
8
#include "opencv2/highgui.hpp"
9
#include "opencv2/core/ocl.hpp"
10
#include "opencv2/video/video.hpp"
11
12
using namespace std;
13
using namespace cv;
14
15
typedef unsigned char uchar;
16
#define LOOP_NUM 10
17
int64 work_begin = 0;
18
int64 work_end = 0;
19
20
static void workBegin()
21
{
22
work_begin = getTickCount();
23
}
24
static void workEnd()
25
{
26
work_end += (getTickCount() - work_begin);
27
}
28
static double getTime()
29
{
30
return work_end * 1000. / getTickFrequency();
31
}
32
33
static void drawArrows(UMat& _frame, const vector<Point2f>& prevPts, const vector<Point2f>& nextPts, const vector<uchar>& status,
34
Scalar line_color = Scalar(0, 0, 255))
35
{
36
Mat frame = _frame.getMat(ACCESS_WRITE);
37
for (size_t i = 0; i < prevPts.size(); ++i)
38
{
39
if (status[i])
40
{
41
int line_thickness = 1;
42
43
Point p = prevPts[i];
44
Point q = nextPts[i];
45
46
double angle = atan2((double) p.y - q.y, (double) p.x - q.x);
47
48
double hypotenuse = sqrt( (double)(p.y - q.y)*(p.y - q.y) + (double)(p.x - q.x)*(p.x - q.x) );
49
50
if (hypotenuse < 1.0)
51
continue;
52
53
// Here we lengthen the arrow by a factor of three.
54
q.x = (int) (p.x - 3 * hypotenuse * cos(angle));
55
q.y = (int) (p.y - 3 * hypotenuse * sin(angle));
56
57
// Now we draw the main line of the arrow.
58
line(frame, p, q, line_color, line_thickness);
59
60
// Now draw the tips of the arrow. I do some scaling so that the
61
// tips look proportional to the main line of the arrow.
62
63
p.x = (int) (q.x + 9 * cos(angle + CV_PI / 4));
64
p.y = (int) (q.y + 9 * sin(angle + CV_PI / 4));
65
line(frame, p, q, line_color, line_thickness);
66
67
p.x = (int) (q.x + 9 * cos(angle - CV_PI / 4));
68
p.y = (int) (q.y + 9 * sin(angle - CV_PI / 4));
69
line(frame, p, q, line_color, line_thickness);
70
}
71
}
72
}
73
74
75
int main(int argc, const char* argv[])
76
{
77
const char* keys =
78
"{ h help | | print help message }"
79
"{ l left | | specify left image }"
80
"{ r right | | specify right image }"
81
"{ c camera | 0 | enable camera capturing }"
82
"{ v video | | use video as input }"
83
"{ o output | pyrlk_output.jpg| specify output save path when input is images }"
84
"{ points | 1000 | specify points count [GoodFeatureToTrack] }"
85
"{ min_dist | 0 | specify minimal distance between points [GoodFeatureToTrack] }"
86
"{ m cpu_mode | false | run without OpenCL }";
87
88
CommandLineParser cmd(argc, argv, keys);
89
90
if (cmd.has("help"))
91
{
92
cout << "Usage: pyrlk_optical_flow [options]" << endl;
93
cout << "Available options:" << endl;
94
cmd.printMessage();
95
return EXIT_SUCCESS;
96
}
97
98
bool defaultPicturesFail = true;
99
string fname0 = cmd.get<string>("left");
100
string fname1 = cmd.get<string>("right");
101
string vdofile = cmd.get<string>("video");
102
string outfile = cmd.get<string>("output");
103
int points = cmd.get<int>("points");
104
double minDist = cmd.get<double>("min_dist");
105
int inputName = cmd.get<int>("c");
106
107
UMat frame0;
108
imread(fname0, cv::IMREAD_GRAYSCALE).copyTo(frame0);
109
UMat frame1;
110
imread(fname1, cv::IMREAD_GRAYSCALE).copyTo(frame1);
111
112
vector<cv::Point2f> pts(points);
113
vector<cv::Point2f> nextPts(points);
114
vector<unsigned char> status(points);
115
vector<float> err;
116
117
cout << "Points count : " << points << endl << endl;
118
119
if (frame0.empty() || frame1.empty())
120
{
121
VideoCapture capture;
122
UMat frame, frameCopy;
123
UMat frame0Gray, frame1Gray;
124
UMat ptr0, ptr1;
125
126
if(vdofile.empty())
127
capture.open( inputName );
128
else
129
capture.open(vdofile.c_str());
130
131
int c = inputName ;
132
if(!capture.isOpened())
133
{
134
if(vdofile.empty())
135
cout << "Capture from CAM " << c << " didn't work" << endl;
136
else
137
cout << "Capture from file " << vdofile << " failed" <<endl;
138
if (defaultPicturesFail)
139
return EXIT_FAILURE;
140
goto nocamera;
141
}
142
143
cout << "In capture ..." << endl;
144
for(int i = 0;; i++)
145
{
146
if( !capture.read(frame) )
147
break;
148
149
if (i == 0)
150
{
151
frame.copyTo( frame0 );
152
cvtColor(frame0, frame0Gray, COLOR_BGR2GRAY);
153
}
154
else
155
{
156
if (i%2 == 1)
157
{
158
frame.copyTo(frame1);
159
cvtColor(frame1, frame1Gray, COLOR_BGR2GRAY);
160
ptr0 = frame0Gray;
161
ptr1 = frame1Gray;
162
}
163
else
164
{
165
frame.copyTo(frame0);
166
cvtColor(frame0, frame0Gray, COLOR_BGR2GRAY);
167
ptr0 = frame1Gray;
168
ptr1 = frame0Gray;
169
}
170
171
172
pts.clear();
173
goodFeaturesToTrack(ptr0, pts, points, 0.01, 0.0);
174
if(pts.size() == 0)
175
continue;
176
calcOpticalFlowPyrLK(ptr0, ptr1, pts, nextPts, status, err);
177
178
if (i%2 == 1)
179
frame1.copyTo(frameCopy);
180
else
181
frame0.copyTo(frameCopy);
182
drawArrows(frameCopy, pts, nextPts, status, Scalar(255, 0, 0));
183
imshow("PyrLK [Sparse]", frameCopy);
184
}
185
char key = (char)waitKey(10);
186
187
if (key == 27)
188
break;
189
else if (key == 'm' || key == 'M')
190
{
191
ocl::setUseOpenCL(!cv::ocl::useOpenCL());
192
cout << "Switched to " << (ocl::useOpenCL() ? "OpenCL" : "CPU") << " mode\n";
193
}
194
}
195
capture.release();
196
}
197
else
198
{
199
nocamera:
200
if (cmd.has("cpu_mode"))
201
{
202
ocl::setUseOpenCL(false);
203
std::cout << "OpenCL was disabled" << std::endl;
204
}
205
for(int i = 0; i <= LOOP_NUM; i ++)
206
{
207
cout << "loop" << i << endl;
208
if (i > 0) workBegin();
209
210
goodFeaturesToTrack(frame0, pts, points, 0.01, minDist);
211
calcOpticalFlowPyrLK(frame0, frame1, pts, nextPts, status, err);
212
213
if (i > 0 && i <= LOOP_NUM)
214
workEnd();
215
216
if (i == LOOP_NUM)
217
{
218
cout << "average time (noCamera) : ";
219
220
cout << getTime() / LOOP_NUM << " ms" << endl;
221
222
drawArrows(frame0, pts, nextPts, status, Scalar(255, 0, 0));
223
imshow("PyrLK [Sparse]", frame0);
224
imwrite(outfile, frame0);
225
}
226
}
227
}
228
229
waitKey();
230
231
return EXIT_SUCCESS;
232
}
233
234