Peak detection is a fundamental task in image processing that allows us to extract key information from images. It helps us identify significant points like edges, corners, or objects of interest. In this article, we’ll explore how to achieve this using GLSL shader code, a powerful tool for processing images directly on the graphics processing unit (GPU).
What is peak detection and why we do it?
Algorithms such as Hough transform and Harris corners detection often require post-processing to isolate the dominant regions of interest. Otherwise we get too noisy image results that prevent our successful segmentation.
This simple peak detector source code helps to achieve this. The algorithm uses a generic non-maximum suppression to eliminate local minima and preserve the dominant results.
Source Code
This algorithm uses separable non-maximal suppression to achieve better performance. Its valuable property to search for peaks in parallel makes it suitable for GPU implementations.
precision mediump float;
#define KERNEL_SIZE %kernelSize%
// our texture
uniform sampler2D u_image;
uniform vec2 u_textureSize;
uniform vec2 u_direction;
#define GET_PIXEL(_p) (texture2D(u_image, textCoord + onePixel*float(_p)))
void main() {
vec2 onePixel = u_direction / u_textureSize;
vec2 textCoord = gl_FragCoord.xy / u_textureSize;
if (any(lessThan(GET_PIXEL(0).rgb, vec3(0.0))))
{
gl_FragColor = vec4(vec3(0.0), 1.0);
}
else
{
int maxIndex = KERNEL_SIZE;
float maxValue = 0.0;
for (int i = -KERNEL_SIZE; i <= KERNEL_SIZE; i++)
{
vec3 color = GET_PIXEL(i).rgb;
float p = dot(color, color);
if (p > maxValue)
{
maxValue = p;
maxIndex = i;
}
}
vec4 color = GET_PIXEL(maxIndex);
gl_FragColor = ((maxIndex == 0) ? color : vec4(vec3(-color.rgb)*u_direction.y, 1.0));
}
}
How this peak detector works?
The following steps briefly describe how the above peak detector code works:
- First, we define the constant “KERNEL_SIZE” so that it is equal to the maximum distance between the peaks;
- For each row in the image we use a sliding window with the defined size. At each step we invert all non-maximum values to a negative number;
- Next we handle the non-maximum values per each column in the same was as in the previous step.
- Pixels with negative value are set to zero
Online Example
WEB APPLET
See how it works in the browser!
Conclusion
In this article we reveal a simple, but yet fast way to isolate peaks in 2D image/array using OpenGL/WebGL shader code. If you find this article useful, you can browse our image analysis algorithms and our software developers portal.