/*+-------------------------------------------------------------------------+ | MORFOLOGIA MATEMATICA: | | ---------------------- | | | | MORFO.H | | | | Arquivo que contem as rotinas para algumas operacoes morfologicas | | basicas como: DILATACAO, EROSAO, GRADIENTE. | | | +-------------------------------------------------------------------------+*/ /*+-------------------------------------------------------------------------+ | Implementacao da DILATACAO numerica: | | A dilatacao numerica para um elemento estruturante plano, e' simples-| | mente atribuir para cada pixel o valor maximo da sua vizinhanca conside-| | rada. Neste caso estamos considerando os 8-vizinhos de um ponto. | | PARAMETROS: | | I = ponteiro para imagem (entra) | | O = ponteiro da imagem resultado (retorna) | | nl = numero de linhas da imagem | | nc = numero de colunas da imagem | +-------------------------------------------------------------------------+*/ void dilata (int *I, int *O, int nl, int nc) { int i, j, di, dj, max; for (i = 0; i < nl; i++) for (j = 0; j < nc; j++) { if (i == 0 || i == nl - 1 || j == 0 || j == nc - 1) *(O+i*nc+j) = *(I+i*nc+j); else { max = 0; for (di = -1; di != 2; di++) for (dj = -1; dj != 2; dj++) if (*(I+(i+di)*nc + j+dj) > max) max = *(I+(i+di)*nc+j+dj); *(O+i*nc+j) = max; } } } /*+-------------------------------------------------------------------------+ | Implementacao da EROSAO numerica: | | A erosao numerica para um elemento estruturante plano e' simplesmente| | atribuir para cada pixel o valor minimo da sua vizinhanca considerada. | | PARAMETROS: | | I = ponteiro da imagem (entra) | | O = ponteiro da imagem resultado (saida) | | nl = numero de linhas da imagem | | nc = numero de colunas da imagem | | mn = maximo nivel de cinza | +-------------------------------------------------------------------------+*/ void erode (int *I, int *O, int nl, int nc, int mn) { int i, j, di, dj, min; for (i = 0; i < nl; i++) for (j = 0; j < nc; j++) { if (i == 0 || i == nl - 1 || j == 0 || j == nc - 1) *(O+i*nc+j) = *(I+i*nc+j); else { min = mn; for (di = -1; di != 2; di++) for (dj = -1; dj != 2; dj++) if (*(I+(i+di)*nc + j+dj) < min) min = *(I+(i+di)*nc+j+dj); *(O+i*nc+j) = min; } } } /*+-------------------------------------------------------------------------+ | Implementacao da INVERSAO de uma imagem qualquer (binaria ou numerica). | | PARAMETROS: | | I = ponteiro da imagem (entrada) | | O = ponteiro da imagem resultado (saida) | | nl = numero de linhas da imagem | | nc = numero de colunas da imagem | | mn = maximo nivel de cinza | +-------------------------------------------------------------------------+*/ void inverte (int *I, int *O, int nl, int nc, int mn) { int i, j; for (i = 0; i < nl; i++) for (j = 0; j < nc; j++) *(O+i*nc+j) = mn - *(I+i*nc+j); } /*+-------------------------------------------------------------------------+ | Implementacao da transformacao GRADIENTE: | | Esta transformacao e' obtida como diferenca entre o resultado da | | DILATACAO e o resultado da EROSAO. | | GRADIENTE = DILATACAO - EROSAO | | PARAMETROS: | | I = ponteiro da imagem (entrada) | | O = ponteiro da imagem resultado (saida) | | nl = numero de linhas da imagem | | nc = numero de colunas da imagem | | mn = maximo nivel de cinza | +-------------------------------------------------------------------------+*/ void gradiente (int *I, int *O, int nl, int nc, int mn) { int *D, *E; int i, j; aloca_memo (&D, nl, nc); aloca_memo (&E, nl, nc); dilata (I, D, nl, nc); erode (I, E, nl, nc, mn); for (i = 0; i < nl; i++) for (j = 0; j < nc; j++) *(O+i*nc+j) = *(D+i*nc+j) - *(E+i*nc+j); free (D); free (E); } /*+-------------------------------------------------------------------------+ | Implementacao da transformacao DISTANCIA: | | Esta transformacao pega uma imagem binaria e transforma numa imagem | | em niveis de cinza (numerica), onde cada valor representa a distancia | | dos pixeis caracteristicos (1) do fundo (0). | | PARAMETROS: | | I = ponteiro da imagem (entrada e saida) | | nl = numero de linhas da imagem | | nc = numero de colunas da imagem | | mn = maximo nivel de cinza | +-------------------------------------------------------------------------+*/ int min (int a, int b, int c) { int m; if (a < b) m = a; else m = b; if (c < m) m = c; return m; } void distancia (int *I, int nl, int nc, int *mn) { int i, j, maior, I1, I2; for (i = 1; i < nl-1; i++) for (j = 1; j < nc-1; j++) if (*(I+i*nc+j) != 0) { I1 = *(I+(i-1)*nc+j) + 1; I2 = *(I+i*nc+(j-1)) + 1; *(I+i*nc+j) = (I1 < I2) ? I1 : I2; } maior = 0; for (i = nl-1; i >= 0; i--) for (j = nc-1; j >= 0; j--) if (*(I+i*nc+j) != 0) { I1 = min (*(I+i*nc+j), *(I+i*nc+(j+1))+1, *(I+(i+1)*nc+j)+1); *(I+i*nc+j) = I1; if (I1 > maior) maior = I1; } *mn = maior; }