Ciekawe fotomontaże wykorzystujące równanie Poissona

Sławomir Krysztowiak

2011-10-23

Bezpośrednią inspiracją do powstania poniżej opisywanego programu było zdjęcie, które podesłał mi Xed, ukazujące mnie w miejscu, w którym nigdy nie byłem. Okazało się, że to fotomontaż, choć przyznam, że nieuzbrojonym okiem wcale nie było tego widać. Sposób, w jaki ów fotomontaż powstał został opisany przez P. Pereza, M. Gangneta i A. Blake'a w publikacji pt. "Poisson Image Editing". Postanowiłem samemu zaimplementować ich algorytm i zobaczyć, cóż on wart.

Co chcemy osiągnąć, mówiąc bez zbędnego formalizmu? Dane mamy dwa obrazy. Chcemy zaznaczyć obszar obrazu źródłowego i wkleić go w wybrane miejsce obszaru docelowego w taki sposób, aby nie było widać śladu ingerencji. Przykład dla zachęty? Proszę bardzo, krokodyl pływający w kanale w Wenecji:

Krokodyl

Reakcja kolegi na widok tego zdjęcia: "O w mordę, z zoo im uciekł?".

A teraz ciut bardziej formalnie, acz wciąż gawędziarsko. Niech f(x, y) oznacza obraz źródłowy, a g(x, y) obraz docelowy. Określamy obszar A na obrazie docelowym. Szukamy takiej funkcji g' określonej na A, która spełnia następujące warunki:

  • g(x, y) = g'(x,y) dla (x,y) należących do brzegu A
  • g' interpoluje funkcję g używając pola wektorowego v jako pola–przewodnika (guidance field)

Pole wektorowe v zostaje w odpowiedni sposób wyznaczone z f. Aby wyznaczyć wartości g' należy rozwiązać dyskretną wersję problemu Poissona z warunkiem brzegowym Dirichleta. Sprowadza się to do układu n równań liniowych o n niewiadomych, gdzie n jest liczbą pikseli w A. W praktyce oznacza to ni mniej ni więcej tylko tyle, że nie warto w ogóle zabierać się za rozwiązywanie tego układu standardową metodą eliminacji Gaussa, bo dla średniej wielkości obrazu obliczenia trwałyby wieki. W mej implementacji użyłem zatem metody iteracyjnej Gaussa–Seidla, dzięki czemu nie muszę wystawiać swej cierpliwości na ciężkie próby.

Tym, którzy łakną więcej teorii, proponuję lekturę oryginalnej publikacji. Oprócz samego opisu zawiera ona przykładowe wyniki działania, co najmniej tak interesujące jak mój krokodyl.

Co też możemy uzyskać przy użyciu metody? Zacznijmy od wstawiania obiektów. Poniżej widać główne okno programu. Po lewej stronie znajduje się obraz źródłowy, a po prawej docelowy. Na żółto zaznaczony jest obszar podlegający działaniu. Wybieramy miejsce wklejenia na obrazie docelowym – widać, że zaznaczony fragment nie pasuje do obrazu po prawej stronie, różnice w intensywności kolorów są znaczne.

Okno

A tak wygląda obraz wynikowy, po wykonaniu algorytmu:

Obeliks

Tak jak możemy obiekty dodawać, tak samo możemy je usuwać, tzn. przykrywać innymi. Dla zilustrowania rozważmy zdjęcie gołębi żyjących w malborskim murze:

Gołębie

Możemy je zamienić w kamienie:

Kamienie

Zajrzyjmy teraz na Plac Świętego Piotra. Oto zdjęcie oryginalne:

Plac św. Piotra

Trudno wyczekać moment, w którym w zasięgu obiektywu nie znajdą się przypadkowi turyści. Ale od czego mamy program, dalej, usuńmy ich!

Plac św. Piotra bez ludzi

Jak widać, łatwo uzyskać przyzwoite efekty, jednak jeszcze łatwiej otrzymać mizerne. Jeśli próbujemy wklejać obiekt zupełnie nie pasujący do obrazu docelowego, to na cuda nie mamy co liczyć. Źle to będzie wyglądać i kropka.

Szczególnie ważne dla końcowego rezultatu są piksele znajdujące się na brzegu wklejanego obszaru. Pamiętajmy, że interpolujemy funkcję obrazu docelowego, a obraz źródłowy służy "tylko" do wyznaczenia wektora–przewodnika! Z tej przyczyny często zdarza się, że wstawiany obiekt nabiera dziwnych kolorów. Krokodyl w kanale wyglądał dobrze, bo zarówno na obrazie źródłowym, jak i docelowym mieliśmy wokół wodę o podobnej kolorystyce. Ale próba wklejenia kota na chodnik w Wenecji sprawiła, że ten wypłowiał:

Ramzes
Ramzes w Wenecji

Podobny efekt dotknął hipopotama skąpanego w fontannie di Trevi:

Hipopotam – zdjęcie, którego źródła nie mogę ustalić
Hipopotam w fontannie

Podsumowując – fajna i bardzo uzależniająca zabawa, ale, jak to zwykle bywa, "bez pracy nie ma kołaczy". Żeby uzyskać naprawdę interesujący wynik, trzeba mieć i dobry pomysł, i zmysł artystyczny, którego mi ewidentnie brakuje.

Jest i drugi algorytm, który robi to samo, ale podobno daje lepsze efekty. Jak znajdę chwilę to i go sprawdzę.

Może zainteresuje Cię: