Robust Local Optical Flow Libary Documentation  V 1.2
 All Classes Files Functions Variables Enumerations Enumerator Macros Pages
RLOFTools.hpp
Go to the documentation of this file.
1 /******************************************************************************
2  * COPYRIGHT: *
3  * *
4  * This file is the property of the author and Communication Systems Group, *
5  * Technische Universität Berlin. All rights reserved. *
6  * *
7  * It may not be publicly disclosed, distributed, used, copied or modified *
8  * without prior written authorization by a representative of *
9  * Communication Systems Group, Technische Universität Berlin or the author. *
10  * Any modified version of this document needs to contain this header. *
11  ******************************************************************************/
12 
13 /******************************************************************************
14  * THERMS IF USAGE: *
15  * PERSONAL, NON-COMMERCIAL or ACADEMIC USAGE: *
16  * You are free to use this software for whatever you like. If you use this *
17  * algorithm for a scientific publication, please cite the one of the *
18  * following paper: *
19  * *
20  * @INPROCEEDINGS{ICIPSenst2014, *
21  * AUTHOR = {Tobias Senst and Thilo Borgmann and Ivo Keller and Thomas *
22  * Sikora}, *
23  * TITLE = {Cross based Robust Local Optical Flow}, *
24  * BOOKTITLE = {21th IEEE International Conference on Image Processing}, *
25  * YEAR = {2014}, *
26  * MONTH = okt, *
27  * PAGES = {1967--1971}, *
28  * ADDRESS = {Paris, France}, *
29  * } *
30  * *
31  * @INPROCEEDINGS{ICIPSenst2013, *
32  * AUTHOR = {Tobias Senst and Jonas Geistert and Ivo Keller and Thomas *
33  * Sikora}, *
34  * TITLE = {Robust Local Optical Flow Estimation using Bilinear Equations for *
35  * Sparse Motion Estimation}, *
36  * BOOKTITLE = {20th IEEE International Conference on Image Processing}, *
37  * YEAR = {2013}, *
38  * MONTH = sep, *
39  * PAGES = {2499--2503}, *
40  * ADDRESS = {Melbourne, Australia}, *
41  * DOI = {10.1109/ICIP.2013.6738515}, *
42  * } *
43  * *
44  * @ARTICLE{TCSVTSenst2012, *
45  * AUTHOR = {Tobias Senst and Volker Eiselein and Thomas Sikora}, *
46  * TITLE = {Robust Local Optical Flow for Feature Tracking}, *
47  * JOURNAL = {IEEE Transactions on Circuits and Systems for Video Technology},*
48  * YEAR = {2012}, *
49  * MONTH = sep, *
50  * PAGES = {1377--1387}, *
51  * VOLUME = {22}, *
52  * NUMBER = {9}, *
53  * DOI = {10.1109/TCSVT.2012.2202070} *
54  * } *
55  * *
56  * @INPROCEEDINGS{WACVSenst2011, *
57  * AUTHOR = {Tobias Senst and Volker Eiselein and Rubén Heras Evangelio and *
58  * Thomas Sikora}, *
59  * TITLE = {Robust Modified L2 Local Optical Flow Estimation and Feature *
60  * Tracking}, *
61  * BOOKTITLE = {IEEE Workshop on Motion and Video Computing}, *
62  * YEAR = {2011}, *
63  * MONTH = jan, *
64  * EDITOR = {Eric Mortensen}, *
65  * PAGES = {685--690}, *
66  * ADDRESS = {Kona, USA}, *
67  * DOI = {10.1109/WACV.2011.5711571}, *
68  * } *
69  * *
70  * COMMERCIAL USAGE: *
71  * It is not allowed to use any content of this package for any commercial *
72  * use or any advertisement for upcoming commercial products. If you want to*
73  * use any content for such a purpose please contact: *
74  * Prof. Dr.-Ing. Thomas Sikora <sikora@nue.tu-berlin.de>. *
75  ******************************************************************************/
76 
77 /******************************************************************************
78  * WARRANTIES: *
79  * *
80  * Software provided by Technische Universität Berlin with this document is *
81  * provided "AS IS" and any express of implied warranties including, but *
82  * not limited to, the implied warranties of merchantability and fitness *
83  * for a particular purpose are disclaimed. *
84  * In no event shall the author or contributors be liable for any direct, *
85  * indirect, incidental, special, exemplary, or consequential damages *
86  * (including, but not limited to, procurement of substitute goods or *
87  * services, loss of use, data, or profits or business interruption) caused in*
88  * any way out of the use of this software, even if advised of the possibility*
89  * of such damage. *
90  ******************************************************************************/
101 #pragma once
102 #ifndef _RLOFTOOLS_HPP_
103 #define _RLOFTOOLS_HPP_
104 #include <OpticalFlow/RLOFFactory.h>
106 #include <iostream>
107 #include <opencv\highgui.h>
116 static void denseMotionField(const cv::Mat & img1,
117  const cv::Mat & img2,
118  IFeatureTracker * tracker,
119  FeatureTrackerContext & param,
120  cv::Mat & U,
121  cv::Mat & V)
122 {
123  std::vector<CRPoint> ptList1(img1.size().area());
124  std::vector<CRPoint> ptList2(img1.size().area());
125  // initialise pointlist
126  int n = 0;
127  for(int r = 0 ; r < img1.rows; r++)
128  {
129  for(int c = 0 ; c < img1.cols; c++, n++)
130  {
131  ptList1[n] = CRPoint(static_cast<float>(c),static_cast<float>(r));
132  }
133  }
134 
135  tracker->run(img1.ptr<uchar>(),
136  img1.step1(),
137  img2.ptr<uchar>(),
138  img2.step1(),
139  img1.rows,
140  img1.cols,
141  ptList1,
142  ptList2,
143  &param);
144 
145  // initialise the motion field matrices
146  if( U.size() != img1.size() || U.type() != CV_32FC1)
147  {
148  U.release();
149  U.create(img1.size(), CV_32FC1);
150  U.setTo(0);
151  }
152  if( V.size() != img1.size() || V.type() != CV_32FC1)
153  {
154  V.release();
155  V.create(img1.size(), CV_32FC1);
156  V.setTo(0);
157  }
158  //
159  for(unsigned int n = 0; n < ptList1.size(); n++)
160  {
161  cv::Point pt(static_cast<int>(ptList1[n].x), static_cast<int>(ptList1[n].y));
162  U.at<float>(pt) = ptList2[n].x - ptList1[n].x;
163  V.at<float>(pt) = ptList2[n].y - ptList1[n].y;
164  }
165 }
166 
167 
168 
170 
180 void FlowToRGB(const cv::Mat & dx,
181  const cv::Mat & dy,
182  cv::Mat & rgbFlow,
183  const float & max_size = -1,
184  bool use_value = false,
185  cv::Mat & sat = cv::Mat())
186 {
187  if(dx.empty() ||dy.empty()) return;
188 
189  if( dx.depth() != CV_32F && dy.depth() != CV_32F)
190  throw(std::exception("FlowToRGB: error dx/dy wrong data type"));
191  if( dx.size() != dy.size())
192  throw(std::exception("FlowToRGB: error dx/dy must have equal size"));
193  if ( !sat.empty() )
194  if( sat.type() != CV_8UC1)
195  throw(std::exception("FlowToRGB: error sat must have type CV_8UC1"));
196 
197 
198  const float grad2deg = (float)(90/3.141);
199  //const float norm_val = (float)(255.f / max_val);
200  double satMaxVal, minVal;
201  if(!sat.empty())
202  {
203  cv::minMaxLoc(sat, &minVal, &satMaxVal);
204  satMaxVal = 255.0/satMaxVal;
205  }
206 
207  cv::Mat pol(dx.size(), CV_32FC2);
208 
209  float mean_val = 0, min_val = 1000, max_val = 0;
210  float _dx, _dy, angle, value;
211 
212  for(int r = 0; r < dx.rows; r++)
213  {
214  for(int c = 0; c < dy.cols; c++)
215  {
216  _dx = dx.at<float>(r,c);
217  _dy = dy.at<float>(r,c);
218  value =sqrt(_dx * _dx + _dy * _dy);
219  if ( value == 0)
220  angle = 0;
221  else if( _dy < 0)
222  angle = 180.f - acos(_dx/ value)* grad2deg;
223  else
224  angle = acos(_dx/ value)* grad2deg;
225 
226  mean_val +=value;
227  max_val = MAX(max_val, value);
228  min_val = MIN(min_val, value);
229  pol.at<cv::Point2f>(r,c) = cv::Point2f(angle,value);
230  }
231  }
232  mean_val /= dy.size().area();
233  float scale = max_val - min_val;
234  float shift = -min_val;//-mean_val + scale;
235  scale = 255.f/scale;
236  if( max_size > 0)
237  {
238  scale = 255.f/max_size;
239  shift = 0;
240  }
241 
242  //calculate the angle, motion value
243  cv::Mat hsv(dx.rows, dx.cols, CV_8UC3);
244  uchar * ptrHSV = hsv.ptr<uchar>();
245  int idx_val = (use_value) ? 2:1;
246  int idx_sat = (use_value) ? 1:2;
247 
248 
249  for(int r = 0; r < dx.rows; r++, ptrHSV += hsv.step1())
250  {
251  uchar * _ptrHSV = ptrHSV;
252  for(int c = 0; c < dy.cols; c++, _ptrHSV+=3)
253  {
254  cv::Point2f vpol = pol.at<cv::Point2f>(r,c);
255 
256  _ptrHSV[0] = cv::saturate_cast<uchar>(vpol.x);
257  _ptrHSV[idx_val] = cv::saturate_cast<uchar>( (vpol.y + shift) * scale);
258  if( sat.empty())
259  _ptrHSV[idx_sat] = 255;
260  else
261  _ptrHSV[idx_sat] = 255- cv::saturate_cast<uchar>(sat.at<uchar>(r,c) * satMaxVal);
262 
263  }
264  }
265 
266  //std::vector<cv::Mat> vec;
267  //cv::split(hsv, vec);
268  //cv::equalizeHist(vec[idx_val],vec[idx_val]);
269  //cv::merge(vec,hsv);
270  cv::Mat rgbFlow32F;
271  cv::cvtColor(hsv, rgbFlow32F, CV_HSV2BGR);
272  rgbFlow32F.convertTo(rgbFlow, CV_8UC3);
273 }
276 void test1()
277 {
278  std::string filename1("../Doc/ErnstReuter1.png");
279  std::string filename2("../Doc/ErnstReuter2.png");
280  cv::Mat img1;
281  cv::Mat img2;
282  cv::Mat U,V;
283  img1 = cv::imread(filename1);
284  img2 = cv::imread(filename2);
285 
286  CPLKParameter PLKParameter; // PLK OpenCV implementation refer to CPU_PLK / GPU_PLK
287  CRobustFlowParameter RLOFParameter; // RLOF see <a href="index.html#Senst2012">Senst et al. 2012</a> refer to CPU_RLOF / GPU_RLOF
288 
289  CPLKParameter BEPLKParameter; // BEPLK see <a href="index.html#Senst2013">Senst et al. 2013</a> refer to CPU_BEPLK
291  CRobustFlowParameter BERLOFParameter; // BERLOF see <a href="index.html#Senst2013">Senst et al. 2013</a> refer to CPU_BERLOF / GPU_BERLOF
292  BERLOFParameter.solverType(CLocalFlowParameter::ITER_BE);
293 
294  CCrossPLKParameter CB_BEPLKParameter; // CB_BEPLK see /cite{ICIPSenst2014} refer to CPU_CROSS_BEPLK
295  CB_BEPLKParameter.solverType(CLocalFlowParameter::ITER_BE);
296  CCrossRobustFlowParameter CB_BERLOFParameter; // CB_BERLOF see /cite{ICIPSenst2014} refer to CPU_CROSS_BERLOF
297  CB_BERLOFParameter.solverType(CLocalFlowParameter::ITER_BE);
298  CCrossPLKParameter CB_PLKParameter; // CB_PLK see /cite{ICIPSenst2014} refer to CPU_CROSS_PLK
299  CCrossRobustFlowParameter CB_RLOFParameter; // CB_RLOF see /cite{ICIPSenst2014} refer to CPU_CROSS_RLOF
300 
301  CLocalFlowParameter * parameters[8] = {&PLKParameter,&RLOFParameter, &BEPLKParameter, &BERLOFParameter, &CB_BEPLKParameter, &CB_BERLOFParameter, &CB_PLKParameter, &CB_RLOFParameter};
302  std::string methodName[8] = {"PLK", "RLOF", "BEPLK", "BERLOF", "CB_BEPLK", "CB_BERLOF", "CB_PLK", "CB_RLOF"};
303  std::cout << "--- RLOFLib Accuracy Test ---" << std::endl;
304  FILE * file;
305 
306 #ifdef _WIN32 || _WIN64
307 #if _WIN64
308  fopen_s(&file, "../Doc/RLOFTest64.dat", "r");
309 #else
310  fopen_s(&file, "../Doc/RLOFTest32.dat", "r");
311 #endif
312 #endif
313 
314 
315  for(int n = 0; n < 8; n++)
316  {
317  IFeatureTracker * tracker = RLOFFactory::createFTInstance(parameters[n]);
318  denseMotionField(img1, img2, tracker, *parameters[n], U, V);
319  delete tracker;
320  float R = 0;
321  for( int r = 0; r < U.rows; r++)
322  for( int c = 0; c < U.cols; c++)
323  {
324  float u, v, b;
325  fscanf(file, "%f %f %f ",&u, &v, &b);
326  float mu = U.at<float>(r,c);
327  float mv = V.at<float>(r,c);
328  if( sqrt((u - mu) * (u - mu) + (v - mv) * (v - mv)) > 0.01 && b != 0)
329  R++;
330 
331  }
332  R /= static_cast<float>(U.size().area());
333  if( R < 0.001 )
334  std::cout << methodName[n] << "\t\tTEST OK!" << std::endl;
335  else
336  std::cout << methodName[n] << "\t\tATTENTION R = "<< R << std::endl;
337  }
338  fclose(file);
339 }
342 void test0()
343 {
344  CPLKParameter PLKParameter; // PLK OpenCV implementation refer to CPU_PLK / GPU_PLK
345  CRobustFlowParameter RLOFParameter; // RLOF see <a href="index.html#Senst2012">Senst et al. 2012</a> refer to CPU_RLOF / GPU_RLOF
346 
347  CPLKParameter BEPLKParameter; // BEPLK see <a href="index.html#Senst2013">Senst et al. 2013</a> refer to CPU_BEPLK
349  CRobustFlowParameter BERLOFParameter; // BERLOF see <a href="index.html#Senst2013">Senst et al. 2013</a> refer to CPU_BERLOF / GPU_BERLOF
350  BERLOFParameter.solverType(CLocalFlowParameter::ITER_BE);
351 
352  CCrossPLKParameter CB_BEPLKParameter; // CB_BEPLK see /cite{ICIPSenst2014} refer to CPU_CROSS_BEPLK
353  CB_BEPLKParameter.solverType(CLocalFlowParameter::ITER_BE);
354  CCrossRobustFlowParameter CB_BERLOFParameter; // CB_BERLOF see /cite{ICIPSenst2014} refer to CPU_CROSS_BERLOF
355  CB_BERLOFParameter.solverType(CLocalFlowParameter::ITER_BE);
356  CCrossPLKParameter CB_PLKParameter; // CB_PLK see /cite{ICIPSenst2014} refer to CPU_CROSS_PLK
357  CCrossRobustFlowParameter CB_RLOFParameter; // CB_RLOF see /cite{ICIPSenst2014} refer to CPU_CROSS_RLOF
358 
359  CLocalFlowParameter * parameters[8] = {&PLKParameter,&RLOFParameter, &BEPLKParameter, &BERLOFParameter, &CB_BEPLKParameter, &CB_BERLOFParameter, &CB_PLKParameter, &CB_RLOFParameter};
360  std::string methodName[8] = {"PLK", "RLOF", "BEPLK", "BERLOF", "CB_BEPLK", "CB_BERLOF", "CB_PLK", "CB_RLOF"};
361 
362  std::cout << "--- RLOFLib Initialisation Test ---" << std::endl;
363  for(int n = 0; n < 8; n++)
364  {
365  try
366  {
367  IFeatureTracker * tracker = RLOFFactory::createFTInstance(parameters[n]);
368  delete tracker;
369  std::cout << methodName[n] << "\t\tTEST OK!" << std::endl;
370  }
371  catch(std::exception & e)
372  {
373  std::cout << methodName[n] << "\t\tTEST FAILED!" << std::endl << e.what() <<std::endl;
374  }
375  }
376 }
377 
378 #endif
Feature tracker parameter base class This class is the base class for all parameter classes in that l...
RLOF parameter.
void solverType(SolverType val)
RLOF parameter class The Robust Local Optical Flow parameter class contains additional parameters use...
void FlowToRGB(const cv::Mat &dx, const cv::Mat &dy, cv::Mat &rgbFlow, const float &max_size=-1, bool use_value=false, cv::Mat &sat=cv::Mat())
Convert motion field to RGB colormap.
Definition: RLOFTools.hpp:180
Pyramidal Lucas Kanade parameter class The Pyramidal Lucas Kanade parameter class. Please use a instance of this class to run the PLK version. The parameter class is associated to PLK.
RLOF factory.
void test0()
Definition: RLOFTools.hpp:342
static IFeatureTracker * createFTInstance(RLOFType type=CPU_BEPLK)
RLOF Interface.
PLK/RLOF parameter base class The parameter base class provides basic interfaces to set up the algori...
void test1()
Definition: RLOFTools.hpp:276
Cross based Pyramidal Lucas Kanade parameter class The cross based Pyramidal Lucas Kanade parameter c...
Wrapper cv::Point2f.
Definition: cvwrapper.hpp:87
static void denseMotionField(const cv::Mat &img1, const cv::Mat &img2, IFeatureTracker *tracker, FeatureTrackerContext &param, cv::Mat &U, cv::Mat &V)
Definition: RLOFTools.hpp:116
virtual void run(const uchar *imgPtr1, unsigned int step1, const uchar *imgPtr2, unsigned int step2, unsigned int nRows, unsigned int nCols, std::vector< CRPoint > &prevPoints, std::vector< CRPoint > &currPoints, const FeatureTrackerContext *context)
Cross based RLOF parameter class The cross based Robust Local Optical Flow parameter class contains i...