daniel_chiu_Ex4

Autor: daniel_chiu
Data: 30/03/2009

Item 1

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

Sendo: (x',y') = T(x,y), ou seja, as coordenadas (x',y') são função das coordenadas (x,y) e A e B são matrizes, temos.

Item 2

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

A função affine permite realizar transformações nas imagens, como escala, rotação e translação. Tal função possui a seguinte forma:

Onde x',y' são as coordenadas transformadas pela matriz de transformação.

Abaixo, veremos como a função iaffine funciona.

Primeiramente, utilizaremos uma matriz 5x7, com números em seqüência, realizando as seguintes transformações: - Ampliação com fator 2 - Redução com fator 3 - Rotação de 30 graus

 1 M = arange(0, 5*7)
 2 M.resize(5,7)
 3 print 'matriz M\n',M,'\n'
 4 
 5 # matrizes de transformação
 6 T_AMPL_2X = array([[2,0,0],[0,2,0],[0,0,1]])
 7 T_RED_3X = array([[1./3,0,0],[0,1./3,0],[0,0,1]])
 8 T_ROT_30 = array([[cos(pi/6),sin(pi/6),0],[-sin(pi/6),cos(pi/6),0],[0,0,1]])
 9 
10 print 'Ampliação 2x\n',iaffine(M,T_AMPL_2X),'\n'
11 print 'Redução 3x\n',iaffine(M,T_RED_3X),'\n'
12 print 'Rotação 30 graus\n',iaffine(M,T_ROT_30),'\n'
matriz M
[[ 0  1  2  3  4  5  6]
 [ 7  8  9 10 11 12 13]
 [14 15 16 17 18 19 20]
 [21 22 23 24 25 26 27]
 [28 29 30 31 32 33 34]] 

Ampliação 2x
[[ 0  1  1  2  2  3  3]
 [ 7  8  8  9  9 10 10]
 [ 7  8  8  9  9 10 10]
 [14 15 15 16 16 17 17]
 [14 15 15 16 16 17 17]] 

Redução 3x
[[ 0  3  6  6  6  6  6]
 [21 24 27 27 27 27 27]
 [28 31 34 34 34 34 34]
 [28 31 34 34 34 34 34]
 [28 31 34 34 34 34 34]] 

Rotação 30 graus
[[ 0  1  9 10 17 18 26]
 [ 7  7 15 16 24 25 33]
 [14 14 22 23 30 31 32]
 [21 21 28 29 30 31 32]
 [21 28 28 29 29 30 31]]

A seguir, faremos o teste utilizando imagens.

1 image = mmreadgray('ia636/keyb.pgm')
2 adshow(image, title='Imagem original')
3 adshow(iaffine(image, T_AMPL_2X), title='Imagem ampliada com fator 2')
4 adshow(iaffine(image, T_RED_3X), title='Imagem reduzida com fator 3')
5 adshow(iaffine(image, T_ROT_30), title='Imagem rotacionada em 30 graus')

Imagem original

Imagem ampliada com fator 2

Imagem reduzida com fator 3

Imagem rotacionada em 30 graus

Item 3

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

Abaixo está a implementação da função fwdaffine, um affine com mapeamento direto. Esta função tem como parâmetros de entrada:

  • f: matriz que representa a imagem original
  • T: matriz de transformação. Esta matriz deve ser 3x3, no formato da matriz afim.
  • show_all: mostrar toda a imagem transformada. Esse parâmetro é opcional e o valor padrão é falso, e, dessa maneira, assim como no iaffine, a imagem não é mostrada integralmente. Caso haja coordenadas negativas na imagem transformada, elas serão suprimidas se este parâmetro tiver valor falso.

Valor de retorno:

  • matriz que representa a imagem transformada
 1 def fwdaffine(f, T,show_all=False):
 2 
 3     # arrays de coordenadas
 4     X,Y = meshgrid(range(0,f.shape[1]), range(0,f.shape[0]))
 5 
 6     # aplicando a matriz de transformação nas coordenadas.
 7     Ydash = T[1,0]*X + T[1,1]*Y + T[1,2]
 8     Ydash=Ydash.astype(int32)
 9     Xdash = T[0,0]*X + T[0,1]*Y + T[0,2]
