Merge pull request #1263 from abidrahmank:pyCLAHE_24
[profile/ivi/opencv.git] / samples / ocl / tvl1_optical_flow.cpp
1 #include <iostream>
2 #include <vector>
3 #include <iomanip>
4
5 #include "opencv2/highgui/highgui.hpp"
6 #include "opencv2/ocl/ocl.hpp"
7 #include "opencv2/video/video.hpp"
8
9 using namespace std;
10 using namespace cv;
11 using namespace cv::ocl;
12
13 typedef unsigned char uchar;
14 #define LOOP_NUM 10
15 int64 work_begin = 0;
16 int64 work_end = 0;
17
18 static void workBegin()
19 {
20     work_begin = getTickCount();
21 }
22 static void workEnd()
23 {
24     work_end += (getTickCount() - work_begin);
25 }
26 static double getTime()
27 {
28     return work_end * 1000. / getTickFrequency();
29 }
30
31 template <typename T> inline T clamp (T x, T a, T b)
32 {
33     return ((x) > (a) ? ((x) < (b) ? (x) : (b)) : (a));
34 }
35
36 template <typename T> inline T mapValue(T x, T a, T b, T c, T d)
37 {
38     x = clamp(x, a, b);
39     return c + (d - c) * (x - a) / (b - a);
40 }
41
42 static void getFlowField(const Mat& u, const Mat& v, Mat& flowField)
43 {
44     float maxDisplacement = 1.0f;
45
46     for (int i = 0; i < u.rows; ++i)
47     {
48         const float* ptr_u = u.ptr<float>(i);
49         const float* ptr_v = v.ptr<float>(i);
50
51         for (int j = 0; j < u.cols; ++j)
52         {
53             float d = max(fabsf(ptr_u[j]), fabsf(ptr_v[j]));
54
55             if (d > maxDisplacement)
56                 maxDisplacement = d;
57         }
58     }
59
60     flowField.create(u.size(), CV_8UC4);
61
62     for (int i = 0; i < flowField.rows; ++i)
63     {
64         const float* ptr_u = u.ptr<float>(i);
65         const float* ptr_v = v.ptr<float>(i);
66
67
68         Vec4b* row = flowField.ptr<Vec4b>(i);
69
70         for (int j = 0; j < flowField.cols; ++j)
71         {
72             row[j][0] = 0;
73             row[j][1] = static_cast<unsigned char> (mapValue (-ptr_v[j], -maxDisplacement, maxDisplacement, 0.0f, 255.0f));
74             row[j][2] = static_cast<unsigned char> (mapValue ( ptr_u[j], -maxDisplacement, maxDisplacement, 0.0f, 255.0f));
75             row[j][3] = 255;
76         }
77     }
78 }
79
80
81 int main(int argc, const char* argv[])
82 {
83     static std::vector<Info> ocl_info;
84     ocl::getDevice(ocl_info);
85     //if you want to use undefault device, set it here
86     setDevice(ocl_info[0]);
87
88     //set this to save kernel compile time from second time you run
89     ocl::setBinpath("./");
90     const char* keys =
91         "{ h   | help       | false           | print help message }"
92         "{ l   | left       |                 | specify left image }"
93         "{ r   | right      |                 | specify right image }"
94         "{ o   | output     | tvl1_output.jpg | specify output save path }"
95         "{ c   | camera     | 0               | enable camera capturing }"
96         "{ s   | use_cpu    | false           | use cpu or gpu to process the image }"
97         "{ v   | video      |                 | use video as input }";
98
99     CommandLineParser cmd(argc, argv, keys);
100
101     if (cmd.get<bool>("help"))
102     {
103         cout << "Usage: pyrlk_optical_flow [options]" << endl;
104         cout << "Avaible options:" << endl;
105         cmd.printParams();
106         return 0;
107     }
108
109     bool defaultPicturesFail = false;
110     string fname0 = cmd.get<string>("l");
111     string fname1 = cmd.get<string>("r");
112     string vdofile = cmd.get<string>("v");
113     string outpath = cmd.get<string>("o");
114     bool useCPU = cmd.get<bool>("s");
115     bool useCamera = cmd.get<bool>("c");
116     int inputName = cmd.get<int>("c");
117
118     Mat frame0 = imread(fname0, cv::IMREAD_GRAYSCALE);
119     Mat frame1 = imread(fname1, cv::IMREAD_GRAYSCALE);
120     cv::Ptr<cv::DenseOpticalFlow> alg = cv::createOptFlow_DualTVL1();
121     cv::ocl::OpticalFlowDual_TVL1_OCL d_alg;
122
123
124     Mat flow, show_flow;
125     Mat flow_vec[2];
126     if (frame0.empty() || frame1.empty())
127     {
128         useCamera = true;
129         defaultPicturesFail = true;
130         CvCapture* capture = 0;
131         capture = cvCaptureFromCAM( inputName );
132         if (!capture)
133         {
134             cout << "Can't load input images" << endl;
135             return -1;
136         }
137     }
138
139
140     if (useCamera)
141     {
142         CvCapture* capture = 0;
143         Mat frame, frameCopy;
144         Mat frame0Gray, frame1Gray;
145         Mat ptr0, ptr1;
146
147         if(vdofile == "")
148             capture = cvCaptureFromCAM( inputName );
149         else
150             capture = cvCreateFileCapture(vdofile.c_str());
151
152         int c = inputName ;
153         if(!capture)
154         {
155             if(vdofile == "")
156                 cout << "Capture from CAM " << c << " didn't work" << endl;
157             else
158                 cout << "Capture from file " << vdofile << " failed" <<endl;
159             if (defaultPicturesFail)
160             {
161                 return -1;
162             }
163             goto nocamera;
164         }
165
166         cout << "In capture ..." << endl;
167         for(int i = 0;; i++)
168         {
169             frame = cvQueryFrame( capture );
170             if( frame.empty() )
171                 break;
172
173             if (i == 0)
174             {
175                 frame.copyTo( frame0 );
176                 cvtColor(frame0, frame0Gray, COLOR_BGR2GRAY);
177             }
178             else
179             {
180                 if (i%2 == 1)
181                 {
182                     frame.copyTo(frame1);
183                     cvtColor(frame1, frame1Gray, COLOR_BGR2GRAY);
184                     ptr0 = frame0Gray;
185                     ptr1 = frame1Gray;
186                 }
187                 else
188                 {
189                     frame.copyTo(frame0);
190                     cvtColor(frame0, frame0Gray, COLOR_BGR2GRAY);
191                     ptr0 = frame1Gray;
192                     ptr1 = frame0Gray;
193                 }
194
195                 if (useCPU)
196                 {
197                     alg->calc(ptr0, ptr1, flow);
198                     split(flow, flow_vec);
199                 }
200                 else
201                 {
202                     oclMat d_flowx, d_flowy;
203                     d_alg(oclMat(ptr0), oclMat(ptr1), d_flowx, d_flowy);
204                     d_flowx.download(flow_vec[0]);
205                     d_flowy.download(flow_vec[1]);
206                 }
207                 if (i%2 == 1)
208                     frame1.copyTo(frameCopy);
209                 else
210                     frame0.copyTo(frameCopy);
211                 getFlowField(flow_vec[0], flow_vec[1], show_flow);
212                 imshow("PyrLK [Sparse]", show_flow);
213             }
214
215             if( waitKey( 10 ) >= 0 )
216                 goto _cleanup_;
217         }
218
219         waitKey(0);
220
221 _cleanup_:
222         cvReleaseCapture( &capture );
223     }
224     else
225     {
226 nocamera:
227         oclMat d_flowx, d_flowy;
228         for(int i = 0; i <= LOOP_NUM; i ++)
229         {
230             cout << "loop" << i << endl;
231
232             if (i > 0) workBegin();
233             if (useCPU)
234             {
235                 alg->calc(frame0, frame1, flow);
236                 split(flow, flow_vec);
237             }
238             else
239             {
240                 d_alg(oclMat(frame0), oclMat(frame1), d_flowx, d_flowy);
241                 d_flowx.download(flow_vec[0]);
242                 d_flowy.download(flow_vec[1]);
243             }
244             if (i > 0 && i <= LOOP_NUM)
245                 workEnd();
246
247             if (i == LOOP_NUM)
248             {
249                 if (useCPU)
250                     cout << "average CPU time (noCamera) : ";
251                 else
252                     cout << "average GPU time (noCamera) : ";
253                 cout << getTime() / LOOP_NUM << " ms" << endl;
254
255                 getFlowField(flow_vec[0], flow_vec[1], show_flow);
256                 imshow("PyrLK [Sparse]", show_flow);
257                 imwrite(outpath, show_flow);
258             }
259         }
260     }
261
262     waitKey();
263
264     return 0;
265 }