- 1. Transformacje obrazu - transformacja afiniczna i nie-afiniczna
- 2. Tłumaczenia obrazów - przesuwanie obrazu w górę, w dół, w lewo iw prawo
- 3. Obrót obrazu - Obracanie obrazu
- 4. Skalowanie, zmiana rozmiaru i interpolacja
- 5. Piramidy obrazu - inny sposób zmiany rozmiaru
- 6. Przycinanie - wycinanie wybranego obszaru obrazu
- 7. Operacje arytmetyczne rozjaśniania i przyciemniania obrazów
W poprzednim samouczku dowiedzieliśmy się o OpenCV i wykonaliśmy podstawowe przetwarzanie obrazu, używając go, jak skalowanie szarości, nasycenie kolorów, histogram, przestrzenie kolorów, komponent RGB itp. Jak powiedziano w poprzednim samouczku, OpenCV jest Open Source Commuter Vision Library, która ma Interfejsy C ++, Python i Java i obsługuje systemy Windows, Linux, Mac OS, iOS i Android. Dzięki temu można go łatwo zainstalować w Raspberry Pi w środowisku Python i Linux. Raspberry Pi z OpenCV i dołączoną kamerą może być używany do tworzenia wielu aplikacji do przetwarzania obrazu w czasie rzeczywistym, takich jak wykrywanie twarzy, blokowanie twarzy, śledzenie obiektów, wykrywanie tablic rejestracyjnych samochodów, system bezpieczeństwa w domu itp.
W tym samouczku zobaczymy, jak będziemy manipulować obrazem za pomocą OpenCV. Tutaj nauczymy się stosować następującą funkcję na obrazie za pomocą OpenCV:
- Transformacje obrazu - transformacja afiniczna i nie-afiniczna
- Tłumaczenia obrazów - przesuwanie obrazu w górę, w dół, w lewo iw prawo
- Obrót obrazu - Obracanie obrazu
- Skalowanie, zmiana rozmiaru i interpolacja
- Piramidy obrazu - inny sposób zmiany rozmiaru
- Kadrowanie - wycinanie wybranego obszaru obrazu
- Operacje arytmetyczne dla rozjaśniania i przyciemniania obrazów
1. Transformacje obrazu - transformacja afiniczna i nie-afiniczna
Transformacje są zniekształceniami geometrycznymi wprowadzanymi na obrazie, zniekształcenia z pewnością nie oznaczają tutaj błędów, ale typ korekty mający na celu skorygowanie problemów perspektywicznych wynikających z miejsca, w którym obraz został uchwycony. Istnieją dwa typy transformacji obrazu - afiniczne i nie-afiniczne
Transformacje afiniczne dzielą się na trzy rodzaje: skalowanie, rotacja i translacja. Ważną rzeczą w transformacjach afinicznych jest to, że linie są równoległe przed i po transformacji obrazu.
Transformacje inne niż afiniczne lub transformacje rzutowe nie zachowują równoległości, długości ani kąta, zachowują jednak kolinearność i incydencję, kolinearność oznacza, że dwa punkty leżą na tej samej prostej.
Transformacje inne niż afiniczne są bardzo powszechne w wizji komputerowej i są generowane z różnych kątów widzenia kamery. Transformacje nieafiniczne lub projekcyjne są również nazywane homografią.
2. Tłumaczenia obrazów - przesuwanie obrazu w górę, w dół, w lewo iw prawo
Tłumaczenie obrazu to przesuwanie obrazu w górę, w dół, w lewo iw prawo, a nawet po przekątnej, jeśli zaimplementujemy tłumaczenie xiy w tym samym czasie.
Teraz do wykonywania tłumaczeń obrazów używamy funkcji warpAffine opencv, do implementacji tych tłumaczeń używana jest cv2.warpAffine , ale do tego potrzebujemy macierzy translacji.
Macierz tłumaczeń, T = 1 0 Tx
0 1 ty
T X, T y to kierunki, w których następuje przesunięcie obrazu.
Gdzie T X jest przesunięty wzdłuż osi X (poziomej)
T Y przesuwa się wzdłuż osi Y (w pionie)
# to jest transformacja afiniczna, która po prostu przesuwa pozycję obrazu # używamy cv2.warpAffine do implementacji tych transformacji. import cv2 import numpy as np image = cv2.imread ('input.jpg') # zapisz wysokość i szerokość obrazu wysokość, width = image.shape print (image.shape) quater_height, quater_width = height / 4, width / 4 T = np.float32 (,]) img_translation = cv2.warpAffine (image, T, (width, height)) print (T) cv2.imshow ('original_image', image) cv2.waitKey (0) cv2.imshow (' Tłumaczenie ', img_translation) cv2.waitKey (0) cv2.destroyAllWindows ()
Wyjście konsoli - (183, 275) - wysokość i szerokość
- macierz T.
]
3. Obrót obrazu - Obracanie obrazu
Obrót obrazu to obrót obrazu wokół punktu lub punktu w środku obrazu, tak jak punkt obrotu działa jak oś.
Jak w translacji mamy macierz T, prawdopodobnie w rotacji mamy macierz M.
Macierz rotacji, macierz M = Cosθ -Sinθ
Sinθ Cosθ
Gdzie θ jest kątem obrotu mierzonym w kierunku przeciwnym do ruchu wskazówek zegara.
Należy również zauważyć, że OpenCV umożliwia sprzedaż i obracanie obrazu w tym samym czasie za pomocą funkcji cv2.getRotationMatrix2D (Rotation_center_x , Rotation_center_y, kąt obrotu, skala)
Nadal używamy funkcji warpAffine opencv, aby uzyskać obrót obrazu, ale zamiast macierzy translacji, jak w poprzednim przypadku, używamy macierzy rotacji.
import cv2 import numpy as np image = cv2.imread ('input.jpg') height, width = image.shape # podziel wysokość i szerokość o 2, aby obrócić obraz wokół jego środka rotation_matrix = cv2.getRotationMatrix2D ((width / 2, wysokość / 2), 90,1) rotated_image = cv2.warpAffine (obraz, macierz_obrotu, (szerokość, wysokość)) cv2.imshow ('oryginalny obraz', obraz) cv2.waitKey (0) cv2.imshow ('obrócony obraz ', rotated_image) cv2.waitKey (0) cv2.destroyAllWindows ()
Teraz obraz jest obrócony o 90 stopni, jest przycinany ze względu na rozmiar płótna, ponieważ rozmiar płótna pozostaje taki sam, ale ze względu na obrót rozmiar obrazu nie pasuje do rozmiaru płótna. Można to zmienić, ustawiając współczynnik skalowania na wartość ujemną, ale pozwala to na czarne tło za obrazem.
Możesz więc ustawić wysokość i szerokość obrazu, przewidując go lub zgadując, lub istnieje inna metoda obracania obrazu polega na transpozycji, ale obraca obraz o wielokrotności 90 stopni w kierunku przeciwnym do ruchu wskazówek zegara.
4. Skalowanie, zmiana rozmiaru i interpolacja
Skalowanie i zmiana rozmiaru to transformacje afiniczne, zmiana rozmiaru obrazu jest tym, co robiliśmy już od dłuższego czasu, a także zajmowaliśmy się interpolacją, na przykład podczas zmiany rozmiaru obrazu do większego rozmiaru, w którym powiększamy piksele, są pewne luki w pikseli i tu właśnie pojawia się interpolacja.
Może się to zdarzyć przy zwiększaniu rozmiaru obrazu z mniejszego na większy lub zmniejszaniu rozmiaru obrazu z większego na mniejszy.
Z technicznego punktu widzenia interpolacja jest metodą konstruowania nowych punktów danych (pikseli) w ramach dyskretnego zestawu znanych punktów danych.
W OpenCV istnieje wiele rodzajów metod interpolacji, takich jak
cv2.INTER_AREA - dobre do zmniejszania lub zmniejszania próbkowania
cv2.INTER_NEAREST - najszybszy
cv2.LINEAR - dobry do powiększania lub próbkowania w górę (domyślnie)
cv2.CUBIC - lepiej
cv2.INTER_LANCZOS4 - najlepiej
# zmiana rozmiaru jest bardzo łatwa dzięki funkcji cv2.resize, jej argumentami są # cv2.resize (obraz, dsize (rozmiar obrazu wyjściowego), x_scale, y_scale, interpolacja) import cv2 import numpy as np image = cv2.imread ('input. jpg ') cv2.imshow (' Original_image ', image) cv2.waitKey (0) # sprawmy , aby obraz był 3/4 oryginalnego rozmiaru obrazu, tj. skaluje się w dół do 75% image_scaled = cv2.resize (image, None, fx = 0,75, fy = 0,75) # Ponieważ interpolacja liniowa jest domyślną metodą dla otwartego cv, nie musimy jej implementować jako funkcji. cv2.imshow ('scaling_linear interpolation', image_scaled) cv2.waitKey (0) # podwojmy rozmiar naszego obrazu img_double = cv2.resize (image, None, fx = 2, fy = 2, interpolation = cv2.INTER_CUBIC) cv2.imshow ('scaing_cubicInterpolation', img_double) cv2.waitKey (0) # zmieńmy rozmiar według dokładnych wymiarów image_resize = cv2.resize (image, (200,300), interpolation = cv2.INTER_AREA) cv2.imshow (', scaling_exact (', scaling_exact) image_resize) cv2.waitKey (0) cv2.destroyAllWindows ()
5. Piramidy obrazu - inny sposób zmiany rozmiaru
Piramidowanie obrazu odnosi się do skalowania w górę (powiększanie obrazów) lub zmniejszania (zmniejszanie obrazów).
Jest to po prostu inny sposób zmiany rozmiaru, który pozwala nam łatwo i szybko skalować obrazy, zmniejszając wysokość i szerokość nowego obrazu o połowę.
Jest to przydatne podczas tworzenia detektorów obiektów, które skalują obrazy za każdym razem, gdy szuka obiektu.
import cv2 image = cv2.imread ('input.jpg') mniejsze = cv2.pyrDown (obraz) większe = cv2.pyrUp (mniejsze) cv2.imshow ('oryginał', obraz) cv2.waitKey (0) cv2.imshow ('mniejsze', mniejsze) cv2.waitKey (0) cv2.imshow ('większe', większe) cv2.waitKey (0) cv2.destroyAllWindows ()
Na większym obrazie zauważysz, że wciąż ten sam rozmiar oryginalnego obrazu jest trochę rozmazany, ponieważ jest bezpośrednio konwertowany z mniejszego obrazu na większy. Ale jeśli ją interpolujemy, jakość obrazu poprawia się w porównaniu z poprzednim, ponieważ interpolacja szacuje piksele podczas wypełniania przestrzeni, gdy obraz jest powiększany.
Uruchomienie tego samego kodu, ale z interpolacją sześcienną, daje lepszą jakość dużego obrazu. Poniższe obrazy pokazują porównanie między oryginalnym obrazem, przeskalowaną w górę wersją obrazu, mniejszym obrazem i sześcienną interpolowaną wersją mniejszego obrazu.
import cv2 image = cv2.imread ('input.jpg') mniejsze = cv2.pyrDown (obraz) większe = cv2.pyrUp (mniejsze) cv2.imshow ('oryginał', obraz) cv2.waitKey (0) cv2.imshow ('mniejsze', mniejsze) cv2.waitKey (0) cv2.imshow ('większe', większe) cv2.waitKey (0) # zwiększanie jakości konwertowanego większego obrazu z mniejszego obrazu za pomocą interpolacji sześciennej img_double = cv2.resize (mniejsze, Brak, fx = 2, fy = 2, interpolation = cv2.INTER_CUBIC) cv2.imshow ('scaing_cubicInterpolation', img_double) cv2.waitKey (0) cv2.destroyAllWindows ()
UWAGA: Jeśli chcesz utworzyć wiele małych kopie obrazów będzie mniejszy i mniejszy lub wielu dużych kopii obrazów nieustannie powiększa się, a następnie możemy wykorzystać do pętli lub podczas pętle utrzymując wewnątrz pyrDown lub pyrUp funkcji.
6. Przycinanie - wycinanie wybranego obszaru obrazu
Kadrowanie obrazów odnosi się do wyodrębniania fragmentu obrazu.
OpenCV bezpośrednio nie ma funkcji przycinania, ale można to łatwo zrobić za pomocą numpy, używając poniższego kodu
Przycięte = obraz
Umieszczamy tablicę obrazu i używając narzędzi lub metody indeksowania w numpy, definiujemy wiersz od początku do końca wiersza i od kolumny do końca kolumny oddzielone przecinkiem, który wyodrębnia prostokąt, który chcemy przyciąć, aby uzyskać obraz.
import cv2 import numpy as np image = cv2.imread ('input.jpg') height, width = image.shape # pobierzmy początkowe współrzędne pikseli (lewy górny róg kadrowania) start_row, start_col = int (height *.25), int (width *.25) # uzyskajmy końcowe współrzędne piksela (na dole po prawej) end_row, end_col = int (height *.75), int (width *.75) # po prostu użyj indeksowania, aby wyciąć prostokąt, który chcemy przyciąć = image cv2.imshow ("oryginalny obraz", obraz) cv2.waitKey (0) cv2.imshow ("przycięty obraz", przycięty) cv2.waitKey (0) cv2.destroyAllWindows ()
Zauważ, że możesz użyć wartości pikseli bezpośrednio zamiast start_col lub start_row , są one podawane tylko w celu łatwej identyfikacji użytkownika.
7. Operacje arytmetyczne rozjaśniania i przyciemniania obrazów
Operacje arytmetyczne w OpenCV zasadniczo polegają na dodawaniu lub odejmowaniu macierzy do obrazu, dodawanie lub odejmowanie macierzy ma wpływ na zwiększanie lub zmniejszanie jasności.
Aby więc dodawać lub odejmować macierze, musimy je utworzyć, a numpy ma funkcję o nazwie np.ones, która daje matryce o rozmiarze 1 co nasz obraz.
import cv2 import numpy as np image = cv2.imread ('input.jpg') # utwórz swoją macierz, a następnie pomnóż ją przez skaler 100 ' # np.ones daje macierz o takich samych wymiarach jak nasz obraz ze wszystkimi wartości to 100 w tym przypadku M = np.ones (image.shape, dtype = "uint8") * 100 # używamy tego do dodania tej macierzy M do naszego obrazu # zauważmy wzrost jasności dodany = cv2.add (obraz, M) cv2.imshow ("Dodane", dodane) cv2.waitKey (0) # podobnie możemy również odjąć # zauważyć spadek jasności odjęty = cv2.subtract (image, M) cv2.imshow ("odejmowany", odejmowany) cv2.waitKey (0) cv2.destroyAllWindows ()
W ten sposób można wykorzystać OpenCV do zastosowania wielu różnych operacji przetwarzania obrazu na obrazie. W następnym samouczku będziemy kontynuować inne funkcje obróbki obrazu.