GPU-based Gradient Vector Flow using OpenCL
Gradient Vector Flow (GVF) is a feature-preserving diffusion of gradient information. It was originally introduced by Xu and Prince to drive snakes, or active contours, towards edges of interest in image segmentation. However, GVF is also used for detection of tubular structures and skeletonization.
I just recently published an article in the Journal of Real-Time Image Processing entitled “Real-time gradient vector flow on GPUs using OpenCL” describing an optimized OpenCL implementation of Gradient Vector Flow (GVF) that runs on GPUs and CPUs for both 2D and 3D.
Conclusions from the project
- The implementation benefits a lot from using textures due to caching
- The OpenCL texture/image format CL_SNORM_INT16 has a big impact on performance as it halves the memory usage and has only a small impact on accuracy.
- Using shared memory actually makes the calculations slower due to expensive synchronization
- NVIDIA doesn’t support writing to 3D textures inside a kernel, this makes AMD GPUs much better at this type of processing.
The source code is available at: https://github.com/smistad/OpenCL-GVF/
Download and compile
# Install some dependencies sudo apt-get install git g++ cmake libgtk2.0-dev # Download source code git clone git://github.com/smistad/OpenCL-GVF.git cd OpenCL-GVF # Fetch the submodules git submodule init git submodule update # Compile cmake CMakeLists.txt make
Note: The default implementation will use a 32-bit floating point storage format, but if -16bit is specified it will use a 16-bit storage format (CL_SNORM_INT16). Use –device gpu to use the GPU or –device cpu to use the CPU. mu is the GVF parameter \(\mu\). Usually set to a value between 0.0 and 0.2 for 2D images and 0.0 and 0.05 for 3D images.
For 2D images
./GVF filename.jpg mu #iterations [-16bit] [--device cpu/gpu]
For 3D images
./GVF filename.raw size_x size_y size_z mu #iterations [-16bit] [--device cpu/gpu] ./GVF filename.mhd mu #iterations [-16bit] [--device cpu/gpu]