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