Estoy escribiendo mi propia implementación de la sobel borde de la detección. Mi función es la interfaz es

void sobel_filter(volatile PIXEL * pixel_in, FLAG *EOL, volatile PIXEL * pixel_out, int rows, int cols)

(PÍXEL en una de 8 bits en escala de grises de píxeles)

Para las pruebas he cambiado la interfaz:

vacío sobel_filter(PIXEL pixels_in[MAX_HEIGHT][MAX_WIDTH],PIXEL
pixels_out[MAX_HEIGHT][MAX_WIDTH], int filas,int cols);

Pero Aún así, la cosa es que me pongo a leer un píxel a la vez, lo que me lleva al problema de la gestión de los valores de salida de sobel cuando son más grande 255 o inferior a 0. Si yo tuviera todo el panorama desde el inicio, yo podría normalizar todos los sobel valores de salida con sus valores min y max. Pero esto no es posible para mí.

Este es mi código de operador sobel, ver1:

PIXEL sobel_op(PIXEL_CH window[KERNEL_SIZE][KERNEL_SIZE]){
    const char x_op[KERNEL_SIZE][KERNEL_SIZE] = { { -1,0,1},
                { -2,0,2},
                { -1,0,1}};

    const char y_op[KERNEL_SIZE][KERNEL_SIZE] = { {1,2,1},
                {0,0,0},
                { -1,-2,-1}};
    short x_weight=0;
    short y_weight=0;
    PIXEL ans;
    for (short i=0; i<KERNEL_SIZE; i++){
        for(short j=0; j<KERNEL_SIZE; j++){
            x_weight+=window[i][j]*x_op[i][j];
            y_weight+=window[i][j]*y_op[i][j];
        }
    }
    short val=ABS(x_weight)+ABS(y_weight);
    //make sure the pixel value is between 0 and 255 and add thresholds
    if(val>200)
        val=255;
    else if(val<100)
        val=0;
    ans=255-(unsigned char)(val);
    return ans;

}

esta es la versión 2, los cambios se realizan sólo después de resumir los pesos:

short val=ABS(x_weight)+ABS(y_weight);
unsigned char char_val=(255-(unsigned char)(val));
//make sure the pixel value is between 0 and 255 and add thresholds
if(char_val>200)
    char_val=255;
else if(char_val<100)
    char_val=0;
ans=char_val;
return ans;

Ahora, por un 3×3 sobel ambos parecen estar dándole a ACEPTAR los resultados:
filtro de sobel algoritmo de umbralización (no externa libs usa);

filtro de sobel algoritmo de umbralización (no externa libs usa)

Pero cuando intento con un 5×5 sobel

    const char x_op[KERNEL_SIZE][KERNEL_SIZE] = { {1,2,0,-2,-1},
                {4,8,0,-8,-4},
                {6,12,0,-12,-6},
                {4,8,0,-8,-4},
                {1,2,0,-2,-1}};

const char y_op[KERNEL_SIZE][KERNEL_SIZE] = { { -1,-4,-6,-4,-1},
                { -2,-8,-12,-8,-2},
                {0,0,0,0,0},
                {2,8,12,8,2},
                {1,4,6,4,1}};

la cosa se complica:
filtro de sobel algoritmo de umbralización (no externa libs usa)
filtro de sobel algoritmo de umbralización (no externa libs usa)

Como se puede ver, para el 5×5 los resultados son bastante malos y no sé cómo normalizar los valores. Alguna idea?

InformationsquelleAutor genau | 2014-05-23

2 Comentarios

  1. 4

    Pensar acerca de la gama de valores que la filtrada valores que puede tomar.

    Para la Sobel 3×3, la más alta de X/Y valor se obtiene cuando los píxeles con un coeficiente positivo son de color blanco (255), y los que tienen un coeficiente negativo son el negro (0), lo que da un total de 1020. Simétricamente, el valor más bajo es de -1020. Después de tomar el valor absoluto, el rango es de 0 a 1020 = 4 x 255.

    Por la magnitud, Abs(X)+Abs(Y), el cálculo es un poco más complicado ya que los dos componentes no pueden llegar a 1020 al mismo tiempo. Si estoy en lo cierto, el rango es de 0 a 1530 = 6 x 255.

    Cifras similares para el 5×5 son de 48 x 255 y 66 x 255.

    Que, sabiendo esto, usted debe cambiar la escala de los valores a un rango menor (aplicar un coeficiente de reducción), y ajustar los umbrales. Lógicamente, si se aplica un coeficiente de 3/66 a la Sobel 5×5, volverá a condiciones similares.

    Todo depende del efecto que se desea lograr.

    De todos modos, la verdadera pregunta es: ¿cómo son los valores filtrados estadísticamente distribuido de imágenes típicas ? Porque es necesario mantener el extremo de las colas de la distribución.

  2. 3

    Tiene para normalizar los resultados de su cálculo. Para que usted tiene que averiguar cómo «grande» es el filtro con todos los absoltue valores. Así que hacer esto:

          for(int i = 0; i < mask.length; i++)
            for(int j = 0; j < mask[i].length; j++)
                size += Math.abs(mask[i][j]);

    Donde la máscara es mi filtro de sobel de cada tamaño. Así que después de aplicar su filtro de sobel tiene para normalizar su valor en el código debería parecerse a:

    for (short i=0; i<KERNEL_SIZE; i++){
        for(short j=0; j<KERNEL_SIZE; j++){
            x_weight+=window[i][j]*x_op[i][j];
            y_weight+=window[i][j]*y_op[i][j];
        }
    }
    x_weight /= size;
    y_weight /= size;

    Después de que la visualización que usted tiene que cambiar los valores de unos 128. Sólo hacerlo si desea visualizar la imagen. De lo contrario se tienen problemas con cálculos posteriores (gradiente por ejemplo).

    x_weight += 128;
    y_weight += 128;

    Espero que funcione y ayuda.

Dejar respuesta

Please enter your comment!
Please enter your name here