Introdução à Transformação Geométrica

As transformações geométricas em imagens bidimensionais fazem um mapeamento entre as coordenadas da imagem original e as coordenadas da imagem transformada.

Iremos explicar as transformações geométricas com o auxílio de equações matemáticas, por ser uma representação mais precisa do que apenas explicar em linguagem natural. Entretanto, vamos procurar ser bastante consistentes entre as equações, nomes de variáveis usadas de modo que as equações que estamos colocando aqui sejam correspondências diretas nos programas Python/NumPy que estaremos exercitando.

As transformações geométricas são da forma a seguir. Temos a imagem de entrada f, com coordenadas (r,c) utilizando a notação do NumPy de (linha, coluna). O valor de f(r,c) deve ser mapeado para a nova imagem g na coordenada (r',c'):

$$ g(r',c') = f(r,c), \ \ (r,c) \in [0,H-1] \times [0,W-1] $$

As coordenadas (r',c') são dadas pela transformação geométrica com 6 parâmetros

$$ \begin{matrix} r'= t_{r,r} r + t_{c,r} c + t_{r}\\ c'= t_{r,c} r + t_{c,c} c + t_{c}\\ \end{matrix} $$

Coordenadas homogêneas

Utilizando a representação em coordenadas homogêneas, é possível colocar a equação acima na forma de multiplicação matricial.

$$ \begin{matrix} \left[\begin{array}{c} r' \\ c' \\ 1 \end{array}\right] &=& \left[\begin{array}{ccc} t_{r,r} & t_{c,r} & t_{r}\\ t_{r,c} & t_{c,c} & t_{c}\\ 0 & 0 & 1 \end{array} \right] \left[\begin{array}{c} r \\ c \\ 1 \end{array}\right] \end{matrix}$$

A matriz T é denominada de matriz de transformação geométrica e possui 6 elementos não nulos:

$$ \begin{matrix} T &=& \left[\begin{array}{ccc} t_{r,r} & t_{c,r} & t_{r}\\ t_{r,c} & t_{c,c} & t_{c}\\ 0 & 0 & 1 \end{array} \right] \\ \end{matrix} $$

Mapeamento Direto e Inverso

Existem duas formas principais de se implementar a transformação geométrica: Mapeamento direto e mapeamento inverso.

Mapeamento Direto

No mapeamento direto, varre-se os pixels da imagem f e mapeia-os na imagem g:

$$ g(T(r,c)) = f((r,c)), \ \ (r,c) \in [0,H-1] \times [0,W-1] $$

A desvantagem neste caso, é que, dependendo da transformação, pode existir pixels de g que não são preenchidos.

Mapeamento Inverso

No mapeamento inverso, varre-se os pixels da imagem g e busca-os na imagem f:

$$ g(r',c') = f(T^{-1}(r',c')),\ \ (r',c') \in [0,H'-1] \times [0,W'-1] $$

Este é o método que usaremos nos nossos experimentos.

Processando vários pontos simultaneamente por multiplicação de matrizes

Utilizando coordenadas homogêneas vimos que a transformação geométrica de uma coordenada pode ser feita multiplicando-se a matriz $T$. Como fazer a transformação geométrica de $n$ coordenadas utilizando uma multiplicação matricial?

$$ \begin{matrix} \left[\begin{array}{c} r'_0 & r'_1 & \ldots & r'_{n-1} \\ c'_0 & r'_1 & \ldots & c'_{n-1}\\ 1 & 1 & \dots & 1 \end{array}\right] &=& \left[\begin{array}{ccc} t_{r,r} & t_{c,r} & t_{r}\\ t_{r,c} & t_{c,c} & t_{c}\\ 0 & 0 & 1 \end{array} \right] \left[\begin{array}{c} r_0 & r_1 & \ldots & r_{n-1}\\ c_0 & c_1 & \ldots & c_{n-1}\\ 1 & 1 & \ldots & 1 \end{array}\right] \end{matrix}$$

Principais dificuldades

Apesar da teoria de transformação geométrica mostrada acima ser simples, ela possui várias considerações práticas que tornam sua implementação bastante complexa.

As principais dificuldades práticas no processamento de transformações geométrica são:

  1. A dificuldade intuitiva de operações nas coordenadas. Há necessidade de uso de operações trigonométricas e operações matriciais
  2. Domínio da imagem de saída geralmente não é o mesmo da imagem de entrada e não sabemos o que preencher nos lugares faltantes. Por exemplo seja uma operação simples de deslocamento horizontal da imagem por 20 pixels para a esquerda. O pixel de coordenada (0,0) deverá ser mapeado no pixel de coordenada (0,-20), mas não temos como representar estas coordenadas. Outro exemplo é a rotação, se rotacionarmos a imagem de 30 graus por exemplo, no sentido horário tendo a origem no canto superior esquerdo da imagem, percebe-se que partes da imagem da saída não serão preenchidas. Por simplicidade, nos nossos exercícios, vamos supor que o domínio que estaremos interessados na imagem g será o mesmo da imagem f. Isto é se deslocarmos f de metade de sua dimensão horizontal para a direita, a imagem resultante g terá apenas metade da imagem f deslocada para a direita.
  3. Interpolação: quando fazemos uma ampliação ou redução da imagem, ou ainda quando a coordenadas mapeadas, que serão em ponto flutuante, após a transformação geométrica, terão que ser mapeadas para coordenadas inteiras e necessitarão ser estimadas, é o que chamamos de interpolação. No nosso caso, para simplificar, usaremos apenas a interpolação denominada de vizinho mais próximo, isto é, quando calculamos os pixels de f a partir dos pixels transformados de g, suas coordenadas são em ponto flutuante (R,C):
$$ (R,C) = T^{-1}(r', c'), \ \ (R,C) \in \mathbb{R}^{2} $$

Interpolação

A interpolação que iremos utilizar é denominada "vizinho mais próximo" e fazemos isto com a operação de arredondamento do inteiro mais próximo, aqui denominada round e no NumPy sendo implementada tanto pelo rint como round:

$$ (r,c) = round(R,C), \ \ (r,c) \in \mathbb{Z}^2 $$

In [ ]: