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 56 CV_OptFlowPyrLKTest::CV_OptFlowPyrLKTest() {} 57 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 213 TEST(Video_OpticalFlowPyrLK, accuracy) { CV_OptFlowPyrLKTest test; test.safe_run(); } 214 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