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ć.
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:
Skład:
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ć.
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.
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
iy2
są pikselami po transformacji, -
M1
iM2
to macierze używane do skalowania i obracania (pamiętaj: skład macierzy nie jest przemienny! ZwykleM1 * M2 * Vect != M2 * M1 * Vect
), -
T
jest wektorem translacji używanym do tłumaczenia każdego pixel.
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