Exercicio 4 - Transformacoes Geometricas

  1. Equação matemática do uso indexado imagens no Python.

2. Estudar a função iaffine da toolbox ia636. Ver como funciona exercitando com valores interessantes. Entender como funciona a sua codificação.

Definimos 3 funcoes: scale, translate e rotate, passando a funcao de transformacao afim como parameto

 1 def scale(imagem, Sx, Sy, function):
 2     T = array([[Sx,0,0],[0,Sy,0],[0,0,1]], 'd')
 3     return function(imagem,T)
 4 #def
 5 
 6 def translate(imagem, Tx, Ty, function):
 7     T = array([[1,0,Tx],[0,1,Ty],[0,0,1]], 'd')
 8     return function(imagem,T)
 9 #def
10 
11 def rotate(imagem, angle, function):
12     T = array([[cos(angle),-sin(angle),0],[sin(angle),cos(angle),0],[0,0,1]], 'd')
13     return function(imagem,T)
14 #def

Funcao para teste de funcoes afim

 1 def testar_funcao(nome_da_funcao_afim):
 2 
 3     I = mmreadgray('keyb.pgm')
 4     adshow(I, title = 'imagem original')
 5 
 6     II = scale(I, 2, 4, nome_da_funcao_afim)
 7     adshow(II, title = 'imagem transformada - funcao Scale')
 8 
 9     II = translate(I,-30, 50, nome_da_funcao_afim)
10     adshow(II, title = 'imagem transformada - funcao Translate')
11 
12 
13     II = rotate(I,0.5, nome_da_funcao_afim)
14     adshow(II, title = 'imagem transformada - funcao Rotate')

Teste da funcao iaffine

1 testar_funcao(iaffine)

imagem original

imagem transformada - funcao Scale

imagem transformada - funcao Translate

imagem transformada - funcao Rotate

Note que o iaffine nao aceita translacao, isto ocorre porque o valor de W na matriz auxiliar 3xN esta com valor de ZERO, sendo o correto 1

  1. Fazer uma nova função, utilizando o mapeamento direto.

Funcao kaffine usando mapeamento DIRETO

 1 def kaffine(imagem, matriz_de_transformacao):
 2 
 3     # Definindo numero de linhase colunas da imagem original.
 4     linhas, colunas = imagem.shape
 5 
 6     # Crinado matrizes NxM de indices.
 7     matriz_linhas, matriz_colunas = mgrid[0:linhas, 0:colunas]
 8 
 9     # Montando matriz 3x(N*M) de INDICES, onde o ultimo valor eh o da coordenada homogenea, no caso, 1.
10     aux = concatenate((reshape(matriz_colunas, (1,linhas*colunas)), reshape(matriz_linhas, (1,linhas*colunas))))
11     aux = concatenate((aux, ones((1, linhas*colunas))))
12 
13     # Multiplicar matriz de INDICES 3xN * matriz_de_transformacao.
14     matriz_transformada = dot(matriz_de_transformacao, aux)
15 
16     # Separa os indices linhas da matriz transformada.
17     linhas_transformadas  = matriz_transformada[1]
18     # Arredonda os indices.
19     linhas_transformadas  = map(round,linhas_transformadas)
20     # Determina o limite MINIMO nos valores de indices.
21     linhas_transformadas  = map(maximum,linhas_transformadas, zeros(linhas*colunas))
22     # Determina o limite MAXIMO nos valores de indices.
23     linhas_transformadas  = map(minimum,linhas_transformadas, ones(linhas*colunas)*(linhas-1))
24     # Volta para matriz NxM de indices de linhas.
25     linhas_transformadas  = reshape(linhas_transformadas, (linhas,colunas))
26 
27     # Separa os indices colunas da matriz transformada.
28     colunas_transformadas = matriz_transformada[0]
29     # Arredonda os indices.
30     colunas_transformadas  = map(round,colunas_transformadas)
31     # Determina o limite MINIMO nos valores de indices.
32     colunas_transformadas  = map(maximum,colunas_transformadas, zeros(linhas*colunas))
33     # Determina o limite MAXIMO nos valores de indices.
34     colunas_transformadas  = map(minimum,colunas_transformadas, ones(linhas*colunas)*(colunas-1))
35     # Volta para matriz NxM de indices de colunas.
36     colunas_transformadas = reshape(colunas_transformadas, (linhas,colunas))
37 
38     # Cria nova matriz imagem NxM zerada.
39     nova_imagem = zeros((linhas,colunas))
40 
41     # Copia os valores da matriz imagem original na matriz nova_imagem indexada pelos indices transformados.
42     nova_imagem[uint32(linhas_transformadas), uint32(colunas_transformadas)] = imagem[matriz_linhas, matriz_colunas]
43 
44     return nova_imagem
45 #def

Teste da funcao kaffine

1 testar_funcao(kaffine)

imagem original

imagem transformada - funcao Scale

imagem transformada - funcao Translate

imagem transformada - funcao Rotate

Note que no mapeamento direto nao ha correspondencia para todos os pontos da imagem (pontos pretos)

  1. Opcionalmente, melhorar a função iaffine.

Reimplementando a funcao iafine corrigindo a translacao

 1 def iaffineX(f,T):
 2 
 3     from numpy.linalg import inv
 4 
 5     f, T = asarray(f), asarray(T)
 6     faux = ravel(f)
 7     if len(f.shape) == 1:
 8         f = f[newaxis,:]
 9     (m, n) = f.shape
10     (x, y) = iameshgrid(range(n),range(m))
11     aux = concatenate((reshape(x, (1,m*n)), reshape(y, (1,m*n))))
12     # CORRIGINDO O TRANSLATE !!!!
13     aux = concatenate((aux, ones((1, m*n))))
14     XY = dot(inv(T), aux)
15     X = XY[0]
16     Y = XY[1]
17     X = map(round, X)
18     Y = map(round, Y)
19     X = maximum(0, minimum(n-1, X))
20     Y = maximum(0, minimum(m-1, Y))
21 
22 
23     XYi = iasub2ind(f.shape, Y, X)
24     g = take(faux, XYi)
25     g = reshape(g, f.shape)
26     return g
27 #def
28 
29 testar_funcao(iaffineX)

imagem original

imagem transformada - funcao Scale

imagem transformada - funcao Translate

imagem transformada - funcao Rotate

Vejam este mesmo exercício feito em MATLAB em ano anterior: http://calhau.dca.fee.unicamp.br/wiki/index.php/Exercicio4

Autor:gkaneblai
Data:29/03/2009