Przekształcenia geometryczne

Transformacje (przekształcenia) geometryczne  są wykorzystywane w przetwarzaniu obrazu z wielu powodów link.

Między innymi pozwalają one ujednolicić format obrazów (przenieść do jednakowego układu odniesienia), tak, że mogą one być łączone (np. operacje arytmetyczne) lub porównanie (np. znajdowanie różnic po upływie pewnego czasu). Mogą być stosowane w celu wyeliminowania zniekształceń (np. zniekształcenia powodowane przez szerokokątne obiektywy). Transformacje geometryczne mogą również uprościć dalsze przetwarzanie obrazu.

W przypadku gdy mamy:

  1. obraz po zniekształceniu $f(i,j)$,
  2. obraz przed zniekształceniem $f'(i',j')$,

to możemy modelować przekształcenie geometryczne pomiędzy współrzędnymi pikseli jako:

\[ i = T_i(i',j'), \qquad j = T_j(i',j') \],

gdzie $(i,j)$ są współrzędnymi pikseli na oryginalnym obrazie, a funkcje $T_i( )$ oraz $T_j( )$ wyznaczają współrzędne pikseli na obrazie przekształconym.

Operacje afiniczne

Wiele podstawowych operacji (używanych w analizie obrazu) można opisać za pomocą przekształceń afinicznych, które definiuje się za pomocą mnożenia macierzy:

\[ \begin{bmatrix} i \\ j  \end{bmatrix}= \begin{bmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12}  \end{bmatrix} \begin{bmatrix} i' \\ j' \\ 1 \end{bmatrix} \]

Istnieje wiele przykładów przekształceń, które są szeroko stosowane w przetwarzaniu grafiki:

Translacja (przesunięcie)

Przesunięcie można uzyskać za pomocą przekształcenia: 

\[ \begin{bmatrix} i \\ j  \end{bmatrix}= \begin{bmatrix} 1 & 0 & m \\ 0 & 1 & n  \end{bmatrix} \begin{bmatrix} i' \\ j' \\ 1 \end{bmatrix}, \],

gdzie $m$ określa przesunięcie w poziomie, a $n$ w pionie.

  

Ilustracja. Efekt przesunięcia o $m=40$ oraz $n=80$.

Powyższy efekt można uzyskać za pomocą kodu w OpenCV (C++).

Przeskalowanie (zmniejszenie / rozszerzenie)

Przeskalowanie można uzyskać za pomocą przekształcenia:

 \[ \begin{bmatrix} i \\ j  \end{bmatrix}= \begin{bmatrix} a & 0 & 0 \\ 0 & b & 0  \end{bmatrix} \begin{bmatrix} i' \\ j' \\ 1 \end{bmatrix}, \]

gdzie $a$ odpowiada za rozciągnięcie w poziomie, a $b$ w pionie. Operacja ta pozwala normalizować obiekty na obrazie.

  

Ilustracja. Efekt przeskalowania z $a=0.5$ oraz $b=1.5$.

Powyższy efekt można uzyskać za pomocą kodu w OpenCV (C++).

Obroty

Obrót można uzyskać za pomocą przekształcenia:

 \[ \begin{bmatrix} i \\ j  \end{bmatrix}= \begin{bmatrix} \cos( \phi ) & \sin(\phi) & 0 \\ - \sin(\phi) & cos(\phi) & 0  \end{bmatrix} \begin{bmatrix} i' \\ j' \\ 1 \end{bmatrix}, \]

gdzie $\phi$ jest kątem obrotu. 

  

Ilustracja. Obrót o kąt $\frac{\pi}{4}$.

Powyższy efekt można uzyskać za pomocą kodu w OpenCV (C++).

Pochylenie

Pochylenie można uzyskać za pomocą przekształcenia:

 \[ \begin{bmatrix} i \\ j  \end{bmatrix}= \begin{bmatrix} 1 & \tan(\phi) & 0 \\ 0 & 1 & 0  \end{bmatrix} \begin{bmatrix} i' \\ j' \\ 1 \end{bmatrix}, \]

gdzie $\phi$ jest kątem pochylenia.

  

Ilustracja. Pochylanie o kąt $\frac{\pi}{8}$.

Powyższy efekt można uzyskać za pomocą kodu w OpenCV (C++).

 Przekształcenie panoramiczne

Przekształcenie panoramiczne można uzyskać za pomocą przekształcenia:

 \[ \begin{bmatrix} i \\ j  \end{bmatrix}= \begin{bmatrix} a & 0 & 0 \\ 0 & 1 & 0  \end{bmatrix} \begin{bmatrix} i' \\ j' \\ 1 \end{bmatrix}, \]

Panoramiczne przekształcenie poprawia nieprawidłowe proporcje.

Przykład. 

Operacji afinicznych możemy użyć do przekształcenia obiektu, tak aby jego geometria odpowiadała zadanemu układowi współrzędnych.

    

  

Ilustracja. Wynik działania obrotu o kąt $15^o$ pochylenia z kątem $\frac{\pi}{12}$
i przekształcenia panoramicznego z $a = 1.3$.

Powyższy efekt można uzyskać za pomocą kodu w OpenCV (C++).

Znajdowanie nieznanego przekształcenia afinicznego

W niektórych zagadnieniach mamy podany obiekt przed i po zniekształceniu, a naszym celem jest wyznaczenie macierzy przekształcenia. Jeżeli założymy, że przekształcenie jest afiniczne, czyli że istnieje macierz postaci:

