1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
8 //
9 //
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
12 //
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
15 //
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
18 //
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
21 //
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
25 //
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 //M*/
41
42 #include "test_precomp.hpp"
43 #include "opencv2/video/tracking_c.h"
44
45 /* ///////////////////// pyrlk_test ///////////////////////// */
46
47 class CV_OptFlowPyrLKTest : public cvtest::BaseTest
48 {
49 public:
50 CV_OptFlowPyrLKTest();
51 protected:
52 void run(int);
53 };
54
55
CV_OptFlowPyrLKTest()56 CV_OptFlowPyrLKTest::CV_OptFlowPyrLKTest() {}
57
run(int)58 void CV_OptFlowPyrLKTest::run( int )
59 {
60 int code = cvtest::TS::OK;
61
62 const double success_error_level = 0.3;
63 const int bad_points_max = 8;
64
65 /* test parameters */
66 double max_err = 0., sum_err = 0;
67 int pt_cmpd = 0;
68 int pt_exceed = 0;
69 int merr_i = 0, merr_j = 0, merr_k = 0;
70 char filename[1000];
71
72 CvPoint2D32f *u = 0, *v = 0, *v2 = 0;
73 CvMat *_u = 0, *_v = 0, *_v2 = 0;
74 char* status = 0;
75
76 IplImage imgI;
77 IplImage imgJ;
78 cv::Mat imgI2, imgJ2;
79
80 int n = 0, i = 0;
81
82 sprintf( filename, "%soptflow/%s", ts->get_data_path().c_str(), "lk_prev.dat" );
83 _u = (CvMat*)cvLoad( filename );
84
85 if( !_u )
86 {
87 ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
88 code = cvtest::TS::FAIL_MISSING_TEST_DATA;
89 goto _exit_;
90 }
91
92 sprintf( filename, "%soptflow/%s", ts->get_data_path().c_str(), "lk_next.dat" );
93 _v = (CvMat*)cvLoad( filename );
94
95 if( !_v )
96 {
97 ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
98 code = cvtest::TS::FAIL_MISSING_TEST_DATA;
99 goto _exit_;
100 }
101
102 if( _u->cols != 2 || CV_MAT_TYPE(_u->type) != CV_32F ||
103 _v->cols != 2 || CV_MAT_TYPE(_v->type) != CV_32F || _v->rows != _u->rows )
104 {
105 ts->printf( cvtest::TS::LOG, "the loaded matrices of points are not valid\n" );
106 code = cvtest::TS::FAIL_MISSING_TEST_DATA;
107 goto _exit_;
108
109 }
110
111 u = (CvPoint2D32f*)_u->data.fl;
112 v = (CvPoint2D32f*)_v->data.fl;
113
114 /* allocate adidtional buffers */
115 _v2 = cvCloneMat( _u );
116 v2 = (CvPoint2D32f*)_v2->data.fl;
117
118 /* read first image */
119 sprintf( filename, "%soptflow/%s", ts->get_data_path().c_str(), "rock_1.bmp" );
120 imgI2 = cv::imread( filename, cv::IMREAD_UNCHANGED );
121 imgI = imgI2;
122
123 if( imgI2.empty() )
124 {
125 ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
126 code = cvtest::TS::FAIL_MISSING_TEST_DATA;
127 goto _exit_;
128 }
129
130 /* read second image */
131 sprintf( filename, "%soptflow/%s", ts->get_data_path().c_str(), "rock_2.bmp" );
132 imgJ2 = cv::imread( filename, cv::IMREAD_UNCHANGED );
133 imgJ = imgJ2;
134
135 if( imgJ2.empty() )
136 {
137 ts->printf( cvtest::TS::LOG, "could not read %s\n", filename );
138 code = cvtest::TS::FAIL_MISSING_TEST_DATA;
139 goto _exit_;
140 }
141
142 n = _u->rows;
143 status = (char*)cvAlloc(n*sizeof(status[0]));
144
145 /* calculate flow */
146 cvCalcOpticalFlowPyrLK( &imgI, &imgJ, 0, 0, u, v2, n, cvSize( 41, 41 ),
147 4, status, 0, cvTermCriteria( CV_TERMCRIT_ITER|
148 CV_TERMCRIT_EPS, 30, 0.01f ), 0 );
149
150 /* compare results */
151 for( i = 0; i < n; i++ )
152 {
153 if( status[i] != 0 )
154 {
155 double err;
156 if( cvIsNaN(v[i].x) )
157 {
158 merr_j++;
159 continue;
160 }
161
162 err = fabs(v2[i].x - v[i].x) + fabs(v2[i].y - v[i].y);
163 if( err > max_err )
164 {
165 max_err = err;
166 merr_i = i;
167 }
168
169 pt_exceed += err > success_error_level;
170 sum_err += err;
171 pt_cmpd++;
172 }
173 else
174 {
175 if( !cvIsNaN( v[i].x ))
176 {
177 merr_i = i;
178 merr_k++;
179 ts->printf( cvtest::TS::LOG, "The algorithm lost the point #%d\n", i );
180 code = cvtest::TS::FAIL_BAD_ACCURACY;
181 goto _exit_;
182 }
183 }
184 }
185
186 if( pt_exceed > bad_points_max )
187 {
188 ts->printf( cvtest::TS::LOG,
189 "The number of poorly tracked points is too big (>=%d)\n", pt_exceed );
190 code = cvtest::TS::FAIL_BAD_ACCURACY;
191 goto _exit_;
192 }
193
194 if( max_err > 1 )
195 {
196 ts->printf( cvtest::TS::LOG, "Maximum tracking error is too big (=%g) at %d\n", max_err, merr_i );
197 code = cvtest::TS::FAIL_BAD_ACCURACY;
198 goto _exit_;
199 }
200
201 _exit_:
202
203 cvFree( &status );
204 cvReleaseMat( &_u );
205 cvReleaseMat( &_v );
206 cvReleaseMat( &_v2 );
207
208 if( code < 0 )
209 ts->set_failed_test_info( code );
210 }
211
212
TEST(Video_OpticalFlowPyrLK,accuracy)213 TEST(Video_OpticalFlowPyrLK, accuracy) { CV_OptFlowPyrLKTest test; test.safe_run(); }
214
TEST(Video_OpticalFlowPyrLK,submat)215 TEST(Video_OpticalFlowPyrLK, submat)
216 {
217 // see bug #2075
218 std::string path = cvtest::TS::ptr()->get_data_path() + "../cv/shared/lena.png";
219
220 cv::Mat lenaImg = cv::imread(path);
221 ASSERT_FALSE(lenaImg.empty());
222
223 cv::Mat wholeImage;
224 cv::resize(lenaImg, wholeImage, cv::Size(1024, 1024));
225
226 cv::Mat img1 = wholeImage(cv::Rect(0, 0, 640, 360)).clone();
227 cv::Mat img2 = wholeImage(cv::Rect(40, 60, 640, 360));
228
229 std::vector<uchar> status;
230 std::vector<float> error;
231 std::vector<cv::Point2f> prev;
232 std::vector<cv::Point2f> next;
233
234 cv::RNG rng(123123);
235
236 for(int i = 0; i < 50; ++i)
237 {
238 int x = rng.uniform(0, 640);
239 int y = rng.uniform(0, 360);
240
241 prev.push_back(cv::Point2f((float)x, (float)y));
242 }
243
244 ASSERT_NO_THROW(cv::calcOpticalFlowPyrLK(img1, img2, prev, next, status, error));
245 }
246