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 <fstream> 44 45 using namespace std; 46 using namespace cv; 47 using namespace cvtest; 48 49 //#define DUMP 50 51 namespace 52 { 53 // first four bytes, should be the same in little endian 54 const float FLO_TAG_FLOAT = 202021.25f; // check for this when READING the file 55 56 #ifdef DUMP 57 // binary file format for flow data specified here: 58 // http://vision.middlebury.edu/flow/data/ 59 void writeOpticalFlowToFile(const Mat_<Point2f>& flow, const string& fileName) 60 { 61 const char FLO_TAG_STRING[] = "PIEH"; // use this when WRITING the file 62 ofstream file(fileName.c_str(), ios_base::binary); 63 64 file << FLO_TAG_STRING; 65 66 file.write((const char*) &flow.cols, sizeof(int)); 67 file.write((const char*) &flow.rows, sizeof(int)); 68 69 for (int i = 0; i < flow.rows; ++i) 70 { 71 for (int j = 0; j < flow.cols; ++j) 72 { 73 const Point2f u = flow(i, j); 74 75 file.write((const char*) &u.x, sizeof(float)); 76 file.write((const char*) &u.y, sizeof(float)); 77 } 78 } 79 } 80 #endif 81 82 // binary file format for flow data specified here: 83 // http://vision.middlebury.edu/flow/data/ 84 void readOpticalFlowFromFile(Mat_<Point2f>& flow, const string& fileName) 85 { 86 ifstream file(fileName.c_str(), ios_base::binary); 87 88 float tag; 89 file.read((char*) &tag, sizeof(float)); 90 CV_Assert( tag == FLO_TAG_FLOAT ); 91 92 Size size; 93 94 file.read((char*) &size.width, sizeof(int)); 95 file.read((char*) &size.height, sizeof(int)); 96 97 flow.create(size); 98 99 for (int i = 0; i < flow.rows; ++i) 100 { 101 for (int j = 0; j < flow.cols; ++j) 102 { 103 Point2f u; 104 105 file.read((char*) &u.x, sizeof(float)); 106 file.read((char*) &u.y, sizeof(float)); 107 108 flow(i, j) = u; 109 } 110 } 111 } 112 113 bool isFlowCorrect(Point2f u) 114 { 115 return !cvIsNaN(u.x) && !cvIsNaN(u.y) && (fabs(u.x) < 1e9) && (fabs(u.y) < 1e9); 116 } 117 118 double calcRMSE(const Mat_<Point2f>& flow1, const Mat_<Point2f>& flow2) 119 { 120 double sum = 0.0; 121 int counter = 0; 122 123 for (int i = 0; i < flow1.rows; ++i) 124 { 125 for (int j = 0; j < flow1.cols; ++j) 126 { 127 const Point2f u1 = flow1(i, j); 128 const Point2f u2 = flow2(i, j); 129 130 if (isFlowCorrect(u1) && isFlowCorrect(u2)) 131 { 132 const Point2f diff = u1 - u2; 133 sum += diff.ddot(diff); 134 ++counter; 135 } 136 } 137 } 138 return sqrt(sum / (1e-9 + counter)); 139 } 140 } 141 142 TEST(Video_calcOpticalFlowDual_TVL1, Regression) 143 { 144 const double MAX_RMSE = 0.03; 145 146 const string frame1_path = TS::ptr()->get_data_path() + "optflow/RubberWhale1.png"; 147 const string frame2_path = TS::ptr()->get_data_path() + "optflow/RubberWhale2.png"; 148 const string gold_flow_path = TS::ptr()->get_data_path() + "optflow/tvl1_flow.flo"; 149 150 Mat frame1 = imread(frame1_path, IMREAD_GRAYSCALE); 151 Mat frame2 = imread(frame2_path, IMREAD_GRAYSCALE); 152 ASSERT_FALSE(frame1.empty()); 153 ASSERT_FALSE(frame2.empty()); 154 155 Mat_<Point2f> flow; 156 Ptr<DenseOpticalFlow> tvl1 = createOptFlow_DualTVL1(); 157 158 tvl1->calc(frame1, frame2, flow); 159 160 #ifdef DUMP 161 writeOpticalFlowToFile(flow, gold_flow_path); 162 #else 163 Mat_<Point2f> gold; 164 readOpticalFlowFromFile(gold, gold_flow_path); 165 166 ASSERT_EQ(gold.rows, flow.rows); 167 ASSERT_EQ(gold.cols, flow.cols); 168 169 double err = calcRMSE(gold, flow); 170 EXPECT_LE(err, MAX_RMSE); 171 #endif 172 } 173