1 // This file is part of OpenCV project.
2 // It is subject to the license terms in the LICENSE file found in the top-level directory
3 // of this distribution and at http://opencv.org/license.html.
4 #ifndef _RLOF_LOCALFLOW_H_
5 #define _RLOF_LOCALFLOW_H_
6 #include <limits>
7 #include <math.h>
8 #include <float.h>
9 #include <stdio.h>
10 #include "opencv2/imgproc.hpp"
11 #include "opencv2/optflow/rlofflow.hpp"
12 //! Fast median estimation method based on @cite Tibshirani2008. This implementation relates to http://www.stat.cmu.edu/~ryantibs/median/
13 using namespace cv;
14 template<typename T>
quickselect(const Mat & inp,int k)15 T quickselect(const Mat & inp, int k)
16 {
17 unsigned long i;
18 unsigned long ir;
19 unsigned long j;
20 unsigned long l;
21 unsigned long mid;
22 Mat values = inp.clone();
23 T a;
24
25 l = 0;
26 ir = MAX(values.rows, values.cols) - 1;
27 while(true)
28 {
29 if (ir <= l + 1)
30 {
31 if (ir == l + 1 && values.at<T>(ir) < values.at<T>(l))
32 std::swap(values.at<T>(l), values.at<T>(ir));
33 return values.at<T>(k);
34 }
35 else
36 {
37 mid = (l + ir) >> 1;
38 std::swap(values.at<T>(mid), values.at<T>(l+1));
39 if (values.at<T>(l) > values.at<T>(ir))
40 std::swap(values.at<T>(l), values.at<T>(ir));
41 if (values.at<T>(l+1) > values.at<T>(ir))
42 std::swap(values.at<T>(l+1), values.at<T>(ir));
43 if (values.at<T>(l) > values.at<T>(l+1))
44 std::swap(values.at<T>(l), values.at<T>(l+1));
45 i = l + 1;
46 j = ir;
47 a = values.at<T>(l+1);
48 while (true)
49 {
50 do
51 {
52 i++;
53 }
54 while (values.at<T>(i) < a);
55 do
56 {
57 j--;
58 }
59 while (values.at<T>(j) > a);
60 if (j < i) break;
61 std::swap(values.at<T>(i), values.at<T>(j));
62 }
63 values.at<T>(l+1) = values.at<T>(j);
64 values.at<T>(j) = a;
65 if (j >= static_cast<unsigned long>(k)) ir = j - 1;
66 if (j <= static_cast<unsigned long>(k)) l = i;
67 }
68 }
69 }
70
71 namespace cv {
72 namespace optflow {
73
74 class CImageBuffer
75 {
76 public:
CImageBuffer()77 CImageBuffer()
78 : m_Overwrite(true)
79 {}
setGrayFromRGB(const cv::Mat & inp)80 void setGrayFromRGB(const cv::Mat & inp)
81 {
82 if(m_Overwrite)
83 cv::cvtColor(inp, m_Image, cv::COLOR_BGR2GRAY);
84 }
setImage(const cv::Mat & inp)85 void setImage(const cv::Mat & inp)
86 {
87 if(m_Overwrite)
88 inp.copyTo(m_Image);
89 }
setBlurFromRGB(const cv::Mat & inp)90 void setBlurFromRGB(const cv::Mat & inp)
91 {
92 if(m_Overwrite)
93 cv::GaussianBlur(inp, m_BlurredImage, cv::Size(7,7), -1);
94 }
95
96 int buildPyramid(cv::Size winSize, int maxLevel, float levelScale[2], bool withBlurredImage = false);
getImage(int level)97 cv::Mat & getImage(int level) {return m_ImagePyramid[level];}
98
99 std::vector<cv::Mat> m_ImagePyramid;
100 cv::Mat m_BlurredImage;
101 cv::Mat m_Image;
102 std::vector<cv::Mat> m_CrossPyramid;
103 int m_maxLevel;
104 bool m_Overwrite;
105 };
106
107 void calcLocalOpticalFlow(
108 const Mat prevImage,
109 const Mat currImage,
110 Ptr<CImageBuffer> prevPyramids[2],
111 Ptr<CImageBuffer> currPyramids[2],
112 const std::vector<Point2f> & prevPoints,
113 std::vector<Point2f> & currPoints,
114 const RLOFOpticalFlowParameter & param);
115
116 }} // namespace
117 #endif
118