Autor Tema: Filtro Sobel en C++ con librería CImg (cplusplus)  (Leído 6465 veces)

fernandoasr.8

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 14
    • Ver Perfil
Filtro Sobel en C++ con librería CImg (cplusplus)
« en: 19 de Octubre 2014, 20:00 »
Buen día, he estado usando un poco la librería CImg en C++. El problema que tengo en estos momentos, es como aplicar un filtro Sobel a una imagen.
Cargo la imagen en escala de grises y aplico el código siguiente.

Código: [Seleccionar]

    int GX[3][3];
    int GY[3][3];

    GX[0][0] = -1; GX[0][1] = 0; GX[0][2] = 1;
    GX[1][0] = -2; GX[1][1] = 0; GX[1][2] = 2;
    GX[2][0] = -1; GX[2][1] = 0; GX[2][2] = 1;

    GY[0][0] =  1; GY[0][1] =  2; GY[0][2] =  1;
    GY[1][0] =  0; GY[1][1] =  0; GY[1][2] =  0;
    GY[2][0] = -1; GY[2][1] = -2; GY[2][2] = -1;


    unsigned char X, Y;
    CImg<unsigned char> XX(width,height,depth,1);
    CImg<unsigned char> YY(width,height,depth,1);
    imfinalsob.assign(width, height, depth,1);
    for(int i=1;i<width-1;i++)
    {
        for(int j=1;j<height-1;j++)
        {
            X = (sobel(i-1, j-1)*GX[0][0]) + (sobel(i-1, j)*GX[0][1]) + (sobel(i-1, j+1)*GX[0][2]) +
                (sobel(i,   j-1)*GX[1][0]) + (sobel(i,   j)*GX[1][1]) + (sobel(i,   j+1)*GX[1][2]) +
                (sobel(i+1, j-1)*GX[2][0]) + (sobel(i+1, j)*GX[2][1]) + (sobel(i+1, j+1)*GX[2][2]);

            Y = (sobel(i-1, j-1)*GY[0][0]) + (sobel(i-1, j)*GY[0][1]) + (sobel(i-1, j+1)*GY[0][2]) +
                (sobel(i,   j-1)*GY[1][0]) + (sobel(i,   j)*GY[1][1]) + (sobel(i,   j+1)*GY[1][2]) +
                (sobel(i+1, j-1)*GY[2][0]) + (sobel(i+1, j)*GY[2][1]) + (sobel(i+1, j+1)*GY[2][2]);

            XX(i,j)=X/4;
            YY(i,j)=Y/4;

            imfinalsob(i,j)= XX(i,j)+YY(i,j);

        }
    }
    CImgDisplay img_d(imfinalsob, "Sobel");
    img_d.wait(4000).close();


El resultado final es una imagen que en vez de un filtro Sobel, parece un tipo de piedra. Espero alguien pueda ayudarme o indicarme en que parte del algoritmo tengo el error.

Muchas gracias de antemano.
« Última modificación: 11 de Mayo 2015, 19:02 por Alex Rodríguez »

Mastermind

  • Experto
  • *****
  • Mensajes: 536
    • Ver Perfil
Re:Filtro Sobel en C++ con librería CImg
« Respuesta #1 en: 19 de Octubre 2014, 21:06 »
Hola, si lo aplicaras a una imagen como una fotografía en blanco y negro (p.ej. la que pone wikipedia como ejemplo)


Se supone que saldrían los bordes de los objetos, como si fuera un dibujo a lápiz


Si lo aplicas a la fotografía en blanco y negro ¿qué te sale?

fernandoasr.8

  • Sin experiencia
  • *
  • APR2.COM
  • Mensajes: 14
    • Ver Perfil
Re:Filtro Sobel en C++ con librería CImg
« Respuesta #2 en: 24 de Octubre 2014, 20:19 »
He conseguido el resultado que deseaba, aquí el código que me funcionó. Gracias por la respuesta.

Código: [Seleccionar]
    int XX[3][3];
    int YY[3][3];

    XX[0][0] = -1; XX[0][1] = 0; XX[0][2] = 1;
    XX[1][0] = -2; XX[1][1] = 0; XX[1][2] = 2;
    XX[2][0] = -1; XX[2][1] = 0; XX[2][2] = 1;

    YY[0][0] =  1; YY[0][1] =  2; YY[0][2] =  1;
    YY[1][0] =  0; YY[1][1] =  0; YY[1][2] =  0;
    YY[2][0] = -1; YY[2][1] = -2; YY[2][2] = -1;


    CImg<unsigned char> px;
    px.assign(width, height, depth, 1);

    for(y = 0; y < height; y++)
    {
        for(x = 0; x < width; x++)
        {
            SX = 0;
            SY = 0;

            if(y == 0 || y == height -1 || x == 0 || x == width -1)
            {
                M = 0;
            }
            else
            {
                for(int i = 0; i < 3; i++)
                {
                    for(int j = 0; j < 3; j++)
                    {
                        SX = SX + XX[j][i] * (int)gris(x+j,y+i);
                    }
                }

                for(int i = 0; i < 3; i++)
                {
                    for(int j = 0; j < 3; j++)
                    {
                        SY = SY + YY[j][i] * (int)gris(x+j,y+i);
                    }
                }
                M = sqrt(pow((double)SX,2) + pow((double)SY,2));
            }
            if(M > 255) M = 255;
            if(M < 0) M = 0;
            px(y,x) = M;
        }
    }

    imfinalsob.assign(width, height, depth,1);
    for(y = 0; y < gris.height(); y++)
    {
        for(x = 0; x<gris.width(); x++)
        {
            imfinalsob(x,y) = px(y,x);
        }
    }

Mastermind

  • Experto
  • *****
  • Mensajes: 536
    • Ver Perfil
Re:Filtro Sobel en C++ con librería CImg
« Respuesta #3 en: 25 de Octubre 2014, 14:36 »
Gracias a tí por compartir el código!!!

 

Sobre la educación, sólo puedo decir que es el tema más importante en el que nosotros, como pueblo, debemos involucrarnos.

Abraham Lincoln (1808-1865) Presidente estadounidense.

aprenderaprogramar.com: Desde 2006 comprometidos con la didáctica y divulgación de la programación

Preguntas y respuestas

¿Cómo establecer o cambiar la imagen asociada (avatar) de usuario?
  1. Inicia sesión con tu nombre de usuario y contraseña.
  2. Pulsa en perfil --> perfil del foro
  3. Elige la imagen personalizada que quieras usar. Puedes escogerla de una galería de imágenes o subirla desde tu ordenador.
  4. En la parte final de la página pulsa el botón "cambiar perfil".