1 #include "perf_precomp.hpp"
2
3 using namespace std;
4 using namespace cv;
5 using namespace perf;
6 using std::tr1::make_tuple;
7 using std::tr1::get;
8
9 typedef tr1::tuple<std::string, int, int, tr1::tuple<int,int>, int> Path_Idx_Cn_NPoints_WSize_t;
10 typedef TestBaseWithParam<Path_Idx_Cn_NPoints_WSize_t> Path_Idx_Cn_NPoints_WSize;
11
FormTrackingPointsArray(vector<Point2f> & points,int width,int height,int nPointsX,int nPointsY)12 void FormTrackingPointsArray(vector<Point2f>& points, int width, int height, int nPointsX, int nPointsY)
13 {
14 int stepX = width / nPointsX;
15 int stepY = height / nPointsY;
16 if (stepX < 1 || stepY < 1) FAIL() << "Specified points number is too big";
17
18 points.clear();
19 points.reserve(nPointsX * nPointsY);
20
21 for( int x = stepX / 2; x < width; x += stepX )
22 {
23 for( int y = stepY / 2; y < height; y += stepY )
24 {
25 Point2f pt(static_cast<float>(x), static_cast<float>(y));
26 points.push_back(pt);
27 }
28 }
29 }
30
31 PERF_TEST_P(Path_Idx_Cn_NPoints_WSize, OpticalFlowPyrLK_full, testing::Combine(
32 testing::Values<std::string>("cv/optflow/frames/VGA_%02d.png", "cv/optflow/frames/720p_%02d.png"),
33 testing::Range(1, 3),
34 testing::Values(1, 3, 4),
35 testing::Values(make_tuple(9, 9), make_tuple(15, 15)),
36 testing::Values(7, 11)
37 )
38 )
39 {
40 string filename1 = getDataPath(cv::format(get<0>(GetParam()).c_str(), get<1>(GetParam())));
41 string filename2 = getDataPath(cv::format(get<0>(GetParam()).c_str(), get<1>(GetParam()) + 1));
42 Mat img1 = imread(filename1);
43 Mat img2 = imread(filename2);
44 if (img1.empty()) FAIL() << "Unable to load source image " << filename1;
45 if (img2.empty()) FAIL() << "Unable to load source image " << filename2;
46
47 int cn = get<2>(GetParam());
48 int nPointsX = min(get<0>(get<3>(GetParam())), img1.cols);
49 int nPointsY = min(get<1>(get<3>(GetParam())), img1.rows);
50 int winSize = get<4>(GetParam());
51
52 int maxLevel = 2;
53 TermCriteria criteria(TermCriteria::COUNT|TermCriteria::EPS, 7, 0.001);
54 int flags = 0;
55 double minEigThreshold = 1e-4;
56
57 Mat frame1, frame2;
58 switch(cn)
59 {
60 case 1:
61 cvtColor(img1, frame1, COLOR_BGR2GRAY, cn);
62 cvtColor(img2, frame2, COLOR_BGR2GRAY, cn);
63 break;
64 case 3:
65 frame1 = img1;
66 frame2 = img2;
67 break;
68 case 4:
69 cvtColor(img1, frame1, COLOR_BGR2BGRA, cn);
70 cvtColor(img2, frame2, COLOR_BGR2BGRA, cn);
71 break;
72 default:
73 FAIL() << "Unexpected number of channels: " << cn;
74 }
75
76 vector<Point2f> inPoints;
77 vector<Point2f> outPoints;
78 vector<uchar> status;
79 vector<float> err;
80
81 FormTrackingPointsArray(inPoints, frame1.cols, frame1.rows, nPointsX, nPointsY);
82 outPoints.resize(inPoints.size());
83 status.resize(inPoints.size());
84 err.resize(inPoints.size());
85
86 declare.in(frame1, frame2, inPoints).out(outPoints);
87
88 TEST_CYCLE_N(30)
89 {
90 calcOpticalFlowPyrLK(frame1, frame2, inPoints, outPoints, status, err,
91 Size(winSize, winSize), maxLevel, criteria,
92 flags, minEigThreshold);
93 }
94
95 SANITY_CHECK(outPoints, 0.3);
96 SANITY_CHECK(status);
97 SANITY_CHECK(err, 2);
98 }
99
100 typedef tr1::tuple<std::string, int, int, tr1::tuple<int,int>, int, bool> Path_Idx_Cn_NPoints_WSize_Deriv_t;
101 typedef TestBaseWithParam<Path_Idx_Cn_NPoints_WSize_Deriv_t> Path_Idx_Cn_NPoints_WSize_Deriv;
102
103 PERF_TEST_P(Path_Idx_Cn_NPoints_WSize_Deriv, OpticalFlowPyrLK_self, testing::Combine(
104 testing::Values<std::string>("cv/optflow/frames/VGA_%02d.png", "cv/optflow/frames/720p_%02d.png"),
105 testing::Range(1, 3),
106 testing::Values(1, 3, 4),
107 testing::Values(make_tuple(9, 9), make_tuple(15, 15)),
108 testing::Values(7, 11),
109 testing::Bool()
110 )
111 )
112 {
113 string filename1 = getDataPath(cv::format(get<0>(GetParam()).c_str(), get<1>(GetParam())));
114 string filename2 = getDataPath(cv::format(get<0>(GetParam()).c_str(), get<1>(GetParam()) + 1));
115 Mat img1 = imread(filename1);
116 Mat img2 = imread(filename2);
117 if (img1.empty()) FAIL() << "Unable to load source image " << filename1;
118 if (img2.empty()) FAIL() << "Unable to load source image " << filename2;
119
120 int cn = get<2>(GetParam());
121 int nPointsX = min(get<0>(get<3>(GetParam())), img1.cols);
122 int nPointsY = min(get<1>(get<3>(GetParam())), img1.rows);
123 int winSize = get<4>(GetParam());
124 bool withDerivatives = get<5>(GetParam());
125
126 int maxLevel = 2;
127 TermCriteria criteria(TermCriteria::COUNT|TermCriteria::EPS, 7, 0.001);
128 int flags = 0;
129 double minEigThreshold = 1e-4;
130
131 Mat frame1, frame2;
132 switch(cn)
133 {
134 case 1:
135 cvtColor(img1, frame1, COLOR_BGR2GRAY, cn);
136 cvtColor(img2, frame2, COLOR_BGR2GRAY, cn);
137 break;
138 case 3:
139 frame1 = img1;
140 frame2 = img2;
141 break;
142 case 4:
143 cvtColor(img1, frame1, COLOR_BGR2BGRA, cn);
144 cvtColor(img2, frame2, COLOR_BGR2BGRA, cn);
145 break;
146 default:
147 FAIL() << "Unexpected number of channels: " << cn;
148 }
149
150 vector<Point2f> inPoints;
151 vector<Point2f> outPoints;
152 vector<uchar> status;
153 vector<float> err;
154
155 FormTrackingPointsArray(inPoints, frame1.cols, frame1.rows, nPointsX, nPointsY);
156 outPoints.resize(inPoints.size());
157 status.resize(inPoints.size());
158 err.resize(inPoints.size());
159
160 std::vector<Mat> pyramid1, pyramid2;
161
162 maxLevel = buildOpticalFlowPyramid(frame1, pyramid1, Size(winSize, winSize), maxLevel, withDerivatives);
163 maxLevel = buildOpticalFlowPyramid(frame2, pyramid2, Size(winSize, winSize), maxLevel, withDerivatives);
164
165 declare.in(pyramid1, pyramid2, inPoints).out(outPoints);
166 declare.time(400);
167
168 int runs = 3;
TEST_CYCLE_MULTIRUN(runs)169 TEST_CYCLE_MULTIRUN(runs)
170 {
171 calcOpticalFlowPyrLK(pyramid1, pyramid2, inPoints, outPoints, status, err,
172 Size(winSize, winSize), maxLevel, criteria,
173 flags, minEigThreshold);
174 }
175
176 SANITY_CHECK(outPoints, 0.3);
177 SANITY_CHECK(status);
178 SANITY_CHECK(err, 2);
179 }
180
181 CV_ENUM(PyrBorderMode, BORDER_DEFAULT, BORDER_TRANSPARENT)
182 typedef tr1::tuple<std::string, int, bool, PyrBorderMode, bool> Path_Win_Deriv_Border_Reuse_t;
183 typedef TestBaseWithParam<Path_Win_Deriv_Border_Reuse_t> Path_Win_Deriv_Border_Reuse;
184
185 PERF_TEST_P(Path_Win_Deriv_Border_Reuse, OpticalFlowPyrLK_pyr, testing::Combine(
186 testing::Values<std::string>("cv/optflow/frames/720p_01.png"),
187 testing::Values(7, 11),
188 testing::Bool(),
189 PyrBorderMode::all(),
190 testing::Bool()
191 )
192 )
193 {
194 string filename = getDataPath(get<0>(GetParam()));
195 Mat img = imread(filename);
196 Size winSize(get<1>(GetParam()), get<1>(GetParam()));
197 bool withDerivatives = get<2>(GetParam());
198 int derivBorder = get<3>(GetParam());
199 int pyrBorder = derivBorder;
200 if(derivBorder != BORDER_TRANSPARENT)
201 {
202 derivBorder = BORDER_CONSTANT;
203 pyrBorder = BORDER_REFLECT_101;
204 }
205 bool tryReuseInputImage = get<4>(GetParam());
206 std::vector<Mat> pyramid;
207
208 img.adjustROI(winSize.height, winSize.height, winSize.width, winSize.width);
209
210 int maxLevel = buildOpticalFlowPyramid(img, pyramid, winSize, 1000, withDerivatives, BORDER_CONSTANT, BORDER_CONSTANT, tryReuseInputImage);
211
212 declare.in(img).out(pyramid);
213
214
TEST_CYCLE()215 TEST_CYCLE()
216 {
217 buildOpticalFlowPyramid(img, pyramid, winSize, maxLevel, withDerivatives, pyrBorder, derivBorder, tryReuseInputImage);
218 }
219
220 SANITY_CHECK(pyramid);
221 }
222