6 #include "opencv2/ocl/ocl.hpp"
7 #include "opencv2/highgui/highgui.hpp"
13 bool help_showed = false;
18 static Params read(int argc, char** argv);
23 string method_str() const
29 case CSBP: return "CSBP";
33 enum {BM, BP, CSBP} method;
34 int ndisp; // Max disparity + 1
43 void handleKey(char key);
44 void printParams() const;
46 void workBegin() { work_begin = getTickCount(); }
49 int64 d = getTickCount() - work_begin;
50 double f = getTickFrequency();
57 ss << "(" << p.method_str() << ") FPS: " << setiosflags(ios::left)
58 << setprecision(4) << work_fps;
65 Mat left_src, right_src;
67 oclMat d_left, d_right;
70 StereoBeliefPropagation bp;
71 StereoConstantSpaceBP csbp;
77 static void printHelp()
79 cout << "Usage: stereo_match_gpu\n"
80 << "\t--left <left_view> --right <right_view> # must be rectified\n"
81 << "\t--method <stereo_match_method> # BM | BP | CSBP\n"
82 << "\t--ndisp <number> # number of disparity levels\n"
83 << "\t--type <device_type> # cpu | CPU | gpu | GPU\n";
87 int main(int argc, char** argv)
97 Params args = Params::read(argc, argv);
101 int flags[2] = { CVCL_DEVICE_TYPE_GPU, CVCL_DEVICE_TYPE_CPU };
104 if(getDevice(info, flags[args.type]) == 0)
106 throw runtime_error("Error: Did not find a valid OpenCL device!");
108 cout << "Device name:" << info[0].DeviceName[0] << endl;
113 catch (const exception& e)
115 cout << "error: " << e.what() << endl;
129 Params Params::read(int argc, char** argv)
133 for (int i = 1; i < argc; i++)
135 if (string(argv[i]) == "--left") p.left = argv[++i];
136 else if (string(argv[i]) == "--right") p.right = argv[++i];
137 else if (string(argv[i]) == "--method")
139 if (string(argv[i + 1]) == "BM") p.method = BM;
140 else if (string(argv[i + 1]) == "BP") p.method = BP;
141 else if (string(argv[i + 1]) == "CSBP") p.method = CSBP;
142 else throw runtime_error("unknown stereo match method: " + string(argv[i + 1]));
145 else if (string(argv[i]) == "--ndisp") p.ndisp = atoi(argv[++i]);
146 else if (string(argv[i]) == "--type")
149 if (t == "cpu" || t == "CPU")
153 else if (t == "gpu" || t == "GPU")
157 else throw runtime_error("unknown device type: " + t);
159 else if (string(argv[i]) == "--help") printHelp();
160 else throw runtime_error("unknown key: " + string(argv[i]));
167 App::App(const Params& params)
168 : p(params), running(false)
170 cout << "stereo_match_ocl sample\n";
171 cout << "\nControls:\n"
173 << "\tp - print current parameters\n"
174 << "\tg - convert source images into gray\n"
175 << "\tm - change stereo match method\n"
176 << "\ts - change Sobel prefiltering flag (for BM only)\n"
177 << "\t1/q - increase/decrease maximum disparity\n"
178 << "\t2/w - increase/decrease window size (for BM only)\n"
179 << "\t3/e - increase/decrease iteration count (for BP and CSBP only)\n"
180 << "\t4/r - increase/decrease level count (for BP and CSBP only)\n";
187 left_src = imread(p.left);
188 right_src = imread(p.right);
189 if (left_src.empty()) throw runtime_error("can't open file \"" + p.left + "\"");
190 if (right_src.empty()) throw runtime_error("can't open file \"" + p.right + "\"");
192 cvtColor(left_src, left, CV_BGR2GRAY);
193 cvtColor(right_src, right, CV_BGR2GRAY);
196 d_right.upload(right);
198 imshow("left", left);
199 imshow("right", right);
201 // Set common parameters
204 csbp.ndisp = p.ndisp;
213 // Prepare disparity map of specified type
220 if (d_left.channels() > 1 || d_right.channels() > 1)
222 cout << "BM doesn't support color images\n";
223 cvtColor(left_src, left, CV_BGR2GRAY);
224 cvtColor(right_src, right, CV_BGR2GRAY);
225 cout << "image_channels: " << left.channels() << endl;
227 d_right.upload(right);
228 imshow("left", left);
229 imshow("right", right);
231 bm(d_left, d_right, d_disp);
234 bp(d_left, d_right, d_disp);
237 csbp(d_left, d_right, d_disp);
244 d_disp.download(disp);
245 if (p.method != Params::BM)
247 disp.convertTo(disp, 0);
249 putText(disp, text(), Point(5, 25), FONT_HERSHEY_SIMPLEX, 1.0, Scalar::all(255));
250 imshow("disparity", disp);
252 handleKey((char)waitKey(3));
257 void App::printParams() const
259 cout << "--- Parameters ---\n";
260 cout << "image_size: (" << left.cols << ", " << left.rows << ")\n";
261 cout << "image_channels: " << left.channels() << endl;
262 cout << "method: " << p.method_str() << endl
263 << "ndisp: " << p.ndisp << endl;
267 cout << "win_size: " << bm.winSize << endl;
268 cout << "prefilter_sobel: " << bm.preset << endl;
271 cout << "iter_count: " << bp.iters << endl;
272 cout << "level_count: " << bp.levels << endl;
275 cout << "iter_count: " << csbp.iters << endl;
276 cout << "level_count: " << csbp.levels << endl;
283 void App::handleKey(char key)
294 if (left.channels() == 1 && p.method != Params::BM)
301 cvtColor(left_src, left, CV_BGR2GRAY);
302 cvtColor(right_src, right, CV_BGR2GRAY);
305 d_right.upload(right);
306 cout << "image_channels: " << left.channels() << endl;
307 imshow("left", left);
308 imshow("right", right);
314 p.method = Params::BP;
317 p.method = Params::CSBP;
320 p.method = Params::BM;
323 cout << "method: " << p.method_str() << endl;
326 if (p.method == Params::BM)
330 case StereoBM_OCL::BASIC_PRESET:
331 bm.preset = StereoBM_OCL::PREFILTER_XSOBEL;
333 case StereoBM_OCL::PREFILTER_XSOBEL:
334 bm.preset = StereoBM_OCL::BASIC_PRESET;
337 cout << "prefilter_sobel: " << bm.preset << endl;
341 p.ndisp = p.ndisp == 1 ? 8 : p.ndisp + 8;
342 cout << "ndisp: " << p.ndisp << endl;
345 csbp.ndisp = p.ndisp;
348 p.ndisp = max(p.ndisp - 8, 1);
349 cout << "ndisp: " << p.ndisp << endl;
352 csbp.ndisp = p.ndisp;
355 if (p.method == Params::BM)
357 bm.winSize = min(bm.winSize + 1, 51);
358 cout << "win_size: " << bm.winSize << endl;
362 if (p.method == Params::BM)
364 bm.winSize = max(bm.winSize - 1, 2);
365 cout << "win_size: " << bm.winSize << endl;
369 if (p.method == Params::BP)
372 cout << "iter_count: " << bp.iters << endl;
374 else if (p.method == Params::CSBP)
377 cout << "iter_count: " << csbp.iters << endl;
381 if (p.method == Params::BP)
383 bp.iters = max(bp.iters - 1, 1);
384 cout << "iter_count: " << bp.iters << endl;
386 else if (p.method == Params::CSBP)
388 csbp.iters = max(csbp.iters - 1, 1);
389 cout << "iter_count: " << csbp.iters << endl;
393 if (p.method == Params::BP)
396 cout << "level_count: " << bp.levels << endl;
398 else if (p.method == Params::CSBP)
401 cout << "level_count: " << csbp.levels << endl;
405 if (p.method == Params::BP)
407 bp.levels = max(bp.levels - 1, 1);
408 cout << "level_count: " << bp.levels << endl;
410 else if (p.method == Params::CSBP)
412 csbp.levels = max(csbp.levels - 1, 1);
413 cout << "level_count: " << csbp.levels << endl;