Skip to content

Sobel Filter

Portalez Régis edited this page May 11, 2026 · 5 revisions

Sobel Filter

Edge detection on a 1D byte buffer. Demonstrates 2D grid distribution over a flat array — explicit row/column indexing, no byte[,].

Source: src/2.Imaging/Sobel/Program.cs

[EntryPoint]
public static void ComputeSobel(byte[] outputPixel, byte[] inputPixel, int width, int height, int from, int to)
{
    for (int i = from + threadIdx.y + blockIdx.y * blockDim.y; i < to; i += blockDim.y * gridDim.y)
    {
        for (int j = threadIdx.x + blockIdx.x * blockDim.x; j < width; j += blockDim.x * gridDim.x)
        {
            int pixelId = i * width + j;
            if (i != 0 && j != 0 && i != height - 1 && j != width - 1)
            {
                byte topl = inputPixel[pixelId - width - 1];
                byte top  = inputPixel[pixelId - width];
                byte topr = inputPixel[pixelId - width + 1];
                byte l    = inputPixel[pixelId - 1];
                byte r    = inputPixel[pixelId + 1];
                byte botl = inputPixel[pixelId + width - 1];
                byte bot  = inputPixel[pixelId + width];
                byte botr = inputPixel[pixelId + width + 1];

                int output = Math.Abs(topl + 2*l + botl - topr - 2*r - botr)
                           + Math.Abs(topl + 2*top + topr - botl - 2*bot - botr);
                outputPixel[pixelId] = (byte) Math.Min(255, output);
            }
        }
    }
}

The grid is configured 2D via SetDistrib(gridX, gridY, blockX, blockY, blockZ, shmem). The host reads lena512.bmp via SixLabors.ImageSharp, converts to grayscale, runs the kernel, and writes lena-sobel.bmp.

See Sobel 2D for the same logic against byte[,] arrays (cleaner indexing).

Clone this wiki locally