RGB to grayscale conversion in CUDA and OpenCV

This prototype deals with the conversion of colour pictures from RGB to grayscale using C++, CUDA, OpenCV and Jetson TK1 for building and deployment.

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

  • an already implemented method from OpenCV cv::cvtColor()
  • own method rgbaToGreyscaleCuda() implemented in Cuda to run in parallel on the GPU
  • own method rgbaToGreyscaleCpu() implemented in C++ to run on CPU with a single thread

The code is build and compiled remotely on the Jetson Tegra K1 development board where OpenCV4Tegra, a free library provided by NVIDIA containing optimizations for NVIDIA’s Tegra CPUs (ARM NEON SIMD optimizations, multi-core CPU optimizations and some GLSL GPU optimizations) is installed.

Formula

A common way to represent color images is called as RGBA – the color is specified by its Red, Green, and Blue colour content. The ‘A’ stands for Alpha and is used for transparency; it will be ignored in this project.
Each channel Red, Blue, Green, and Alpha is represented by one byte. Since we are using one byte for each color there are 256 possible values for each color. So basically, we use 4 bytes per pixel.
Greyscale images are represented by a single intensity value per pixel which is one byte in size.
One simple method to convert an image from colour to grayscale is to set the intensity to the average of the RGB channels.  But we will use a more sophisticated method that takes into account how the eye perceives color and weights the channels unequally.
The eye responds most strongly to green followed by red and then blue. The NTSC (National Television System Committee) recommends the following formula for color to greyscale conversion:

OpenCV implementation

In this first test, the image is loaded from the disk and the method cv::cvtColor from OpenCV4Tegra is used to convert the image into grayscale.

CUDA implementation

In the second test, the image is loaded from the disk, its content is copied to the GPU memory and rgbaToGreyscaleCuda() is executed. The rgbaToGreyscaleCuda() initializes the threads and blocks, and starts the CUDA kernel rgbaToGreyscaleCudaKernel() to process each x_y position in parallel.

CPU implementation

The third test does the same as the first two tests, but here the processing happens in the CPU using a single thread. This method is implemented only to test the correctiveness and the speed of the other two implementations OpenCV and CUDA.

Execution times of the 3 implementations on image_big.jpg, 748,4 kB, 2560×1920 pixels

The 3 implementations were run 10 times in a row. By excluding the peaks from the output, we can see that the OpenCV implementation took in average ~4.5 ms, the CUDA implementation took in average ~4.0 ms, while the CPU single thread implementation took in average ~46 ms.

Execution times of the 3 implementations on image_small.jpg, 100,0 kB, 800×600 pixels

The 3 implementations were run again 10 times in a row. By excluding the peaks from the output we can see that the OpenCV implementation took in average ~0.5 ms, the CUDA implementation took in average ~1.5 ms, while the CPU single thread implementation took in average ~3 ms.

Compiler options

Original and generated grayscale images

image_big output_cuda

Conclusion

With an increase in the image size, the CUDA implementation tends to be faster than the OpenCV version, while the CPU version rapidly slows down with an increase in size.

Sources

https://bitbucket.org/coldvisionio/coldvision-library/src/b16b50352cdf3a3680e0077931f4ff0b5ab1256a/samples/2_imaging/grayscale/?at=master

References

https://en.wikipedia.org/wiki/Grayscale

https://www.udacity.com/course/viewer#!/c-cs344/

http://docs.nvidia.com/cuda/cuda-samples/index.html#imaging

http://docs.nvidia.com/cuda/index.html#programming-guides

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

http://docs.opencv.org/2.4/modules/imgproc/doc/miscellaneous_transformations.html

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

http://elinux.org/Jetson/Tutorials/OpenCV

http://elinux.org/Jetson/Computer_Vision_Performance

Leave a Reply

Your email address will not be published.