- Wykrywanie obiektów za pomocą SIFT
- Wykrywanie obiektów za pomocą ORB
- Histogram zorientowanych gradientów (HOG)
- Histogram zorientowanych gradientów (HOG), krok po kroku:
- Klasyfikatory kaskadowe HAAR
- Wykrywanie twarzy i oczu
- Wykrywanie twarzy i oczu na żywo
- Dostrajanie klasyfikatorów kaskadowych
- Wykrywanie samochodów i pieszych w filmach
Zaczęliśmy od instalacji Python OpenCV w systemie Windows i do tej pory wykonaliśmy podstawowe przetwarzanie obrazu, segmentację obrazu i wykrywanie obiektów za pomocą Pythona, które są opisane w poniższych samouczkach:
- Pierwsze kroki z Python OpenCV: instalacja i podstawowe przetwarzanie obrazu
- Manipulacje obrazami w Python OpenCV (część 1)
- Manipulacje obrazami w OpenCV (część 2)
- Segmentacja obrazu za pomocą OpenCV - wyodrębnianie określonych obszarów obrazu
Dowiedzieliśmy się również o różnych metodach i algorytmach wykrywania obiektów, w których niektóre kluczowe punkty zostały zidentyfikowane dla każdego obiektu przy użyciu różnych algorytmów. W tym samouczku będziemy używać tych algorytmów do wykrywania rzeczywistych obiektów, tutaj do wykrywania używalibyśmy SIFT i ORB.
Wykrywanie obiektów za pomocą SIFT
W tym przypadku detekcja obiektu zostanie wykonana przy użyciu strumienia z kamery internetowej na żywo, więc jeśli rozpozna obiekt, wspomina o znalezionym obiekcie. W kodzie główną rolę odgrywa funkcja zwana detektorem SIFT, większość przetwarzania jest wykonywana przez tę funkcję.
A w drugiej połowie kodu zaczynamy od otwarcia strumienia z kamery internetowej, następnie wczytujemy szablon obrazu, czyli obraz referencyjny, czyli program faktycznie przegląda strumień kamery internetowej.
Następnie, w sposób ciągły, przechwytywanie obrazu ze strumienia kamery za pomocą nieskończonej while pętli, a następnie uchwycenia odpowiedniej wysokości i szerokości ramy kamery, po czym określić parametry obszaru zainteresowania (ROI), skrzynki, w której nasz obiekt może zmieścić się, biorąc odpowiednią wysokość i szerokość ramki kamery internetowej. Następnie rysujemy prostokąt na podstawie parametrów ROI, które zdefiniowaliśmy powyżej. Na koniec wytnij prostokąt i umieść go w części kodu z detektorem SWIFT.
Teraz detektor SIFT ma w zasadzie dwa wejścia, jedno to przycięty obraz, a drugie to szablon obrazu, który wcześniej zdefiniowaliśmy, a następnie daje nam kilka dopasowań, więc dopasowania to w zasadzie liczba obiektów lub punktów kluczowych, które są podobne na przyciętym obrazie i obraz docelowy. Następnie określamy wartość progową dla dopasowań, jeśli wartość dopasowania jest większa niż próg, umieszczamy obraz znaleziony na naszym ekranie z zielonym kolorem prostokąta ROI.
Wróćmy teraz do głównej części kodu, funkcji, która nazywa się detektorem SIFT, pobiera dane wejściowe jako dwa obrazy, jeden to obraz, na którym szuka obiektu, a drugi to obiekt, który próbujemy dopasować do (szablon obrazu). Następnie przeskaluj pierwszy obraz w odcieniach szarości i zdefiniuj szablon obrazu jako drugi obraz. Następnie tworzymy obiekt detektora SIFT i uruchamiamy funkcję wykrywania i obliczania OpenCV SIFT, aby wykryć punkty kluczowe i obliczyć deskryptory, deskryptory to w zasadzie wektory, które przechowują informacje o punktach kluczowych, i jest to naprawdę ważne, ponieważ wykonujemy dopasowywanie między deskryptorami obrazów.
A następnie zdefiniuj dopasowywanie oparte na FLANN, nie wchodzimy w matematyczną teorię dopasowywania, która się za nim kryje, ale możesz łatwo znaleźć w Google. Najpierw określamy indeks kdtree na zero, a następnie ustawiamy indeks i parametry wyszukiwania w formacie słownikowym, po prostu określamy algorytm, którego będziemy używać, czyli KDTREE, a liczba drzew, których będziemy używać, tym więcej drzew używamy, im bardziej się to komplikuje i wolniej. W parametrze wyszukiwania określ liczbę sprawdzeń, czyli w zasadzie liczbę dopasowań, które ma zakończyć.
Następnie utwórz nasz obiekt dopasowujący oparty na FLANN, ładując parametr, który wcześniej zdefiniowaliśmy, który jest parametrami indeksu i parametrami wyszukiwania, i na tej podstawie utwórz nasz element dopasowujący oparty na FLANN, który jest dopasowaniem KNN, gdzie KNN jest K-najbliższymi sąsiadami, w zasadzie jest to sposób, w którym szukamy najbliższych dopasowań i deskryptorów i dopasowujemy za pomocą stałej inicjalizacji k. Teraz ten element dopasowujący oparty na FLANN zwraca liczbę otrzymanych dopasowań.
Dopasowanie oparte na FLANN jest tylko przybliżeniem, więc aby zwiększyć dokładność dopasowywania opartego na FLANN, wykonujemy test współczynnika Lowe'a i to, co robi, to wyszukuje dopasowania z dopasowywania opartego na knn flann i definiuje niektóre parametry matematyczne, czyli odległość tutaj, dla której odległość jest funkcją numpy, a gdy spełnia kryteria, dołącz dopasowania do dobrych dopasowań i zwraca znalezione dobre dopasowania, dzięki czemu strumień wideo na żywo pokazuje liczbę dopasowań znalezionych w rogu ekranu.
Teraz spójrzmy na kod powyższego opisu:
import cv2 import numpy as np def sift_detector (new_image, image_template): # Funkcja porównująca obraz wejściowy z szablonem # Następnie zwraca liczbę dopasowań SIFT między nimi image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Create Obiekt detektora SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Uzyskaj punkty kluczowe i deskryptory za pomocą SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2A = imageCndeift, Brak) # Zdefiniuj parametry dla naszego Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algorytm = FLANN_INDEX_KDTREE, drzewa = 3) search_params = dict (CHECKS = 100) # Utwórz obiekt Flann Matcher flann = cv2.FlannBasedMatcher (index_params, search_params) # Uzyskaj dopasowania za pomocą metody K-Nearest Neighbor # wynik „pasuje” to liczba podobnych dopasowań znalezionych w obu dopasowanych obrazach = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Przechowuj dobre dopasowania za pomocą testu współczynnika Lowe'a good_matches = dla m, n w dopasowaniach: jeśli m. odległość <0,7 * n. odległość: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Załaduj nasz szablon obrazu, to jest nasz obraz referencyjny image_template = cv2.imread ('phone.jpg', 0) while True: # Pobierz obrazy z kamery internetowej ret, frame = cap.read () # Uzyskaj wysokość i szerokość ramy kamery internetowej wysokość, width = frame.shape # Zdefiniuj wymiary pola ROI top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Rysuj prostokątne okno dla naszego obszaru zainteresowania cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Przytnij okno obserwacji, które zdefiniowaliśmy powyżej cropped = ramka # Odwróć orientację ramki w poziomie frame = cv2.flip (frame, 1) # Uzyskaj liczbę dopasowań SIFT = sift_detector (przycięte, image_template) # Wyświetla ciąg statusu pokazujący aktualny nr. of dopasowań cv2.putText (ramka, str (pasuje), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Nasz próg wskazujący detekcję obiektu # Używamy 10, ponieważ detektor SIFT zwraca niewiele fałszywych pozycji reshold = 10 # Jeśli dopasowania przekraczają nasz próg, to obiekt został wykryty, jeśli pasuje> próg: cv2.rectangle (ramka, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (ramka, 'Object Found', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Object Detector using SIFT', frame) if cv2.waitKey (1) == 13: # 13 to klawisz Enter przerwy cap.release () cv2.destroyAllWindows ()
Wykrywanie obiektów za pomocą ORB
Wykrywanie obiektów za pomocą SIFT jest całkiem fajne i dokładne, ponieważ generuje bardzo dokładną liczbę dopasowań w oparciu o punkty kluczowe, jednak jest opatentowane i utrudnia użycie go w zastosowaniach komercyjnych, innym wyjściem jest algorytm ORB do wykrywania obiektów.
Podobnie jak w przypadku metody wykrywania obiektów przez SIFT, w której podzieliliśmy program na dwie części, to samo zostanie tutaj zastosowane.
Po pierwsze, definiujemy funkcję ORB_detector, która pobiera dwa wejścia, jedno to obraz na żywo z kamery internetowej, a drugie to szablon obrazu, na podstawie którego dopasujemy nasz obraz. Następnie skalujemy obraz z kamery internetowej w skali szarości, a następnie inicjalizujemy nasz detektor ORB i ustawiamy go tutaj na 1000 kluczowych punktów i parametry skalowania 1,2. możesz łatwo pobawić się tymi parametrami, a następnie wykryć punkty kluczowe (kp) i deskryptory (des) dla obu obrazów, a drugi parametr, który definiujemy w funkcji DetectANDCompute to NONE, prosi o użycie maski obrazu lub nie i zaprzeczamy temu tutaj.
Następnie przejdź do detektora, którego wcześniej używaliśmy matchera opartego na FLANN, ale tutaj będziemy używać BFMatchera i wewnątrz BFMatchera definiujemy dwa parametry, jeden to NORM_HAMMING, a drugi to crossCheck, którego wartość to TRUE.
Następnie oblicz dopasowania dopasowań między tymi dwoma obrazami, używając deskryptorów zdefiniowanych powyżej, co w sumie zwraca liczbę dopasowań, ponieważ te dopasowania nie są przybliżone i dlatego nie ma potrzeby wykonywania testu współczynnika Lowe'a, zamiast tego sortujemy dopasowania na podstawie odległości, przynajmniej im większa odległość tym dopasowanie jest lepsze (tutaj odległość oznacza odległość między punktami), a na koniec zwracamy liczbę dopasowań za pomocą funkcji length.
W funkcji głównej ustawiliśmy próg na znacznie wyższą wartość, ponieważ detektor kul generuje dużo szumu.
Spójrzmy teraz na kod do wykrywania opartego na ORB
import cv2 import numpy as np def ORB_detector (new_image, image_template): # Funkcja porównująca obraz wejściowy z szablonem # Następnie zwraca liczbę dopasowań ORB między nimi image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Utwórz detektor ORB z 1000 punktów kluczowych ze współczynnikiem piramidy skalowania 1,2 orb = cv2.ORB_create (1000, 1,2) # Wykryj punkty kluczowe oryginalnego obrazu (kp1, des1) = orb.detectAndCompute (obraz1, brak) # Wykryj punkty kluczowe obróconego obrazu (kp2, des2) = orb.detectAndCompute (image_template, None) # Create matcher # Uwaga, nie używamy już dopasowania flannbased bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Dopasuj dopasowania = bf.match (des1, des2) # Sortuj dopasowania na podstawie odległości. Najmniejsza odległość # to lepsze dopasowanie = sortowane (mecze, klucz = lambda val: val.distance) return len ( trafia ) cap = cv2.VideoCapture (0) # Załaduj nasz szablon obrazu, to jest nasz obraz referencyjny image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) while True: # Pobierz obrazy z kamery internetowej ret, frame = cap.read () # Uzyskaj wysokość i szerokość wysokości ramki kamery internetowej , width = frame.shape # Zdefiniuj wymiary pola ROI (Zwróć uwagę, że niektóre z tych rzeczy powinny znajdować się poza pętlą) top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Rysuj prostokątne okno dla naszego region zainteresowania cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Przytnij okno obserwacji zdefiniowane powyżej cropped = ramka # Odwróć orientację ramki poziomo frame = cv2.flip (frame, 1) # Uzyskaj liczbę dopasowań ORB = ORB_detector (przycięty, szablon_obrazu) # Wyświetl ciąg statusu pokazujący aktualny nr. z dopasowań output_string = "Matches =" + str ( trafi) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Nasza próg, aby wskazać obiekt deteciton # Dla nowych obrazów lub warunkami oświetleniowymi może trzeba trochę poeksperymentować # Uwaga: czujnik ORB zdobycia szczytu 1000 mecze, 350 jest zasadniczo min 35% dopasowania progu = 250 # Jeśli mecze przekraczać nasze próg to obiekt został wykryty, jeśli pasuje> próg: cv2.rectangle (ramka, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (ramka, 'Object Found', (50 50) cv2.FONT_HERSHEY_COMPLEX 2 (0,255,0), 2) cv2.imshow ('czujnik za pomocą obiektu ORB', ramka) jeśli cv2.waitKey (1) == 13: # 13, klawisz zatwierdzania przerwy nasadkę.release () cv2.destroyAllWindows ()
Histogram zorientowanych gradientów (HOG)
Porozmawiajmy teraz o innym deskryptorze, którym jest histogram zorientowanych gradientów (HOG).
HOG są całkiem fajnymi i użytecznymi deskryptorami i są szeroko iz powodzeniem stosowane do wykrywania obiektów, jak widać wcześniej w deskryptorach obrazów, takich jak SIFT i ORB, gdzie musimy obliczyć punkty kluczowe, a następnie obliczyć deskryptory z tych punktów kluczowych, HOG wykonują ten proces różnie. To oznacza obiekty jako pojedynczy wektor, w przeciwieństwie do szeregu wektorów cech w których każdy reprezentuje segment obrazu. Oznacza to, że mamy jeden element wektorowy dla całego obrazu.
Jest obliczany przez detektor przesuwanego okna nad obrazem, gdzie deskryptor HOG jest obliczany dla każdej pozycji. Następnie każda pozycja jest łączona dla jednego wektora cech.
Podobnie jak SIFT, skala obrazu jest regulowana przez piramidowanie.
Wcześniej używaliśmy dopasowań, takich jak FLANN i BFMatcher, ale HOG robią to inaczej za pomocą klasyfikatorów SVM (maszyna wektorów wsparcia), w których każdy obliczany deskryptor HOG jest podawany do klasyfikatora SVM w celu określenia, czy obiekt został znaleziony, czy nie.
Oto link do świetnego artykułu Dalal & Triggs na temat korzystania z HOG-ów do wykrywania ludzi:
Histogram zorientowanych gradientów (HOG), krok po kroku:
Zrozumienie HOG może być dość złożone, ale tutaj zajmiemy się tylko teorią HOG bez zagłębiania się w związaną z nią matematykę.
Zróbmy więc to zdjęcie jest trochę pikselowane, a w górnym rogu jest tutaj pole 8x8 pikseli, więc w tym polu obliczamy wektor gradientu lub orientację krawędzi dla każdego piksela. Oznacza to, że w tym polu obliczamy wektor gradientu obrazu pikseli wewnątrz ramki (są one rodzajem kierunku lub przepływu samego natężenia obrazu), co generuje 64 (8 x 8) wektory gradientu, które są następnie reprezentowane jako histogram. Wyobraź sobie więc histogram, który reprezentuje każdy wektor gradientu. Więc jeśli wszystkie punkty lub intensywności leżą w jednym kierunku, histogram dla tego kierunku, powiedzmy 45 stopni, miałby szczyt pod kątem 45 stopni.
Więc to, co teraz robimy, to podzielenie każdej komórki na kątowe kosze, gdzie każdy pojemnik odpowiada kierunkowi gradientu (np. X, y). W artykule Dalal i Triggs używali 9 pojemników 0-180 ° (20 ° każdy pojemnik). To skutecznie redukuje 64 wektory do zaledwie 9 wartości. Więc to, co zrobiliśmy, to zmniejszenie rozmiaru, ale zachowaliśmy wszystkie kluczowe informacje, które są potrzebne.
Kolejnym krokiem w obliczaniu świń jest normalizacja, normalizujemy gradienty, aby zapewnić niezmienność zmian oświetlenia, tj. Jasność i Kontrast.
Na tym obrazie wartości natężenia są pokazane w kwadracie zgodnie z odpowiednim kierunkiem i wszystkie mają różnicę 50 między sobą
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Wektory dzielimy przez wielkości gradientu, które otrzymujemy dla wszystkich 0,707, to jest normalizacja.
Podobnie, jeśli zmienimy intensywność lub zmienimy kontrast, otrzymamy poniższe wartości.
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707; ∆ H = 100, ∆ v = 100; │∆│ = √100 2 +100 = 141,42, 141,42 / 100 = 1,41
Normalizacja nie odbywa się na poziomie komórki, zamiast tego odbywa się na poziomie bloku, więc tutaj bloki są w zasadzie grupą 4 komórek, bierze się pod uwagę sąsiednie bloki, więc normalizuj biorąc pod uwagę większe segmenty obrazu.
Teraz spójrzmy na kod
import numpy as np import cv2 import matplotlib.pyplot as plt # Wczytaj obraz, a następnie obraz w skali szarości = cv2.imread ('elephant.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Pokaż oryginalny obraz cv2.imshow (' Input Image ', image) cv2.waitKey (0) #definiowanie parametrów, rozmiaru komórki i rozmiaru bloku # hxw w pikselach cell_size = (8, 8) # hxw in cells block_size = (2, 2) # liczba pojemników orientacji nbins = 9 # Korzystanie z deskryptora HOG OpenCV # winSize to rozmiar obrazu przyciętego do wielokrotności rozmiaru komórki hog = cv2.HOGDescriptor (_winSize = (gray.shape // rozmiar_komórki * rozmiar_komórki, gray.shape // cell_size * cell_size), _blockSize = (block_size * cell_size, block_size * cell_size), _blockStride = (cell_size, cell_size), _cellSize = (cell_size, cell_size), _nbins = nbins) # Tworzymy numpy to create hog_features n_cells = (gray.shape // cell_size, gray.shape // cell_size) # Najpierw indeksujemy bloki po wierszach. # hog_feats zawiera teraz amplitudy gradientu dla każdego kierunku, # dla każdej komórki swojej grupy dla każdej grupy. Indeksowanie odbywa się według wierszy, a następnie kolumn. hog_feats = hog.compute (gray).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Utwórz naszą tablicę gradientów z wymiarami nbin, aby przechowywać orientacje gradientu gradients = np.zeros ((n_cells, n_cells, nbins)) # Utwórz tablicę wymiarów cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Normalizacja bloku dla off_y in range (block_size): for off_x in range (block_size): gradients - block_size + off_y + 1, off_x: n_cells - block_size + off_x + 1] + = \ hog_feats cell_count - block_size + off_y + 1, off_x: n_cells - block_size + off_x + 1] + = 1 # Średnie gradienty gradienty / = cell_count # Wykreśl HOG używając Matplotlib # kąt to 360 / nbins * kierunek color_bins = 5 plt.pcolor (gradients) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('equal', Adjustable = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Obraz pokazuje, jak obraz wejściowy jest reprezentowany jako reprezentacja HOG.
Klasyfikatory kaskadowe HAAR
Jak wspomniano wcześniej, możemy wyodrębnić cechy z obrazu i użyć tych funkcji do klasyfikowania lub wykrywania obiektów.
Czym są klasyfikatory kaskadowe HAAR?
Metoda wykrywania obiektów, która wprowadza funkcje Haara do szeregu klasyfikatorów (kaskadowych) w celu identyfikacji obiektów na obrazie. Są wyszkoleni w rozpoznawaniu jednego typu obiektu, jednak możemy używać kilku z nich równolegle, np. Wykrywając jednocześnie oczy i twarze.
Wyjaśnienie klasyfikatorów HAAR:
Klasyfikatory HAAR są szkolone przy użyciu wielu pozytywnych obrazów (tj. Obrazów z obecnym obiektem) i
negatywowych (tj. Obrazów bez obiektu).
Gdy mamy te obrazy, wyodrębniamy elementy za pomocą przesuwanych okien prostokątnych bloków. Te cechy (cechy HAAR) są jednostkowe i są obliczane przez odjęcie sumy intensywności pikseli pod białymi prostokątami od czarnych prostokątów.
Jest to jednak absurdalna liczba obliczeń, nawet dla okna bazowego 24 x 24 piksele (180 000 wygenerowanych cech).
Dlatego naukowcy opracowali metodę zwaną Integral Images, która obliczyła to z czterema odniesieniami do tablicy. Jednak nadal posiadały 180 000 funkcji, a większość z nich nie dodała żadnej realnej wartości.
Zwiększenie została następnie wykorzystana do określenia najbardziej funkcje informacyjne, z Freunda & Schapire za adaboost i stwierdzono cechy najbardziej informacyjny obrazu. Zwiększanie to proces, w którym używamy słabych klasyfikatorów do tworzenia silnych klasyfikatorów, po prostu przypisując cięższe kary do nieprawidłowych klasyfikacji. Zmniejszenie 180 000 funkcji do 6000, co wciąż jest dość dużą liczbą funkcji.
W tych 6000 funkcji niektóre będą zawierały więcej informacji niż inne. Więc jeśli użyliśmy najbardziej pouczających funkcji, aby najpierw sprawdzić, czy region może mieć potencjalnie twarz (fałszywe alarmy nie będą wielkim problemem). Takie postępowanie eliminuje potrzebę obliczania wszystkich 6000 cech jednocześnie. Ta koncepcja nosi nazwę kaskady klasyfikatorów - do wykrywania twarzy metoda Viola Jones wykorzystała 38 etapów.
Wykrywanie twarzy i oczu
Więc po zdobyciu pewnej wiedzy teoretycznej na temat kaskad HAAR zamierzamy w końcu ją wdrożyć, aby wszystko było jasne, podzielimy lekcje na części, najpierw wykryjemy twarz czołową, a następnie przejdziemy do wykrywania twarzy czołowej za pomocą oczy i na koniec wykrywaliśmy twarz i oczy na żywo przez kamerę internetową.
W tym celu użyjemy wstępnie wytrenowanych klasyfikatorów, które zostały dostarczone przez OpenCV jako pliki.xml, xml oznacza rozszerzalny język znaczników, ten język jest używany do przechowywania ogromnej ilości danych, można nawet zbudować na nim bazę danych.
Możesz mieć dostęp do tych klasyfikatorów pod tym linkiem .
Wykrywanie twarzy
Spróbujmy do wykrywania twarzy czołowej, tutaj możesz mieć dostęp do kaskady przedniego detektora twarzy. Po prostu wyodrębnij plik zip, aby uzyskać plik xml.
import numpy as np import cv2 # Wskazujemy funkcję CascadeClassifier OpenCV na miejsce, w którym przechowywany jest nasz # klasyfikator (format pliku XML), pamiętaj, aby przechowywać kod i klasyfikator w tym samym folderze face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load nasz obraz następnie przekonwertuj go na skalę szarości image = cv2.imread ('Trump.jpg') gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Nasz klasyfikator zwraca ROI wykrytej twarzy jako krotkę # Przechowuje lewy górny współrzędne i współrzędne w prawym dolnym rogu # zwraca listę list, które są lokalizacjami różnych wykrytych twarzy. twarze = face_cascade.detectMultiScale (szary, 1,3, 5) # Gdy nie wykryto żadnych twarzy, face_classifier zwraca i pustą krotkę, jeśli twarze to (): print ("Nie znaleziono twarzy") # Iterujemy przez naszą tablicę twarzy i rysujemy prostokąt # na każdej twarzy w twarzach dla (x, y, w, h) w twarzach: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Face Detection', image) cv2.waitKey (0) cv2.destroyAllWindows ()
Teraz połączmy razem wykrywanie twarzy i oczu, aby uzyskać dostęp do kaskady detektora oczu w tym samym pliku zip.
import numpy as np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpgColor.c = gray ') = cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) # Gdy nie wykryto żadnych twarzy, zwraca face_classifier i pustą krotkę, jeśli twarze to (): print ("No Face Found") for (x, y, w, h) w twarzach: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = grey roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) for (ex, ey, ew, eh) in eyes: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (255,255,0), 2) cv2.imshow ('img', img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
Więc ten kod jest taki sam jak kod do wykrywania twarzy, ale tutaj dodaliśmy kaskady oczu i metodę ich wykrywania, jak widać, wybraliśmy wersję twarzy w skali Graya jako parametr dla funkcji detectionMultiScale dla oczy, co prowadzi nas do ograniczenia obliczeń, ponieważ będziemy wykrywać oczy tylko w tym obszarze.
Wykrywanie twarzy i oczu na żywo
Do tej pory wykonaliśmy wykrywanie twarzy i oczu, teraz zaimplementujmy to samo z transmisją wideo na żywo z kamery internetowej. W tym przypadku zrobimy to samo wykrywanie twarzy i oczu, ale tym razem zrobimy to dla transmisji na żywo z kamery internetowej. W większości aplikacji Twoja twarz byłaby podkreślona ramką wokół niej, ale tutaj zrobiliśmy coś innego, że Twoja twarz byłaby wycięta, a oczy identyfikowałyby się tylko w tym.
Więc tutaj importujemy zarówno klasyfikator twarzy, jak i oczu i zdefiniowaliśmy funkcję do wykonywania całego przetwarzania dla wykrywania twarzy i oczu. Następnie uruchomiono strumień z kamery internetowej i wywołałem funkcję wykrywania twarzy, aby wykryć twarz i oczy. Parametr, który definiujemy w funkcji wykrywania twarzy, to ciągłe obrazy z transmisji na żywo z kamery internetowej
import cv2 import numpy as np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5): # Przekonwertuj obraz na cv2. (img, cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (gray, 1.3, 5) if faces is (): return img for (x, y, w, h) in Faces: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2.rectangle (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = grey roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) for (ex, ey, ew, eh) w oczach: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) return roi_color cap = cv2.VideoCapture (0) while True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) if cv2.waitKey (1) == 13: # 13 to Enter Key break cap.release () cv2.destroyAllWindows ()
Dostrajanie klasyfikatorów kaskadowych
Parametry zdefiniowane w narzędziu DetectMultiScale inne niż obraz wejściowy mają następujące znaczenie
ourClassifier. DetectMultiScale (obraz wejściowy, współczynnik skali, minimalna liczba sąsiadów)
- Współczynnik skali Określa, o ile zmniejszamy rozmiar obrazu przy każdym skalowaniu. Np. Przy wykrywaniu twarzy zazwyczaj używamy 1.3. Oznacza to, że za każdym razem, gdy jest skalowany, zmniejszamy obraz o 30%. Mniejsze wartości, takie jak 1,05, będą wymagały więcej czasu do obliczenia, ale zwiększą szybkość wykrywania.
- Min. Sąsiadów Określa liczbę sąsiadów, które powinno mieć każde potencjalne okno, aby uznać je za wykrycie pozytywne. Zwykle ustawia się między 3-6. Działa jako ustawienie czułości, niskie wartości mogą czasami wykrywać wielokrotne twarze na jednej twarzy. Wysokie wartości zapewnią mniej fałszywych alarmów, ale możesz przeoczyć niektóre twarze.
Wykrywanie samochodów i pieszych w filmach
Teraz będziemy wykrywać pieszych i samochody w filmach za pomocą kaskad HAAR, ale w przypadku, gdy wideo nie jest ładowane, a kod kompiluje się bez błędu, należy wykonać następujące czynności:
Jeśli po uruchomieniu kodu wideo nie zostanie załadowane, może być konieczne skopiowanie naszego pliku opencv_ffmpeg.dl z : opencv \ sources \ 3rdparty \ ffmpeg, aby wkleić go tam , gdzie jest zainstalowany twój Python, np. C: \ Anaconda2
Po skopiowaniu musisz zmienić nazwę pliku zgodnie z wersją OpenCV, której używasz.eg, jeśli używasz OpenCV 2.4.13, a następnie zmień nazwę pliku na: opencv_ffmpeg2413_64.dll lub opencv_ffmpeg2413.dll (jeśli jesteś na komputerze X86) opencv_ffmpeg310_64.dll lub opencv_ffmpeg310.dll (jeśli używasz komputera X86)
Aby dowiedzieć się, gdzie jest zainstalowany python.exe, po prostu uruchom te dwie linie kodu, aby wydrukować lokalizację, w której jest zainstalowany python.
import sys print (sys.executable)
Teraz, jeśli pomyślnie wykonałeś te kroki, przejdźmy do kodu wykrywania pieszych, Możesz mieć kaskadę do wykrywania pieszych i z załączonego pliku zip tutaj.
import cv2 import numpy as np # Utwórz nasz klasyfikator ciała body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Zainicjuj przechwytywanie wideo dla pliku wideo, tutaj używamy pliku wideo, w którym wykryto przechodniów cap = cv2.VideoCapture ('walking.avi') # Zapętlaj po pomyślnym załadowaniu wideo podczas cap.isOpened (): # Czytanie każdej klatki wideo ret, frame = cap.read () # tutaj zmieniamy rozmiar klatki do połowy jej rozmiaru, robimy, aby przyspieszyć klasyfikację, # ponieważ większe obrazy mają dużo więcej okien do przesuwania, więc ogólnie zmniejszamy rozdzielczość # wideo o połowę to właśnie wskazuje 0,5, a my również używamy szybszej metody interpolacji, czyli #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) gray = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Przekaż ramkę do naszych ciał klasyfikatorów treści = body_classifier.detectMultiScale (gray, 1.2, 3) # Wyodrębnij ramki ograniczające dla dowolnych obiektów zidentyfikowanych dla (x, y, w, h) w ciałach: cv2. rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Pedestrians', frame) if cv2.waitKey (1) == 13: # 13 to limit przerwania klawisza Enter .release () cv2.destroyAllWindows ()
Po pomyślnym wykryciu pieszych na wideo, przejdźmy do kodu do wykrywania samochodów, stąd możesz mieć kaskadę do wykrywania pieszych.
import cv2 import time import numpy as np # Utwórz nasz klasyfikator nadwozia car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Rozpocznij przechwytywanie wideo dla pliku wideo cap = cv2.VideoCapture ('cars.avi') # Zapętlaj po pomyślnym wyświetleniu wideo ładowane while cap.isOpened (): time.sleep (.05) # Odczytaj pierwszą klatkę ret, frame = cap.read () gray = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Przekaż ramkę do naszego klasyfikatora samochodów cars = car_classifier.detectMultiScale (gray, 1.4, 2) # Wyodrębnij obwiednie dla dowolnych ciał zidentyfikowanych dla (x, y, w, h) w samochodach: cv2.rectangle (frame, (x, y), (x + w, y + h)), (0, 255, 255), 2) cv2.imshow ('Cars', ramka) jeśli cv2.waitKey (1) == 13: # 13 jest Enter przerwa cap.release () cv2.destroyAllWindows ()
Zauważyłeś, że dodaliśmy time.sleep (0,05) , to tylko opóźnienie w liczbie klatek na sekundę, dzięki czemu możesz potwierdzić, że wszystkie samochody są poprawnie zidentyfikowane, lub możesz łatwo go usunąć, dodając do niego etykietę komentarza.
Ten artykuł pochodzi z kursu Master Computer Vision ™ OpenCV4 w Pythonie z głębokim uczeniem na Udemy, stworzonego przez Rajeeva Ratana, subskrybuj go, aby dowiedzieć się więcej o Computer Vision i Pythonie.