Our first GPU-based program

In this section, we show two versions of the same program: one version uses the CPU to perform computations, and the other version uses the GPU. These two examples are called edgesCPU and edgesGPU, respectively, and allow us to point out the differences when using the GPU module in OpenCV.

The edgesCPU example is presented in the first place:

#include <iostream>
#include "opencv2/core/core.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp" 
using namespace cv;

int main(int argc, char** argv){
if ( argc < 2 ){
        std::cout << "Usage: ./edgesGPU <image>" << std::endl;
        return -1;
    }
    Mat orig = imread(argv[1]);
    Mat gray, dst;

    bilateralFilter(orig,dst,-1,50,7);
    cvtColor(dst,gray,COLOR_BGR2GRAY);
    Canny(gray,gray,7,20);

    imshow("Canny Filter", gray);
    waitKey(0);

    return 0;
}

Now the edgesGPU example is shown as follows:

#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/gpu/gpu.hpp>
using namespace cv;

int main( int argc, char** argv){
  if ( argc < 2 ){
        std::cout << "Usage: ./edgesGPU <image>" << std::endl;
        return -1;
    }
    Mat orig = imread(argv[1]);
    gpu::GpuMat g_orig, g_gray, g_dst;
    //Transfer the image data to the GPU
    g_orig.upload(orig);

    gpu::bilateralFilter(g_orig,g_dst,-1,50,7);
    gpu::cvtColor(g_dst,g_gray,COLOR_BGR2GRAY);
    gpu::Canny(g_gray,g_gray,7,20);

    Mat dst;
    //Copy the image back to the CPU memory
    g_gray.download(dst);
    imshow("Canny Filter", dst);
    waitKey(0);

    return 0;
}

The explanation of the code is given as follows. There are several differences in the previous examples, although they ultimately obtain the same result, as shown in the following screenshot. A new header file is added as the new data type and different implementations of the algorithms are used. #include <opencv2/gpu/gpu.hpp> contains the GpuMat data type, which is the basic container that stores images in the GPU memory. It also includes the specific GPU versions of the filter algorithms used in the second example.

An important consideration is that we need to transfer the images between the CPU and the GPU. This is achieved with the g_orig.upload(orig) and g_gray.download(dst) methods. Once the image is uploaded to the GPU, we can apply different operations to it that are executed on the GPU. In order to distinguish the version of the algorithm that needs to run, the gpu namespace is used as in gpu::bilateralFilter, gpu::cvtColor, and gpu::Canny. After the filters have been applied, the image is copied to the CPU memory again and displayed.

Regarding performance, the CPU version runs in 297 milliseconds, whereas the GPU version runs in just 18 milliseconds. In other words, the GPU version runs 16.5x faster.

Our first GPU-based program

The output of the edgesCPU and edgesGPU examples

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset