Przekrzywianie obrazu za pomocą przekształceń perspektywy

Staram się wykonać pochylenie na obrazie, jak ten pokazany tutaj

Http://i.msdn.microsoft.com/3b575a03.TransformedClimber%28en-us, VS. 90% 29. png .

Mam tablicę pikseli reprezentujących mój obraz i nie wiem, co z nimi zrobić.

Author: Jacob, 2010-03-15

3 answers

Znacznie lepszym sposobem na to jest odwrotne mapowanie.

Zasadniczo, chcesz "wypaczać" obraz, prawda? Co oznacza, że każdy piksel obrazu źródłowego trafia do predefiniowanego punktu - predefinicja jest macierzą transformacji, która mówi, jak obracać, skalować, tłumaczyć, ścinać itp. obraz, który zasadniczo przyjmuje pewną współrzędną (x,y) na Twoim obrazie i mówi: "Ok, nowa pozycja dla tego piksela to (f(x),g(y)).

To w zasadzie to, co "wypaczanie" tak.

Teraz pomyśl o skalowaniu obrazu ... powiedzmy, dziesięć razy większy. Oznacza to, że piksel w (1,1) staje się pikselem w (10,10) - a następnie następny piksel, (1,2) staje się pikselem (10,20) na nowym obrazie. Ale jeśli będziesz to robić, nie będziesz miał wartości dla piksela, (13,13) ponieważ {[7] } nie jest zdefiniowany w oryginalnym obrazie i będziesz miał kilka dziur w nowym obrazie - będziesz musiał interpolować dla tej wartości za pomocą czterech pikseli wokół niego w nowym obrazie obraz, tzn. (10,10) , (10,20), (20,10), (200,2) - nazywa się to interpolacją dwuliniową .

Ale jest jeszcze jeden problem, Załóżmy, że twoja transformacja nie była prostym skalowaniem i była affiniczna( jak przykładowy obraz, który opublikowałeś) - wtedy (1,1) stałaby się czymś w rodzaju (2.34,4.21), a następnie trzeba było zaokrąglić je w obrazie wyjściowym do (2,4) i wtedy trzeba było wykonać dwuliniową interpolację na nowym obrazie, aby wypełnić dziury lub bardziej skomplikowaną interpolację - niechlujny prawda?

Teraz, nie ma sposobu , aby wydostać się z interpolacji, ale możemy uciec od interpolacji dwuliniowej, tylko raz . Jak? Proste, odwrotne odwzorowanie.

Zamiast patrzeć na obraz źródłowy przechodzący do nowego obrazu, pomyśl, skąd będą pochodzić dane dla nowego obrazu w obrazie źródłowym! Tak więc, (1,1) w nowym obrazie będzie pochodzić z jakiegoś odwrotnego mapowania w obrazie źródłowym, powiedzmy, (3.4, 2.1), a następnie wykonaj dwuliniową interpolację na obrazie źródłowym, aby obliczyć z odpowiedniej wartości!

Macierz transformacji

Ok, więc jak zdefiniować macierz transformacji dla transformacji afinicznej? ta strona mówi ci, jak to zrobić, komponując różne macierze transformacji do obracania, ścinania itp.

Transformacje:

alt text

Skład:

alt text

Macierz końcową można uzyskać składając każdą macierz w kolejności i odwracając do uzyskaj odwrotne mapowanie-użyj tego, aby obliczyć pozycje pikseli w obrazie źródłowym i interpolować.

 52
Author: Jacob,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-08 14:22:37

Jeśli nie masz ochoty na ponowne wynalezienie koła, sprawdź bibliotekę OpenCV. Implementuje wiele przydatnych funkcji przetwarzania obrazu, w tym transformacji perspektywy. Sprawdź cvWarpPerspective , którego użyłem do wykonania tego zadania dość łatwo.

 3
Author: jeff7,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-15 16:36:37

Jak skomentował KennyTM, potrzebna jest transformata afiniczna, która jest odwzorowaniem liniowym otrzymanym przez pomnożenie każdego piksela przez macierz M i dodanie wyniku do wektora translacji V. To prosta matematyka

end_pixel_position = M*start_pixel_position + V

Gdzie M jest kompozycją prostych przekształceń, takich jak obroty lub skalowanie, a V jest wektorem, który tłumaczy każdy punkt obrazów dodając stałe współczynniki do każdego piksela.

Na przykład, jeśli chcesz obracanie obrazu można mieć macierz obrotu zdefiniowaną jako:

    | cos(a) -sin(a) |
M = |                |
    | sin(a)  cos(a) |

Gdzie a jest kątem, o który chcesz obrócić obraz.

Podczas skalowania używa się macierzy postaci:

    | s1   0 |
M = |        |
    | 0   s2 |

Gdzie s1 i s2 są współczynnikami skalowania na obu osiach.

Do tłumaczenia wystarczy wektor V :

    | t1 |
V = |    |
    | t2 |

, który dodaje t1 i t2 do współrzędnych piksela.

Następnie łączysz macierze w jedną transformację, na przykład, jeśli masz albo skalowanie, obrót i tłumaczenie skończysz mając coś takiego jak:

| x2 |             | x1 |
|    | = M1 * M2 * |    | + T
| y2 |             | y1 |

Gdzie:

  • x1 i {[11] } są współrzędnymi pikseli przed zastosowaniem transformacji,
  • x2 i y2 są pikselami po transformacji,
  • M1 i M2 to macierze używane do skalowania i obracania (pamiętaj: skład macierzy nie jest przemienny! Zwykle M1 * M2 * Vect != M2 * M1 * Vect),
  • T jest wektorem translacji używanym do tłumaczenia każdego pixel.
 2
Author: Jack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-15 14:28:58