- 1. Segmentacja i kontury
- 2. Hierarchia i tryb pobierania
- 3. Przybliżanie konturów i znajdowanie ich wypukłego kadłuba
- 4. Wypukły kadłub
- 5. Dopasowywanie konturu według kształtów
- 6. Rozpoznawanie kształtów (koło, prostokąt, trójkąt, kwadrat, gwiazda)
- 7. Wykrywanie linii
- 8. Wykrywanie plamek
- 9. Filtrowanie blobów - liczenie okręgów i elips
W poprzednich samouczkach używaliśmy OpenCV do podstawowego przetwarzania obrazu i wykonaliśmy kilka zaawansowanych operacji edycji obrazu. Jak wiemy, OpenCV to 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żywane 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 dowiemy się, jak to zrobić segmentacja obrazu za pomocą OpenCV. Poniżej wymieniono operacje, które zamierzamy wykonać:
- Segmentacja i kontury
- Hierarchia i tryb pobierania
- Przybliżenie konturów i znalezienie ich wypukłego kadłuba
- Conex Hull
- Dopasowany kontur
- Rozpoznawanie kształtów (koło, prostokąt, trójkąt, kwadrat, gwiazda)
- Wykrywanie linii
- Wykrywanie plamek
- Filtrowanie plamek - liczenie okręgów i elips
1. Segmentacja i kontury
Segmentacja obrazów to proces, w którym dzielimy obrazy na różne regiony. Natomiast kontury to ciągłe linie lub krzywe, które ograniczają lub pokrywają pełną granicę obiektu na obrazie. Tutaj użyjemy techniki segmentacji obrazu zwanej konturami, aby wyodrębnić części obrazu.
Również kontury są bardzo ważne w programie
- Wykrywanie obiektów
- Analiza kształtu
Mają bardzo szeroki zakres zastosowań, od analizy obrazu w świecie rzeczywistym do analizy obrazów medycznych, takich jak MRI
Dowiedzmy się, jak zaimplementować kontury w opencv, wyodrębniając kontury kwadratów.
import cv2 import numpy jako np
Załadujmy prosty obraz z 3 czarnymi kwadratami
image = cv2.imread ('squares.jpg') cv2.imshow ('obraz wejściowy', obraz) cv2.waitKey (0)
Skala szarości
gray = cv2.cvtColor (obraz, cv2.COLOR_BGR2GRAY)
Znajdź sprytne krawędzie
edged = cv2.Canny (szary, 30,200 ) cv2.imshow ('sprytne krawędzie', krawędzie) cv2.waitKey (0)
Znajdowanie konturów
# użyj kopii swojego obrazu, np. - edged.copy (), ponieważ znalezienie konturów zmienia obraz # musimy dodać _, przed konturami jako pusty argument z powodu aktualizacji wersji OpenCV _, contours, hierarchy = cv2.findContours (edged, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) cv2.imshow ('sprytne krawędzie po konturowaniu', z krawędziami) cv2.waitKey (0)
Drukowanie pliku konturu, aby wiedzieć, z czego składają się kontury
print (kontury) print ('Liczba znalezionych konturów =' + str (len (kontury)))
Narysuj wszystkie kontury
# użyj -1 jako trzeciego parametru, aby narysować wszystkie kontury cv2.drawContours (image, contours, -1, (0,255,0), 3) cv2.imshow ('contours', image) cv2.waitKey (0) cv2. zniszczAllWindows ()
Wyjście konsoli -],],], …,],],]], dtype = int32), szyk(],],
], …,
],],]], dtype = int32), tablica (],],], …,],],]], dtype = int32)]
Liczba znalezionych konturów = 3. Więc znaleźliśmy w sumie trzy kontury.
Teraz, w powyższym kodzie, również wydrukowaliśmy plik konturu przy użyciu , ten plik mówi, jak wyglądają te kontury, jak wydrukowano w powyższym wyjściu konsoli.
Na powyższym wyjściu konsoli mamy macierz, która wygląda jak współrzędne punktów x, y. OpenCV przechowuje kontury w postaci list. Możemy po prostu pokazać powyższe dane wyjściowe konsoli w następujący sposób:
CONTOUR 1 CONTOUR 2 CONTOUR 3
], tablica (], tablica (],],],],],],],
…,…,…,],],],],],],]], dtype = int32),]], dtype = int32),]], dtype = int32)]
Teraz, kiedy używamy funkcji length na pliku konturu, otrzymujemy długość równą 3, co oznacza, że w tym pliku były trzy listy list, czyli trzy kontury.
Teraz wyobraź sobie, że CONTOUR 1 jest pierwszym elementem w tej tablicy, a lista zawiera listę wszystkich współrzędnych, a te współrzędne są punktami wzdłuż konturów, które właśnie widzieliśmy, jako zielone prostokątne prostokąty.
Istnieją różne metody przechowywania tych współrzędnych i są one nazywane metodami aproksymacji, zasadniczo metody aproksymacji są dwojakiego rodzaju
- cv2.CHAIN_APPROX_NONE
- cv2.CHAIN_APPROX_SIMPLE
cv2.CHAIN_APPROX_NONE przechowuje wszystkie punkty graniczne, ale niekoniecznie potrzebujemy wszystkich punktów granicznych, jeśli punkt tworzy linię prostą, potrzebujemy tylko punktu początkowego i końcowego na tej linii.
cv2.CHAIN_APPROX_SIMPLE zamiast tego zapewnia tylko punkt początkowy i końcowy konturów ograniczających, w wyniku czego jest znacznie bardziej wydajne przechowywanie informacji o konturach.
_, kontury, hierarchia = cv2.findContours (z krawędziami, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
W powyższym kodzie cv2.RETR_EXTERNAL jest trybem pobierania, podczas gdy cv2.CHAIN_APPROX_NONE jest
metoda aproksymacji.
Więc nauczyliśmy się o konturach i metodzie aproksymacji, teraz zbadajmy hierarchię i tryb wyszukiwania.
2. Hierarchia i tryb pobierania
Tryb wyszukiwania definiuje hierarchię konturów, takich jak kontury podrzędne, kontur zewnętrzny lub wszystkie kontury.
Teraz są cztery tryby pobierania posortowane według typów hierarchii.
cv2.RETR_LIST - pobiera wszystkie kontury.
cv2.RETR_EXTERNAL - pobiera tylko kontury zewnętrzne lub zewnętrzne.
cv2.RETR_CCOMP - pobiera wszystko w 2-poziomowej hierarchii.
cv2.RETR_TREE - pobiera wszystko w pełnej hierarchii.
Hierarchia jest przechowywana w następującym formacie
Teraz zilustrujmy różnicę między pierwszymi dwoma trybami pobierania, cv2.RETR_LIST i cv2.RETR_EXTERNAL.
import cv2 import numpy jako np
Załadujmy prosty obraz z 3 czarnymi kwadratami
image = cv2.imread ('kwadratowy pączek.jpg') cv2.imshow ('obraz wejściowy', obraz) cv2.waitKey (0)
Skala szarości
gray = cv2.cvtColor (obraz, cv2.COLOR_BGR2GRAY)
Znajdź Canny Edges
edged = cv2.Canny (szary, 30,200 ) cv2.imshow ('sprytne krawędzie', krawędzie) cv2.waitKey (0)
Znajdowanie konturów
# użyj kopii swojego obrazu, np. - edged.copy (), ponieważ znalezienie konturów zmienia obraz # musimy dodać _, przed konturami jako pusty argument z powodu aktualizacji otwartej wersji cv _, kontury, hierarchia = cv2.findContours (krawędziowe, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE) cv2.imshow ('sprytne krawędzie po konturowaniu', z krawędziami) cv2.waitKey (0)
Drukowanie pliku konturu, aby wiedzieć, z czego składają się kontury.
print (kontury) print ('Liczba znalezionych konturów =' + str (len (kontury)))
Narysuj wszystkie kontury
# użyj -1 jako trzeciego parametru, aby narysować wszystkie kontury cv2.drawContours (image, contours, -1, (0,255,0), 3) cv2.imshow ('contours', image) cv2.waitKey (0) cv2. zniszczAllWindows
import cv2 import numpy jako np
Załadujmy prosty obraz z 3 czarnymi kwadratami
image = cv2.imread ('kwadratowy pączek.jpg') cv2.imshow ('obraz wejściowy', obraz) cv2.waitKey (0)
Skala szarości
gray = cv2.cvtColor (obraz, cv2.COLOR_BGR2GRAY)
Znajdź sprytne krawędzie
edged = cv2.Canny (szary, 30,200 ) cv2.imshow ('sprytne krawędzie', krawędzie) cv2.waitKey (0)
Znajdowanie konturów
# użyj kopii swojego obrazu, np. - edged.copy (), ponieważ znalezienie konturów zmienia obraz # musimy dodać _, przed konturami jako pusty argument z powodu aktualizacji otwartej wersji cv _, kontury, hierarchia = cv2.findContours (edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE) cv2.imshow ('sprytne krawędzie po konturowaniu', z krawędziami) cv2.waitKey (0)
Drukowanie pliku konturu, aby wiedzieć, z czego składają się kontury.
print (kontury) print ('Liczba znalezionych konturów =' + str (len (kontury)))
Narysuj wszystkie kontury
# użyj -1 jako trzeciego parametru, aby narysować wszystkie kontury cv2.drawContours (image, contours, -1, (0,255,0), 3) cv2.imshow ('contours', image) cv2.waitKey (0) cv2. zniszczAllWindows ()
Tak więc poprzez demonstrację powyższych kodów mogliśmy wyraźnie zobaczyć różnicę między cv2.RETR_LIST i cv2.RETR_EXTERNNAL , w cv2.RETR_EXTERNNAL brane są pod uwagę tylko zewnętrzne kontury, podczas gdy wewnętrzne kontury są ignorowane.
Podczas gdy w cv2.RETR_LIST są również brane pod uwagę kontury wewnętrzne.
3. Przybliżanie konturów i znajdowanie ich wypukłego kadłuba
W przypadku konturów przybliżanych, kształt konturu jest aproksymowany na inny kształt konturu, który może nie być zbyt podobny do kształtu pierwszego konturu.
Dla zbliżenia używamy approxPolyDP funkcję OpenCV, który jest opisany poniżej
cv2.approxPolyDP (kontur, dokładność aproksymacji, zamknięty)
Parametry:
- Kontur - to indywidualny kontur, który chcemy przybliżać.
- Dokładność aproksymacji - ważny parametr przy określaniu dokładności aproksymacji, mała wartość daje dokładne przybliżenie, duże wartości dają bardziej ogólne informacje. Dobra reguła kciuka to mniej niż 5% obwodu konturu.
- Zamknięty - wartość logiczna określająca, czy przybliżony kontur może być otwarty, czy zamknięty.
Spróbujmy przybliżyć prostą figurę domu
import numpy jako np import cv2
Załaduj obraz i zachowaj kopię
image = cv2.imread ('house.jpg') orig_image = image.copy () cv2.imshow ('oryginalny obraz', orig_image) cv2.waitKey (0)
Skala szarości i binaryzacja obrazu
gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold (gray, 127,255, cv2.THRESH_BINARY_INV)
Znajdź kontury
_, kontury, hierarchia = cv2.findContours (thresh.copy (), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
Przejdź przez każdy kontur i oblicz ich prostokąt ograniczający
dla c w konturach: x, y, w, h = cv2.boundingRect (c) cv2.rectangle (orig_image, (x, y), (x + w, y + h), (0,0,255), 2) cv2.imshow ('Bounding rect', orig_image) cv2.waitKey (0)
Przejdź przez każdy kontur i oblicz przybliżony kontur
dla c w konturach:
# obliczyć dokładność jako procent dokładności obwodu konturu = 0,03 * cv2.arcLength (c, True) w przybliżeniu = cv2.approxPolyDP (c, dokładność, True) cv2.drawContours (image,, 0, (0,255,0), 2) cv2.imshow ('W przybliżeniu polyDP', obraz) cv2.waitKey (0) cv2.destroyAllWindows ()
4. Wypukły kadłub
Kadłub wypukły to w zasadzie zewnętrzne krawędzie, reprezentowane przez rysowanie linii na danej figurze.
Może to być najmniejszy wielokąt, który może zmieścić się wokół samego obiektu.
import cv2 import numpy as np image = cv2.imread ('star.jpg') gray = cv2.cvtColor (obraz, cv2.COLOR_BGR2GRAY) cv2.imshow ('oryginalny obraz', obraz) cv2.waitKey (0)
Ustaw próg obrazu
ret, thresh = cv2.threshold (gray, 176,255,0)
Znajdź kontury
_, kontury, hierarchia = cv2.findContours (thresh.copy (), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
Posortuj kontury według obszaru, a następnie usuń największy kontur ramy
n = len (kontury) -1 kontury = posortowane (kontury, klucz = cv2.contourArea, odwrócone = fałszywe)
Powtarzaj kontury i narysuj wypukły kadłub
dla c w konturach:
hull = cv2.convexHull (c) cv2.drawContours (image,, 0, (0,255,0), 2) cv2.imshow ('convex hull', image) cv2.waitKey (0) cv2.destroyAllWindows ()
5. Dopasowywanie konturu według kształtów
cv2.matchShapes (szablon konturu, metoda konturu, parametr metody)
Wynik - dopasowana wartość (niższa wartość oznacza bliższe dopasowanie)
szablon konturu - To jest nasz kontur odniesienia, który próbujemy znaleźć na nowym obrazku.
kontur - indywidualny kontur, z którym sprawdzamy.
Metoda - rodzaj dopasowania konturu (1, 2, 3).
parametr metody - pozostaw bez zmian jako 0.0 (nieużywane w opencv Pythona)
import cv2 import numpy jako np
Załaduj szablon kształtu lub obraz referencyjny
template = cv2.imread ('star.jpg', 0) cv2.imshow ('template', template) cv2.waitKey (0)
Załaduj docelowy obraz kształtami, które próbujemy dopasować
target = cv2.imread ('shapestomatch.jpg') gray = cv2.cvtColor (target, cv2.COLOR_BGR2GRAY)
Przed użyciem cv2.findContours należy najpierw określić próg dla obu obrazów
ret, thresh1 = cv2.threshold (template, 127,255,0) ret, thresh2 = cv2.threshold (gray, 127,255,0)
Znajdź kontury w szablonie
_, kontury, hierarhy = cv2.findContours (thresh1, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) # musimy posortować kontury według obszaru, abyśmy mogli usunąć największy kontur, który jest
Zarys obrazu
sort_contours = sortowane (kontury, klucz = cv2.contourArea, reverse = True) # wyodrębniamy drugi co do wielkości kontur, którym będzie nasz szablon kontur tempelate_contour = kontury # wyodrębnij kontury z drugiego obrazu docelowego _, kontury, hierarchia = cv2.findContours (thresh2, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE) dla c w konturach: # przejrzyj każdy kontur w obrazie docelowym i użyj cv2.matchShape, aby porównać kształt konturu match = cv2.matchShapes (tempelate_contour, c, 1,0.0) print ("match") #if wartość dopasowania jest mniejsza niż 0,15, jeśli pasuje <0,16: Najbliższy_kontur = c else: Najbliższy_kontur = cv2.drawContours (target,, - 1, (0,255,0), 3) cv2.imshow ('wyjście',cel) cv2.waitKey (0) cv2.destroyAllWindows ()
Wyjście konsoli -
0,16818605122199104
0.19946910256158912
0.18949760627309664
0.11101058276281539
Istnieją trzy różne metody z różnymi funkcjami matematycznymi, możemy poeksperymentować z każdą metodą, zastępując wartości metody cv2.matchShapes (tempelate_contour, c, 1, 0,0), które wahają się od 1,2 do 3, dla każdej wartości otrzymasz inne dopasowanie wartości w danych wyjściowych konsoli.
6. Rozpoznawanie kształtów (koło, prostokąt, trójkąt, kwadrat, gwiazda)
OpenCV może być również używany do automatycznego wykrywania różnych typów kształtów z obrazu. Korzystając z poniższego kodu będziemy w stanie wykryć na obrazie okrąg, prostokąt, trójkąt, kwadrat i gwiazdy.
import cv2 import numpy jako np
Załaduj, a następnie obrazy w skali szarości
image = cv2.imread ('shapes.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) cv2.imshow ('identyfikowanie kształtów', obraz) cv2.waitKey (0) ret, thresh = cv2.threshold (szary 127,255,1)
Wydobądź kontury
_, kontury, hierarchia = cv2.findContours (thresh.copy (), cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
Dla cnt w konturach:
Uzyskaj przybliżone wielokąty approx = cv2.approxPolyDP (cnt, 0,01 * cv2.arcLength (cnt, True), True) if len (w przybliżeniu) == 3: shape_name = "Triangle" cv2.drawContours (image,, 0, (0,255, 0), - 1)
znajdź środek konturu, aby umieścić tekst w środku
M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (obraz, nazwa_kształtu, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0, 0), 1) elif len (w przybliżeniu) == 4: x, y, w, h = cv2.boundingRect (cnt) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M)
Sprawdź, czy ten czteroboczny wielokąt jest kwadratowy czy prostokątny
# cv2.boundingRect zwraca lewą szerokość i wysokość w pikselach, zaczynając od górnego # lewego rogu, dla kwadratu byłoby mniej więcej tak samo, gdyby abs (wh) <= 3: nazwa_kształtu = "kwadrat" # znajdź środek konturu, aby umieścić tekst w center cv2.drawContours (image,, 0, (0,125,255), - 1) cv2.putText (image, shape_name, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1) else: shape_name = "Reactangle" # znajdź środek konturu, aby umieścić tekst w środku cv2.drawContours (image,, 0, (0,0,255), - 1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (obraz, nazwa_kształtu, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1) elif len (w przybliżeniu) == 10: nazwa_kształtu = 'gwiazda' cv2.drawContours (image,, 0, (255,255,0), - 1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (obraz, nazwa_kształtu, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1) elif len (w przybliżeniu)> = 15: nazwa_kształtu = 'circle' cv2.drawContours (image,, 0, (0,255,255), -1) M = cv2.moments (cnt) cx = int (M / M) cy = int (M / M) cv2.putText (obraz, nazwa_kształtu, (cx-50, cy), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,0,0), 1) cv2.imshow ('identyfikowanie kształtów', obraz) cv2.waitKey (0) cv2.destroyAllWindows ()
7. Wykrywanie linii
Wykrywanie linii jest bardzo ważną koncepcją w OpenCV i ma obiecujące zastosowanie w świecie rzeczywistym. Autonomiczne samochody wykorzystują algorytmy wykrywania linii do wykrywania pasów ruchu i dróg.
W detekcji linii zajmiemy się dwoma algorytmami,
- Algorytm Hough Line
- Algorytm probalistycznej linii Hougha.
Być może pamiętałeś przedstawienie prostej z matematyki w liceum za pomocą równania y = mx + c.
Jednak w OpenCV linia jest reprezentowana w inny sposób
Równanie powyżej ρ = xcosӨ + ysincosӨ jest reprezentacją linii OpenCV, gdzie ρ jest prostopadłą odległością prostej od początku, a Ө jest kątem utworzonym przez normalną tej linii do początku (mierzonym w radianach, gdzie 1pi radianów / 180 = 1 stopień).
Funkcja OpenCV do wykrywania linii jest podana jako
cv2.HoughLines (zbinaryzowany obraz, dokładność ρ, dokładność Ө, próg), gdzie próg jest minimalnym głosem, aby można go było uznać za linię.
Teraz wykryjmy linie dla obrazu pudełka za pomocą funkcji linii Hougha w opencv.
import cv2 import numpy as np image = cv2.imread ('box.jpg')
Usunięto odcienie szarości i ostre krawędzie
gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) brzegi = cv2.Canny (gray, 100,170, apertureSize = 3)
Uruchom linie Hough z dokładnością rho do 1 piksela
Dokładność #theta kwasu (np.pi / 180), który ma jeden stopień próg #line jest do 240 (liczba punktów linia) linii (= cv2.HoughLines krawędzie 1, np.pi / 180, 240) #we iteracji przez każdą linię i przekonwertować na format #required by cv2.lines (tj. wymagające punktów końcowych) dla i w zakresie (0, len (linie)): dla rho, theta w wierszach: a = np.cos (theta) b = np.sin (theta) x0 = a * rho y0 = b * rho x1 = int (x0 + 1000 * (- b)) y1 = int (y0 + 1000 * (a)) x2 = int (x0-1000 * (-b)) y2 = int (y0-1000 * (a)) cv2.line (obraz, (x1, y1), (x2, y2), (0,255,0), 2) cv2.imshow ('hough lines', obraz) cv2.waitKey (0) cv2.destroyAllWindows ()
Teraz powtórzmy wykrywanie powyżej linii z innym algorytmem probabilistycznej linii Hougha.
Ideą probabilistycznej linii Hougha jest wybranie losowego podzbioru punktów wystarczających do wykrycia linii.
Funkcja OpenCV dla probabilistycznej linii Hougha jest reprezentowana jako cv2. HoughLinesP (obraz zbinaryzowany, dokładność ρ, dokładność Ө, próg, minimalna długość linii, maksymalna przerwa między wierszami)
Teraz wykryjmy linie pudełkowe za pomocą probabilistycznych linii Hougha.
import cv2 import numpy jako np
Usunięto odcienie szarości i ostre krawędzie
image = cv2.imread ('box.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) brzegi = cv2.Canny (gray, 50,150, apertureSize = 3) # ponownie używamy tych samych dokładności rho i theta #jed, określamy minimalny głos (punkty wzdłuż linii) 100 # i minimalną długość linii 5 pikseli i maksymalną przerwę między wierszami 10 pikseli linie = cv2. HoughLinesP (edge, 1, np.pi / 180,100,100,10) dla i in range (0, len (lines)): for x1, y1, x2, y2 in lines: cv2.line (image, (x1, y1), (x2, y2), (0,255,0), 3) cv2. imshow ('probalistic hough lines', image) cv2.waitKey (0) cv2.destroyAllWindows
8. Wykrywanie plamek
Obiekty blob można opisać jako grupę połączonych pikseli, które mają wspólną właściwość. Metodę użycia detektora plamek OpenCV opisano na tym schemacie blokowym.
Do rysowania punktów kluczowych używamy cv2.drawKeypoints, który przyjmuje następujące argumenty.
cv2.drawKeypoints (obraz wejściowy, punkty kluczowe, blank_output_array, kolor, flagi)
gdzie na flagach może być
cv2.DRAW_MATCHES_FLAGS_DEFAULT
cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS
cv2.DRAW_MATCHES_FLAGS_DRAW_OVER_OUTIMG
cv2.DRAW_MATCHES_FLAGS_NOT_DRAW_SINGLE_POINTS
a puste tutaj to właściwie nic innego jak macierz zer
Teraz wykonajmy wykrywanie plamek na obrazie słoneczników, gdzie plamki byłyby centralną częścią kwiatu, ponieważ są one wspólne dla wszystkich kwiatów.
import cv2 import numpy as np image = cv2.imread ('Słoneczniki.jpg', cv2.IMREAD_GRAYSCALE)
Skonfiguruj detektor z domyślnymi parametrami
detektor = cv2.SimpleBlobDetector_create ()
Wykryj plamy
keypoints = detektor.detect (obraz)
Narysuj wykryte plamy jako czerwone kółka
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS upewnij się, że # rozmiar okręgu odpowiada rozmiarowi blob blank = np.zeros ((1,1)) blobs = cv2.drawKeypoints (obraz, punkty kluczowe, puste, (0,255,255), cv2.D_FAULT_FLAG)
Pokaż punkty kluczowe
cv2.imshow ('blobs', blobs) cv2.waitKey (0) cv2.destroyAllWindows ()
Mimo że kod działa dobrze, ale niektóre plamy są pomijane z powodu nierównych rozmiarów kwiatów, ponieważ kwiaty z przodu są duże w porównaniu z kwiatami na końcu.
9. Filtrowanie blobów - liczenie okręgów i elips
Możemy użyć parametrów do filtrowania plamek według ich kształtu, rozmiaru i koloru. Do używania parametrów z detektorem blob używamy funkcji OpenCV
cv2.SimpleBlobDetector_Params ()
Zobaczymy filtrowanie obiektów blob głównie według tych czterech parametrów wymienionych poniżej:
Powierzchnia
params.filterByArea = True / False params.minArea = piksele params.maxArea = piksele
Kolistość
params.filterByCircularity = True / False params.minCircularity = 1 oznacza idealne, 0 przeciwne
Wypukłość - obszar kropelki / obszar wypukłego kadłuba
params.filterByConvexity = True / False params.minConvexity = Area
Bezwładność
params.filterByInertia = True / False params.minInertiaRatio = 0.01
Teraz spróbujmy filtrować obiekty blob według wyżej wymienionych parametrów
import cv2 import numpy as np image = cv2.imread ('blobs.jpg') cv2.imshow ('oryginalny obraz', obraz) cv2.waitKey (0)
Zainicjuj czujkę przy użyciu parametrów domyślnych
detektor = cv2.SimpleBlobDetector_create ()
Wykryj plamy
keypoints = detektor.detect (obraz)
Narysuj plamy na naszym obrazie jako czerwone kółka
blank = np.zeros ((1,1)) plamy = cv2.drawKeypoints (obraz, punkty kluczowe, puste, (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) number_of_blobs = len (keypoints) text = "całkowita liczba plamek" + str (len (keypoints)) cv2.putText (blobs, text, (20,550), cv2.FONT_HERSHEY_SIMPLEX, 1, (100,0,255), 2)
Wyświetl obraz z punktami kluczowymi typu blob
cv2.imshow ('blob używający parametrów domyślnych', blobs) cv2.waitKey (0)
Ustaw nasze parametry filtrowania
#initialize ustawianie parametrów za pomocą cv2.SimpleBlobDetector params = cv2.SimpleBlobDetector_Params ()
Ustaw parametry filtrowania obszaru
params.filterByArea = True params.minArea = 100
Ustaw parametry filtrowania cykliczności
params.filterByCircularity = True params.minCircularity = 0,9
Ustaw parametr filtrowania wypukłości
params.filterByConvexity = Fałsz params.minConvexity = 0.2
Ustaw parametr filtrowania bezwładności
params.filterByInertia = True params.minInertiaRatio = 0,01
Utwórz detektor z parametrem
detektor = cv2.SimpleBlobDetector_create (parametry)
Wykryj plamy
keypoints = detektor.detect (obraz)
Narysuj plamy na obrazach jako czerwone kółka
blank = np.zeros ((1,1)) blobs = cv2.drawKeypoints (image, keypoints, blank, (0,255,0), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) number_of_blobs = len (keypoints) text = "całkowita liczba okrągłych plamek" + str (len (keypoints)) cv2.putText (blob, tekst, (20,550), cv2.FONT_HERSHEY_SIMPLEX, 1, (0,100,255), 2)
Pokaż obiekty blob
cv2.imshow ('filtrowanie cyklicznych obiektów blob', blobs) cv2.waitKey (0) cv2.destroyAllWindows ()
Oto jak można przeprowadzić segmentację obrazu w Python-OpenCV. Aby dobrze zrozumieć wizję komputerową i OpenCV, przejrzyj poprzednie artykuły (Pierwsze kroki z Python OpenCV i Manipulacje obrazami w Python OpenCV, a będziesz w stanie stworzyć coś fajnego dzięki Computer Vision.