\[  \begin{bmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12}  \end{bmatrix} \]

opisująca nasze przekształcenie, to jesteśmy wstanie je odzyskać na podstawie informacji o co najmniej $3$ pikselach.

Jeżeli mamy zaobserwowane przekształcenie:

\[ (i_1,j_1) \to (i'_1,j'_1),\]

\[ (i_2,j_2) \to (i'_2,j'_2),\]

\[ (i_3,j_3) \to (i'_3,j'_3)\]

 zakładamy, że w każdym z tych przypadków otrzymane przekształcenie jest efektem mnożenia macierzy (przekształcenie afiniczne)

\[ \begin{bmatrix} i \\ j  \end{bmatrix}= \begin{bmatrix} a_{00} & a_{01} & a_{02} \\ a_{10} & a_{11} & a_{12}  \end{bmatrix} \begin{bmatrix} i' \\ j' \\ 1 \end{bmatrix} \]

to układ powstały w taki sposób można zapisać jako:

\[ \begin{bmatrix} i_1 \\ j_1 \\ i_2 \\ j_2 \\ i_3 \\ j_3 \\ \end{bmatrix}= \begin{bmatrix} i'_1 & j'_1 & 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & i'_1 & j'_1 & 1 \\ i'_2 & j'_2 & 1 & 0 & 0 & 0 \\ 0 & 0  & 0 & i'_2 & j'_2 & 1 \\ i'_3 & j'_3 & 1 & 0 & 0 & 0 \\   0 & 0 & 0 & i'_3 & j'_3 & 1 \\  \end{bmatrix} \begin{bmatrix} a_{00} \\ a_{01} \\ a_{02} \\ a_{10} \\ a_{11} \\ a_{12} \end{bmatrix} \]

Powyższe równanie można obliczyć przemnażając obie strony równania przez macierz odwrotną. W przypadku posiadania większej liczby przekształcanych punktów powyższy układ można rozwiązać za pomocą metody Uogólnionej macierzy odwrotnej.

  

Ilustracja. Znalezione przekształcenie afiniczne.

Powyższy efekt można uzyskać za pomocą kodu w OpenCV (C++).

Transformacja perspektywiczna

Obrazy uzyskiwane przez większość aparatów są zwykle tworzone przez rzutowanie perspektywy, elementy ze świata 3D są rzutowane na płaszczyznę obrazu (model kamery otworkowej) lub przez obiektyw. Zniekształcenie perspektywiczne nie jest przekształceniem afinicznym, dlatego musimy użyć bardziej złożonego modelu:

\[ \begin{bmatrix} i \cdot w \\ j \cdot w \\ w \end{bmatrix}= \begin{bmatrix} p_{00} & p_{01} & p_{02} \\ p_{10} & p_{11} & p_{12} \\ p_{20} & p_{21} & p_{22} \end{bmatrix} \begin{bmatrix} i' \\ j' \\ 1 \end{bmatrix}, \]

Dla tej transformacji, potrzebujemy co najmniej cztery punkty i ich obrazy. Wtedy możemy łatwo wyliczyć wzory.

Z pierwszego równania mamy:

\[i ⋅ w = p_{00} \cdot i′ + p_{01} \cdot j′ + p_{02}\] 

oraz z trzeciego:

\[w = p_{20} \cdot i′ + p_{21} \cdot j′ + 1.\]
Stąd:

\[i = p_{00} \cdot i′ + p_{01} \cdot j′ + p_{02} − p_{20} \cdot i \cdot i′ − p_{21} \cdot i \cdot j′.\]

Analogiczne przeliczenie można wykonać dla drugiej współrzędnej

\[j = p_{10} \cdot i′ + p_{11} \cdot j′ + p_{12} − p_{20} \cdot j \cdot i′ − p_{21} \cdot j \cdot j′.\]

W konsekwencji, aby odzyskać nasze parametry, musimy rozwiązać równanie:

\[ \begin{bmatrix} i_1 \\ j_1 \\ i_2 \\ j_2 \\ i_3 \\ j_3 \\ i_4 \\ j_4 \end{bmatrix}= \begin{bmatrix} i'_1 & j'_1 & 1 & 0 & 0 & 0 & -i_1i'_1 & -i_1j_1'\\ 0 & 0 & 0 & i'_1 & j'_1 & 1 & -i_1i'_1 & -i_1j_1' \\ i'_2 & j'_2 & 1 & 0 & 0 & 0 & -i_2i'_2 & -i_2j_2' \\ 0 & 0  & 0 & i'_2 & j'_2 & 1 & -i_3i'_3 & -i_3j_3' \\ i'_3 & j'_3 & 1 & 0 & 0 & 0 & -i_3i'_3 & -i_3j_3' \\   0 & 0 & 0 & i'_3 & j'_3 & 1 & -i_4i'_4 & -i_4j_4' \\ i'_4 & j'_4 & 1 & 0 & 0 & 0 & -i_5i'_5 & -i_5j_5' \\   0 & 0 & 0 & i'_4 & j'_4 & 1  & -i_5i'_5 & -i_5j_5' \end{bmatrix} \begin{bmatrix} p_{00} \\ p_{01} \\ p_{02} \\ p_{10} \\ p_{11} \\ p_{12} \\ p_{20} \\ p_{21} \end{bmatrix} \]

  

Ilustracja. Efekt działania przekształcenia perspektywicznego.

 

Powyższy efekt można uzyskać za pomocą kodu w OpenCV (C++).