Tuesday, 9 June 2015

OpenCV transparent API (for OpenCL acceleration)

        Opencv 3.0 introduced a concept called Transparent API to easily accelerate computer vision algorithms  on any openCL compatible devise. With the Transparent API no(some time minimal) code change is needed for GPU acceleration.  This results in a code which is "Write Once, build once and run everywhere faster!"

To run a simple openCV code with openCL acceleration we have to,


  • Install the openCL driver.


a.       For NVIDIA

go to the link
chose  Developer Drivers for WinVista and Win7 (257.21) - 64-bit

b.      For intel CPU/ integrated graphics

go to the link
choose appropriate binary based on your model
(in my case HD Graphics 4400)

c.       Restart the PC

  • Create an environment variable to choose the openCL devise from the open-CV program
        Advanced System settings > Environment variables > System variables > New

                  Variable Name:                 OPENCV_OPENCL_DEVICE

                  Variable Value:                 :GPU:1 (in my case it is Nvidia GPU)
                                                               :GPU:0 (intel integrated graphics)

  •  Setup openCV 3 -> compile the program -> Run



Result

Depending on the algorithm the openCL acceleration will be 1x to 70x. I've tried canny edge detection on webcam images with openCL devise set to Nvidia GPU. The below screen shot shows it all. When edges in the image are dense the speed Up will be more.


(*time is in milisecond)




















Code


#include <iostream>
#include <stdio.h>
#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/core/ocl.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"

using namespace cv;
using namespace std;

int main()
{

 
 //time measurement
 double t1, t2, tOCL, tCPU, tInit, tFrame;
 int N = 1;
 
    
    VideoCapture cap(0); // open the default camera
    if (!cap.isOpened())  // check if we succeeded
     return -1;
    cap.set(CAP_PROP_FRAME_WIDTH, 2048);
    cap.set(CAP_PROP_FRAME_HEIGHT, 1536);

    UMat edges;
    namedWindow("edges", 1);
    for (;;)
    {
     
     //
     UMat frame,tempFrame;
     cap >> frame; // get a new frame from camera
     
     //==========================================================
     ocl::setUseOpenCL(true);
     
     
     //
     cvtColor(frame, edges, COLOR_BGR2GRAY);     
     //GaussianBlur(edges, edges, Size(51, 51), 2.5, 2.5); 
     t1 = getTickCount();
     Canny(edges, edges, 0, 10, 3);
     //
     t2 = getTickCount();
     tOCL = t2 - t1;
     //==========================================================

     ocl::setUseOpenCL(false);

     
     //
     cvtColor(frame, edges, COLOR_BGR2GRAY);
     
     //GaussianBlur(edges, edges, Size(51, 51), 2.5, 2.5); 
     t1 = getTickCount();
     Canny(edges, edges, 0, 10, 3);
     //
     t2 = getTickCount();
     tCPU = t2 - t1;
     
     //=============================
     tCPU = tCPU*1000.0 / getTickFrequency();
     tOCL = tOCL*1000.0 / getTickFrequency();

     //cout << "time spent on initialisation = " << tInit << endl;
     cout << "time spent on OCL = " << tOCL << endl;
     cout << "time spent on CPU = " << tCPU << endl << endl;
     cout << "speedUp = " << tCPU / tOCL << "x" << endl << endl << endl<< endl;



     imshow("edges", edges);
     if (waitKey(30) >= 0) break;

     
    }

 waitKey(0);

 return 0;
}






From the AMD developer conference April 2014 



Reference

  1. http://developer.amd.com/community/blog/2014/10/15/opencv-3-0-transparent-api-opencl-acceleration/
  2. http://www.learnopencv.com/opencv-transparent-api/
  3. http://opencv.org/opencv-3-0.html

No comments:

Post a Comment