Correlação digital


Processamento Digital de Imagens

Correlação Digital

A correlação digital serve para encontrar uma determinada região, um template, em uma imagem. Para isto, é medida a correlação (coeficiente de correlação) entre esta pequena imagem e todas as regiões da imagem. Em termos pr´ticos, é similar ao processo de filtragem, pois se desloca a amostra ao longo de toda a imagem variando as linhas e colunas, porém, neste caso, não se desloca o filtro, mas sim a imagem que se deseja encontrar.

DIca: Uma ajuda, existem funções para calcular a correlação em Python.

  • O comando rm=np.corrcoef(A,B) calcula a matriz de correlação entre dois vetores.
  • e então, r=rm[0,1] seria o elemento fora da diagonal que mostra a correlação entre A e B.

    Então, dada uma matriz (o template ou a região a sr=er analizada, devemos transformar esta matriz em um vetor. Podemos fazer isto usando uma função...
       
    def mat2vec(M):
        tl,tc = M.shape
        M1=np.zeros(( tl*tc),dtype = float)
        c=0
        for i in range(tl):      # varrer template e criar vetor
            for j in range(tc):
                M1[c]=M[i,j]
                c=c+1
        return(M1)
     
    OK, então, agora podemos fazer um programa que encontre este recorte nesta imagem?

    Então, a primeira parte voce já conhece, ler imagem e template. Também aproveitamos para convefrter o template em um vetor.
       
    
    # ler imagem de entrada e recuperar dimensoes
    X1= plt.imread('recorte.tif')
    nl,nc = X1.shape
    X=np.array(X1, dtype=float)   #transforma em float para facilitar multiplicacoes
    Y=np.zeros((nl,nc),dtype = float)        # replica imagem para gerar uma saida
    Y=np.uint8(Y)
    
    # Ler template
    T1= plt.imread('template.tif')
    tl,tc = T1.shape
    T=np.array(T1, dtype=float)
    print('Image size: ',nl,nc, "  Template size: ", tl, tc)
    
    dim=tl              # dimensao do filtro exe 3x3 dim=3, 5x5 dim=5...
    lado=(dim-1)/2      # numero de vizinhos antes ou depois do central
    lado=np.uint8(lado)
    
    TT=mat2vec(T)  # transforma matriz template a vetor
    
     

    Finalmente, podemos calcular a correlação para todas as posições da imagem:
       
    for L in range(lado,nl-lado):          # varrer em linhas lado+1, para vizinhos+central
        for C in range (lado, nc-lado):    # varrer em colunas
            # posicao inicial
            p=(L-lado)             # determina o elemento do filtro a ser usado
            q=(C-lado)
            R=X[p:p+tl, q:q+tc]   # copia a regiao de interesse
            RR=mat2vec(R)         # transforma regiao a vetor
            rm=np.corrcoef(RR,TT) # matriz de correlacao
            r=rm[0,1]             # correlacao
            if r<0:               # anulamos correlacoes negativas
                r=0
            rp=r*255              # mudamos para 8  bits para salvar imagem
            v=np.uint8( np.round( rp ) )   # arredonda e muda a uint8
            Y[L,C]=v                      # salva na posicao do central
    
    plt.imsave('matriz.png',Y,cmap='gray')
    
     

    Se tudo deu certo, voce tem esta imagem no seu disco. Note que existem varias posições onde a correlação é alta (regiões claras). Também se nota que em torno do máximo existem outros valores altos.

    Como estamos interessados em apenas um valor, vamos buscar o pixel que:

    1. seja maior que um limiar de correlação
    2. seja um máximo local
    3. seja o maior máximo local
       
    Limiar=200
    maximo=0                               # inicializar o maximo
    for L in range(lado,nl-lado):          # varrer em linhas lado+1, para vizinhos+central
        for C in range (lado, nc-lado):    # varrer em colunas
            if Y[L,C]>Limiar:              #pixel supera limiar, vejamos se é maximo local
    	    # se é maximo local, é maior que os quatro vizinhos
                if Y[L,C]>Y[L+1,C] and Y[L,C]>Y[L-1,C] and Y[L,C]>Y[L,C+1] and Y[L,C]>Y[L,C-1]:
                    if Y[L,C]>maximo:      # e se é maior que o anterior máximo registrado
                        maxL=L             # coordenadas do pico
                        maxC=C
                        maximo=Y[L,C]      # valor do máximo atual
    print('localizado em: ', maxL, maxC, '| ',maximo)
    
    # visualizar a imagem com o ponto localizado
    imgplot = plt.imshow(X, cmap='gray', vmin=0, vmax=255)
    plt.plot(maxC, maxL, 'o', color='red');
    plt.show()
     

    vamos ver, consegue rodar este programa ?