Gaussian blur in C using SDL

150 views Asked by At

I'm trying to create a Gaussian blur in C using SDL.

Here is my function:

We admit that the param surface is a grayscale image (that's why i only use the r).

SDL_Surface* gaussian_blur(SDL_Surface* surface) {
    int w = surface->w;
    int h = surface->h;

    SDL_Surface* res = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);

   
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            Uint8 r = 0;

            for (int i = -2; i <= 2; i++) {
                for (int j = -2; j <= 2; j++) {
                    Uint32 pixel = get_pixel(surface, x+i, y+j);
                    double weight = core[i+2][j+2];

                    r += pixel*weight;
                }
            }

            Uint32 nPixel = SDL_MapRGB(res->format, r, r, r);
            put_pixel(res, x, y, nPixel); 
        }
    }

    free_surface(surface);
    return res;
}

My core is defined as it :

double core[KERNEL_SIZE][KERNEL_SIZE] = {
    {1.0/273.0, 4.0/273.0, 7.0/273.0, 4.0/273.0, 1.0/273.0},
    {4.0/273.0, 16.0/273.0, 26.0/273.0, 16.0/273.0, 4.0/273.0},
    {7.0/273.0, 26.0/273.0, 41.0/273.0, 26.0/273.0, 7.0/273.0},
    {4.0/273.0, 16.0/273.0, 26.0/273.0, 16.0/273.0, 4.0/273.0},
    {1.0/273.0, 4.0/273.0, 7.0/273.0, 4.0/273.0, 1.0/273.0}
};
Uint32 get_pixel(SDL_Surface* surface, int x, int y) {
    int w = surface->w;
    int h = surface->h;

    if (surface != NULL && x >= 0 && x < w && y >= 0 && y < h) {
        Uint32* pixels = (Uint32*)surface->pixels;
        return pixels[y * w + x];
    }
    return 0;
}

void put_pixel(SDL_Surface* surface, int x, int y, Uint32 pixel) {
    int w = surface->w;
    int h = surface->h;
    
    if (surface != NULL && x >= 0 && x < w && y >= 0 && y < h) {
        Uint32* pixels = (Uint32*)surface->pixels;
        pixels[y * w + x] = pixel;
    }
}

The picture is the result of the function : Result of the function

I've searched on different sites but I can't find anything that could help me.

I can't use MATHLAB or OpenCV. I'm only allowed to use SDL

If anyone has any ideas on how to go about it, I'd love to hear from you.

1

There are 1 answers

0
ImDaronned On BEST ANSWER

My get_pixel give me all the color (r, g and b). So i have just to apply a mask (& 0xFF) to have the right color.

There is the correction :

Uint8 pixel_color(SDL_Surface* surface, int w, int h, int x, int y) {
    Uint8 r = 0;

    for (int i = -2; i <= 2; i++) {
        for (int j = -2; j <= 2; j++) {
            Uint32 pixel = get_pixel(surface, x+i, y+j);
            Uint8 pixel_color = pixel & 0xFF; //HERE
            double weight = core[i+2][j+2];

            int nX = x+i, nY = y+j; 

            if (nX >= 0 && nX < w && nY >= 0 && nY < h)
                r += pixel_color*weight;
            else
                r += weight*255;
        }
    }

    return r;
}

SDL_Surface* gaussian_blur(SDL_Surface* surface) {
    int w = surface->w;
    int h = surface->h;

    SDL_Surface* res = SDL_CreateRGBSurface(0, w, h, 32, 0, 0, 0, 0);

   
    for (int y = 0; y < h; y++) {
        for (int x = 0; x < w; x++) {
            
            Uint8 color = pixel_color(surface, w, h, x, y);

            Uint32 nPixel = SDL_MapRGB(res->format, color, color, color);
            put_pixel(res, x, y, nPixel); 
        }
    }

    free_surface(surface);
    return res;
}