Image resize with OpenCV 3.x and CUDA

This prototype implements and tests different downsampling algorithms of grayscale and color images to any size using C++, CUDA, OpenCV 3.X.

In image analysis downsampling is a fundamental transformation to significantly decrease the processing time with little or no errors introduced into the system.

Several algorithms exist, from simple skipping pixels which results in aliased images to more sophisticated reduction kernels with decrease in speed. Popular image processing libraries such OpenCV implement it as a simple geometric transformation like pixel area relation where areas are shrunk independently.

Three different methods are being implemented and compared to each other in the prototype :

  • OpenCV 3.x CPU based method cv::rezize() from the imgproc module.
  • OpenCV 3.x GPU based method cuda::rezize()¬†from the cudawarping module.
  • own method downscaleCuda() implemented in Cuda to run in parallel on the GPU. This method simply merges frames of pixels into a single points in the output image. For instance, a downscale of 4x on both x and y scale will merge frames of 4×4 pixels of the original image in a single pixel in the output image.

The code is build and compiled on a MSI laptop with Geforce GTX 970M, 3GB GDDR5 and 13 streaming multi processors.

OpenCV CPU implementation

In this first test, the image is loaded from the disk and and downscaled 4 times in both x and y scale using cv::resize.

OpenCV GPU implementation

In this second test, the image is loaded from the disk and and downscaled 4 times in both x and y scale using cuda::resize.

Own CUDA implementation

In this third test, the image is loaded from the disk and and downscaled 4 times in both x and y scale using own implemented cuda method.

Execution times of the 3 implementations on simple_room-wallpaper-4096×3072.jpg, 2,3 MB, 4096×3072 pixels to a 4x downscale

The 3 implementations were run 10 times in a row. By excluding the peaks from the output, we can see that the OpenCV CPU implementation took in average ~6.5 ms, the OpenCV GPU implementation took in average ~1.65 ms and the CUDA implementation took in average ~1.60 ms.

All these times does not include the time spent on loading the image into CPU or GPU memory, but only the time spent in processing the downscale. In a normal usage an image is loaded once and many transformations are aplied on it, so the loading time is irrelevant to the total processing time.

Profiling of the OpenCV GPU and own CUDA implementation using NSight profiler

Also in profiling can be seen the time spent on computing is about 1.5 ms for both methods.

resize_release_profile

 

 

 

 

 

 

 

 

 

Original and generated rescaled images with OpenCV GPU and own method

resize_simple_room-wallpaper-4096x3072

Original image

Resized 1 4th

Rescaled image using OpenCV GPU

Resized 1 4th

Rescaled image using CUDA method

Conclusion

Both GPU versions tend to have a similar speed. While the OpenCV implementation is straightforward and easy to use, the CUDA implementation gives more flexibility like sharing of the GPU memory between CUDA kernels without the need to copy back and forth between the CPU and GPU. Speedups can also been achieved using features of the CUDA runtime such streams, shared memory or pinned memory.

Sources

https://bitbucket.org/coldvisionio/coldvision-library/src/6f9843646d1a4443d860df42e642a4a1151d6c10/samples/2_imaging/resize/

Resources

https://en.wikipedia.org/wiki/Decimation_(signal_processing)

http://stackoverflow.com/questions/6133957/image-downsampling-algorithms

http://stackoverflow.com/questions/31761203/the-most-efficient-way-to-resize-cvmat

http://docs.opencv.org/master/da/d54/group__imgproc__transform.html#ga47a974309e9102f5f08231edc7e7529d

http://docs.opencv.org/master/db/d29/group__cudawarping.html#ga4f5fa0770d1c9efbadb9be1b92a6452a

http://docs.opencv.org/master/d3/d63/classcv_1_analysis1Mat.html#gsc.tab=0

http://docs.opencv.org/master/d0/d60/classcv_1_1cuda_1_1GpuMat.html#ab44144c4debe262119be744715138977

https://github.com/Itseez/opencv/blob/master/modules/cudawarping/src/resize.cpp

https://github.com/Itseez/opencv/blob/master/samples/gpu/hog.cpp

http://devblogs.nvidia.com/parallelforall/gpu-pro-tip-cuda-7-streams-simplify-concurrency/

http://docs.opencv.org/2.4/doc/tutorials/introduction/linux_eclipse/linux_eclipse.html

Leave a Reply

Your email address will not be published.