From 7452eef6e972cc787d858bca52913fd9d377c693 Mon Sep 17 00:00:00 2001 From: Chuanbo Weng Date: Mon, 20 Oct 2014 11:50:46 +0800 Subject: [PATCH] Correctly enable OpenCL mode in tapi's hog example. For current OpenCV-CL architecture, if the data buffer allocated in UMat are cpu buffer(not ocl buffer) under cpu mode, and then pass this UMat to an OpenCL kernel as an argument, the OpenCL path will fail and fallback to cpu mode. Take HOGDescriptor::oclSvmDetector as an example: ocl::setUseOpenCL(false); //data allocated in hog.oclSvmDetector will be cpu buffer hog.setSVMDetector(HOGDescriptor::getDaimlerPeopleDetector()); ocl::setUseOpenCL(true); //We enabled OpenCL, but hog.oclSvmDetector are cpu buffer, //so it will fail in the function ocl_classify_hists //when reach to this line //idx = k.set(idx, ocl::KernelArg::PtrReadOnly(detector)); hog.detectMultiScale(img, found, hit_threshold, win_stride, Size(0, 0), scale, gr_threshold); Similar problems heppen on img_aux and img. So we should re-define or re-set these UMat when do mode switch (CPU -> OpenCL) in order to make their data be allocated by ocl and then OpenCL path will succeed. Signed-off-by: Chuanbo Weng --- samples/tapi/hog.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/samples/tapi/hog.cpp b/samples/tapi/hog.cpp index 389e1e5..62d7aa4 100644 --- a/samples/tapi/hog.cpp +++ b/samples/tapi/hog.cpp @@ -44,6 +44,8 @@ private: //Args args; bool running; bool make_gray; + bool use_ocl; + bool ocl_switch; double scale; double resize_scale; int win_width; @@ -134,6 +136,9 @@ App::App(CommandLineParser& cmd) gamma_corr = true; write_once = false; + use_ocl = ocl::useOpenCL(); + ocl_switch = true; + cout << "Group threshold: " << gr_threshold << endl; cout << "Levels number: " << nlevels << endl; cout << "Win width: " << win_width << endl; @@ -155,7 +160,6 @@ void App::run() HOGDescriptor hog(win_size, Size(16, 16), Size(8, 8), Size(8, 8), 9, 1, -1, HOGDescriptor::L2Hys, 0.2, gamma_corr, cv::HOGDescriptor::DEFAULT_NLEVELS); - hog.setSVMDetector( HOGDescriptor::getDaimlerPeopleDetector() ); while (running) { @@ -187,13 +191,17 @@ void App::run() throw runtime_error(string("can't open image file: " + img_source)); } - UMat img_aux, img; Mat img_to_show; // Iterate over all frames while (running && !frame.empty()) { workBegin(); + if(ocl_switch){ + hog.setSVMDetector( HOGDescriptor::getDaimlerPeopleDetector() ); + ocl_switch = false; + } + UMat img_aux, img; // Change format of the image if (make_gray) cvtColor(frame, img_aux, COLOR_BGR2GRAY ); @@ -213,8 +221,12 @@ void App::run() // Perform HOG classification hogWorkBegin(); - hog.detectMultiScale(img.getMat(ACCESS_READ), found, hit_threshold, win_stride, - Size(0, 0), scale, gr_threshold); + if(use_ocl) + hog.detectMultiScale(img, found, hit_threshold, win_stride, + Size(0, 0), scale, gr_threshold); + else + hog.detectMultiScale(img.getMat(ACCESS_READ), found, hit_threshold, win_stride, + Size(0, 0), scale, gr_threshold); hogWorkEnd(); @@ -225,7 +237,7 @@ void App::run() rectangle(img_to_show, r.tl(), r.br(), Scalar(0, 255, 0), 3); } - putText(img_to_show, "Mode: CPU", Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2); + putText(img_to_show, use_ocl ? "Mode: OpenCL" : "Mode: CPU", Point(5, 25), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2); putText(img_to_show, "FPS (HOG only): " + hogWorkFps(), Point(5, 65), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2); putText(img_to_show, "FPS (total): " + workFps(), Point(5, 105), FONT_HERSHEY_SIMPLEX, 1., Scalar(255, 100, 0), 2); imshow("opencv_hog", img_to_show); @@ -272,7 +284,9 @@ void App::handleKey(char key) case 'm': case 'M': ocl::setUseOpenCL(!cv::ocl::useOpenCL()); - cout << "Switched to " << (ocl::useOpenCL() ? "OpenCL enabled" : "CPU") << " mode\n"; + ocl_switch = true; + use_ocl = ocl::useOpenCL(); + cout << "Switched to " << (use_ocl ? "OpenCL enabled" : "CPU") << " mode\n"; break; case 'g': case 'G': -- 2.7.4