Wpisany przez Andrzej Borucki,
24 lipca 2013 21:02
Morphing - płynne przechodzenie jednego obrazu w drugi. Zadaniem jest półautomatyczna transformacja jednego obrazu w drugi a zwłaszcza uzyskanie obrazów pośrednich dla pewnego λ z zakresu <0,1> co oznacza stopień zawartości drugiego obrazka w obrazie wynikowym. Na przykład dla λ = 0.4 obraz wynikowy składa się w 60% z pierwszego i 40% z drugiego obrazu. Nazywamy to interpolacją. Dla λ mniejszego niż zero lub większego niż jeden będziemy mieli do czynienia z ekstrapolacją obrazu.
Proces jest półautomatyczny, od użytkownika wymagane jest wyznaczenie punktów charakterystycznych na pierwszym obrazie i opowiadających im punktów na drugim obrazie. W najczęstszym przypadków będziemy mieli do czynienia ze zdjęciami twarzy więc takimi punktami mogą być kąciki ust, oczy itp. Jest to zadanie różne od dopasowania mapy do rastra, ponieważ tam mamy przekształcenie afiniczne i aproksymację, czyli najlepsze dopasowanie do punktów, niekoniecznie każdy punkt musi być dokładnie dopasowany, tutaj mamy interpolację.
Na obrazie wynikowym kolor punktu jest średnią kolorów na obu obrazach wejściowych w miejscach, które wynikają z rozkładu punktów charakterystycznych. Średni kolor to po prostu średnia składowych RGB; testy wykazały że dla innych modeli np. HSV były znacznie gorsze rezultaty niż dla RGB.
Użyty jest przypominający oddziaływanie grawitacji algorytm, w którym w dowolnym punkcie punkty charakterystyczne oddziaływają odwrotnie proporcjonalnie do kwadratu odległości. Zaletą jest to, że dla punktu będącego charakterystycznym, oddziaływanie od tego punktu charakterystycznego dąży do nieskończoności w porównaniu z wpływem innych punktów, tak że zależy od tylko od tego punkt charakterystycznego.
Pewną wadą jest to, że każdy punkt jest zależny od wszystkich punktów charakterystycznych, przez co złożoność to ilość pikseli * ilość punktów charakterystycznych, ma jednak to tę zaletę że mamy płynną zmianę na całym obszarze obrazka bez podziału na obszary.
Mamy dane punkty o współrzędnych xi, yi i kolorach Ri, Gi, Bi, wtedy punkt P o współrzędnych (x,y) ma kolor o składowych R,G,B wyliczonych ze wzoru:
di - odległość do i-tego punktu kontrolnego.
Podobnie obliczamy składowe kanałów G i B.
Przejdźmy teraz do opisu pełnego algorytmu. Mamy zadane punkty charakterystyczne pi o współrzędnych px,i, py,i na pierwszym obrazku i qx,i, qy,i na drugim. Wyliczamy punkty na obrazie docelowym: ti o współrzędnych tx,i, ty,i:
tx,i = (1 - λ) * px,i + λ * qx,i
ty,i = (1 - λ) * py,i + λ * qy,i
Dodatkowo wyliczamy odległości względne rpi i rqi będącą różnica między punktami pi i qi a punktami docelowymi ti
rpi = pi - ti
rqi = qi - ti,
dla obu współrzędnych.
Teraz dla każdego punktu t{x,y} obrazu docelowego należy znaleźć punkty p{x,y} i q{x,y} z których pobierzemy średnią koloru:
color = (1-λ)*colorA + λ*colorB
w następujący sposób:
di2 jest odległością punktu (x,y) na obrazie docelowym do i-tego punktu charakterystycznego na obrazie docelowym.
Generując obrazy dla kolejnych wartości λ możemy uzyskać "przemianę" jednego obiektu w drugi. Poniżej przykład dla kota i psa.
Animację można udoskonalić wprowadzając większą liczbę klatek (mniejsza zmiana λ między klatkami) oraz definiując większą liczbę punktów pośrednich.
Proces jest półautomatyczny, od użytkownika wymagane jest wyznaczenie punktów charakterystycznych na pierwszym obrazie i opowiadających im punktów na drugim obrazie. W najczęstszym przypadków będziemy mieli do czynienia ze zdjęciami twarzy więc takimi punktami mogą być kąciki ust, oczy itp. Jest to zadanie różne od dopasowania mapy do rastra, ponieważ tam mamy przekształcenie afiniczne i aproksymację, czyli najlepsze dopasowanie do punktów, niekoniecznie każdy punkt musi być dokładnie dopasowany, tutaj mamy interpolację.
Na obrazie wynikowym kolor punktu jest średnią kolorów na obu obrazach wejściowych w miejscach, które wynikają z rozkładu punktów charakterystycznych. Średni kolor to po prostu średnia składowych RGB; testy wykazały że dla innych modeli np. HSV były znacznie gorsze rezultaty niż dla RGB.
Użyty jest przypominający oddziaływanie grawitacji algorytm, w którym w dowolnym punkcie punkty charakterystyczne oddziaływają odwrotnie proporcjonalnie do kwadratu odległości. Zaletą jest to, że dla punktu będącego charakterystycznym, oddziaływanie od tego punktu charakterystycznego dąży do nieskończoności w porównaniu z wpływem innych punktów, tak że zależy od tylko od tego punkt charakterystycznego.
Pewną wadą jest to, że każdy punkt jest zależny od wszystkich punktów charakterystycznych, przez co złożoność to ilość pikseli * ilość punktów charakterystycznych, ma jednak to tę zaletę że mamy płynną zmianę na całym obszarze obrazka bez podziału na obszary.
Mamy dane punkty o współrzędnych xi, yi i kolorach Ri, Gi, Bi, wtedy punkt P o współrzędnych (x,y) ma kolor o składowych R,G,B wyliczonych ze wzoru:
R = \frac{\sum{\frac{R_i}{d_i^2}}}{\sum{\frac{1}{d_i^2}}}
gdzie:di - odległość do i-tego punktu kontrolnego.
Podobnie obliczamy składowe kanałów G i B.
Przejdźmy teraz do opisu pełnego algorytmu. Mamy zadane punkty charakterystyczne pi o współrzędnych px,i, py,i na pierwszym obrazku i qx,i, qy,i na drugim. Wyliczamy punkty na obrazie docelowym: ti o współrzędnych tx,i, ty,i:
tx,i = (1 - λ) * px,i + λ * qx,i
ty,i = (1 - λ) * py,i + λ * qy,i
Dodatkowo wyliczamy odległości względne rpi i rqi będącą różnica między punktami pi i qi a punktami docelowymi ti
rpi = pi - ti
rqi = qi - ti,
dla obu współrzędnych.
Teraz dla każdego punktu t{x,y} obrazu docelowego należy znaleźć punkty p{x,y} i q{x,y} z których pobierzemy średnią koloru:
color = (1-λ)*colorA + λ*colorB
w następujący sposób:
p_{x,y} = \frac{\sum{\frac{rp_i}{d_i^2}}}{\sum{\frac{1}{d_i^2}}} + t_{x,y}\\\\
q_{x,y} = \frac{\sum{\frac{rq_i}{d_i^2}}}{\sum{\frac{1}{d_i^2}}} + t_{x,y}
gdzie:di2 jest odległością punktu (x,y) na obrazie docelowym do i-tego punktu charakterystycznego na obrazie docelowym.
Generując obrazy dla kolejnych wartości λ możemy uzyskać "przemianę" jednego obiektu w drugi. Poniżej przykład dla kota i psa.
Animację można udoskonalić wprowadzając większą liczbę klatek (mniejsza zmiana λ między klatkami) oraz definiując większą liczbę punktów pośrednich.
Implementacje
Autor | Język programowania | Komentarz | Otwórz | Pobierz | Ocena |
Andrzej Borucki | Delphi/Pascal | Lazarus + Graphics32 | .pas | .pas | ***** / 0 |
Andrzej Borucki | Delphi/Pascal | Borland Delphi 7 | .pas | .pas | ***** / 2 |
Poprawiony: 25 lipca 2013 17:40
1. Założyć stały kolor dla wartości spoza obrazu (np. czarny albo biały).
2. Pobrać wartości z krawędzi obrazu, tzn w przypadku obrazu 400x400 prawidłowe wartości indeksów to 0..399 czyli dla punktu (402, 302) użyć koloru z punktu (399, 302), dla punktu (235, -24) użyć kolor z punktu (235, 0).