10     Xdash=Xdash.astype(int32)
11 
12     # caso o parâmetro show_all seja falso, ignore as coordenadas de valor negativo
13     # isso foi feito para que não houvesse sobreposição de píxeis em coordenadas negativas
14     # com píxeis em coordenadas positivas
15     if show_all == False :
16         Xdash = (Xdash+abs(Xdash))/2
17         Ydash = (Ydash+abs(Ydash))/2
18     # caso contrário, a imagem será mostrada integralmente.
19     # os píxeis de valores negativos são mostrados, normalizando os valores das coordenadas
20     # para que apareçam na imagem.
21     else:
22         Xdash_min = Xdash.ravel()[argmin(Xdash)] # determinando o valor mínimo de x'
23         Ydash_min = Ydash.ravel()[argmin(Ydash)] # determinando o valor mínimo de y'
24         # normalização
25         if Xdash_min<0 :
26             Xdash = Xdash + abs(Xdash_min)
27         if Ydash_min<0 :
28             Ydash = Ydash + abs(Ydash_min)
29 
30     Xdash_max = Xdash.ravel()[argmax(Xdash)] # determinando o valor máximo de x'
31     Ydash_max = Ydash.ravel()[argmax(Ydash)] # determinando o valor máximo de y'
32 
33     g = zeros((max(f.shape[0],Ydash_max)+1 , max(f.shape[1],Xdash_max)+1))
34 
35     # atribuição dos valores de intensidades de f em g, em cada uma das
36     # coordenadas correspondentes.
37     g[Ydash,Xdash] = f
38 
39     # corte a imagem ao tamanho original, caso show_all seja falso.
40     if show_all==False :
41         g=g[0:f.shape[0], 0:f.shape[1]]
42     g=g.astype(int32)
43 
44     return g

Repetiremos os testes realizados no item 2, utilizando a função fwdaffine.

Teste com matriz de números:

1 M = arange(0, 5*7)
2 M.resize(5,7)
3 print 'matriz M\n',M,'\n'
4 print 'Ampliação 2x\n',fwdaffine(M,T_AMPL_2X),'\n'
5 print 'Redução 3x\n',fwdaffine(M,T_RED_3X),'\n'
6 print 'Rotação 30 graus\n',fwdaffine(M,T_ROT_30),'\n'
matriz M
[[ 0  1  2  3  4  5  6]
 [ 7  8  9 10 11 12 13]
 [14 15 16 17 18 19 20]
 [21 22 23 24 25 26 27]
 [28 29 30 31 32 33 34]] 

Ampliação 2x
[[ 0  0  1  0  2  0  3]
 [ 0  0  0  0  0  0  0]
 [ 7  0  8  0  9  0 10]
 [ 0  0  0  0  0  0  0]
 [14  0 15  0 16  0 17]] 

Redução 3x
[[16 19 20  0  0  0  0]
 [30 33 34  0  0  0  0]
 [ 0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0]
 [ 0  0  0  0  0  0  0]] 

Rotação 30 graus
[[ 7  8 16 17 25 26 33]
 [14 15  0 23 31 32  0]
 [ 0 21 29 30  0  0  0]
 [ 0 28  0  0  0  0  0]
 [ 0  0  0  0  0  0  0]]

Teste com imagem:

1 image = mmreadgray('ia636/keyb.pgm')
2 adshow(image, title='Imagem original')
3 adshow(fwdaffine(image, T_AMPL_2X), title='Imagem ampliada com fator 2')
4 adshow(fwdaffine(image, T_RED_3X), title='Imagem reduzida com fator 3')
5 adshow(fwdaffine(image, T_ROT_30), title='Imagem rotacionada em 30 graus')

Imagem original

Imagem ampliada com fator 2

Imagem reduzida com fator 3

Imagem rotacionada em 30 graus

É curioso observar como estas imagens ficam quando são mostradas integralmente.

1 # Matriz de transformação para rotação de 90 graus
2 T_ROT_90 = array([[0,1,0],[-1,0,0],[0,0,1]])
3 
4 adshow(fwdaffine(image, T_AMPL_2X, True), title='Imagem inteira ampliada com fator 2')
5 adshow(fwdaffine(image, T_ROT_30, True), title='Imagem inteira rotacionada em 30 graus')
6 adshow(fwdaffine(image, T_ROT_90, True), title='Imagem rotacionada 90 graus, sentdo anti-horário')

Imagem inteira ampliada com fator 2

Imagem inteira rotacionada em 30 graus

Imagem rotacionada 90 graus, sentdo anti-horário

Na transformação utilizando o mapeamento direto, os píxeis não são todos preenchidos, fazendo-se necessário uma interpolação, no caso de se querer uma imagem de aparência mais homogênea. Apesar disso, no iaffine, os píxeis fora do domínio da imagem não ficam negros, como neste fwdaffine. Além disso, não há uma opção de se mostrar a imagem inteira.