- Detekce objektů pomocí SIFT
- Detekce objektů pomocí ORB
- Histogram orientovaných gradientů (HOG)
- Histogram orientovaných gradientů (HOG), krok za krokem:
- Kaskádové klasifikátory HAAR
- Detekce obličeje a očí
- Živá detekce obličeje a očí
- Ladění kaskádových klasifikátorů
- Detekce automobilů a chodců ve videích
Začali jsme instalací pythonu OpenCV na Windows a zatím jsme provedli některé základní zpracování obrazu, segmentaci obrazu a detekci objektů pomocí Pythonu, které jsou popsány v následujících cvičeních:
- Začínáme s Python OpenCV: Instalace a základní zpracování obrazu
- Manipulace s obrázky v Pythonu OpenCV (část 1)
- Manipulace s obrázky v OpenCV (část 2)
- Segmentace obrazu pomocí OpenCV - extrakce konkrétních oblastí obrazu
Dozvěděli jsme se také o různých metodách a algoritmech pro detekci objektů, kde byly identifikovány některé klíčové body pro každý objekt pomocí různých algoritmů. V tomto tutoriálu použijeme tyto algoritmy k detekci skutečných objektů, zde bychom pro detekci používali SIFT a ORB.
Detekce objektů pomocí SIFT
Zde bude detekce objektu provedena pomocí živého streamu webové kamery, takže pokud rozpozná objekt, zmíní se nalezený objet. V kódu hraje hlavní část funkce, která se nazývá detektor SIFT, většinu zpracování provádí tato funkce.
A v druhé polovině kódu začínáme otevřením streamu webové kamery, poté načteme šablonu obrázku, tj. Referenční obrázek, což je program, který se ve skutečnosti dívá skrz stream webové kamery.
Dále průběžně snímáme obrázky ze streamu webové kamery pomocí nekonečné smyčky while a poté zachycujeme odpovídající výšku a šířku rámu webové kamery a poté definujeme parametry pole oblasti zájmu (ROI), ve kterém náš objekt zapadne do odpovídající výšky a šířky rámu webové kamery. A pak nakreslíme obdélník z parametrů ROI, které jsme definovali výše. Nakonec obdélník nakonec ořízněte a vložte do části kódu detektoru SWIFT.
Nyní má detektor SIFT v zásadě dva vstupy, jeden je oříznutý obraz a druhý je obrazová šablona, kterou jsme dříve definovali, a pak nám dává nějaké shody, takže shody jsou v podstatě počet objektů nebo klíčových bodů, které jsou podobné oříznutému obrazu a cílový obraz. Poté definujeme prahovou hodnotu pro shody, pokud je hodnota shody větší než prahová hodnota, vložíme obrázek nalezený na naší obrazovce se zelenou barvou obdélníku ROI.
Nyní se vraťme zpět k hlavní části kódu, funkci, která se nazývá jako detektor SIFT, bere vstup jako dva obrázky, jeden je obraz, kde hledá objekt a druhý je objekt, který se snažíme porovnat do (šablona obrázku). Poté šedý obrázek prvního obrázku a definujte šablonu obrázku jako druhý obrázek. Poté vytvoříme objekt detektoru SIFT a spustíme funkci detekce a výpočtu OpenCV SIFT, abychom detekovali klíčové body a vypočítali deskriptory, deskriptory jsou v podstatě vektory, které ukládají informace o klíčových bodech, a je opravdu důležité, protože porovnáváme mezi deskriptory obrázků.
A pak definujte FLANN založený matcher, nebudeme se zabývat matematickou teorií párování za tím, ale můžete o tom snadno Google. Nejprve definujte index kdtree na nulu a poté nastavíme parametry indexu a vyhledávání ve formátu slovníku, pouze definujeme algoritmus, který budeme používat, kterým je KDTREE, a počet stromů, které budeme používat, tím více stromů používáme čím složitější je to a pomalejší. A ve vyhledávacím parametru definujte počet šeků, což je v podstatě počet shod, které bude dokončen.
A pak vytvořte náš porovnávací objekt založený na FLANN načtením parametru, který jsme dříve definovali, což jsou parametry indexu a vyhledávací parametry, a na základě toho vytvořte náš srovnávač založený na FLANN, což je KNN porovnávač, kde KNN jsou K-nejbližší sousedé, v podstatě je to způsob hledáme nejbližší porovnávače a deskriptory a provádíme porovnávání s inicializační konstantou k. Nyní tento srovnávač založený na FLANNu vrátí počet shod, které získáme.
Porovnání založené na FLANN je pouze přibližné, abychom zvýšili přesnost srovnávače založeného na FLANN, provedeme test poměru Lowe a to, co dělá, je, že hledá shody ze srovnávače založeného na knn flann a definuje některé maticové parametry, což je vzdálenost zde, pro kterou je vzdálenost funkcí NumPy, a jakmile splní kritéria, připojí shody k dobrým shodám a vrátí nalezené dobré shody, takže živý videostream řekne počet nalezených shod v rohu obrazovky.
Nyní se podívejme na kód pro výše uvedený popis:
import cv2 import numpy jako np def sift_detector (new_image, image_template): # Funkce, která porovnává vstupní obrázek se šablonou # Potom vrátí počet shod SIFT mezi nimi image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Vytvořit Objekt detektoru SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Získejte klíčové body a deskriptory pomocí SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2 = sift.detect Žádné) # Definujte parametry pro náš Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algoritmus = FLANN_INDEX_KDTREE, stromy = 3) search_params = dict (kontroly = 100) # Vytvořit objekt Flann dohazovač Flann = cv2.FlannBasedMatcher (index_params, search_params) # Získání zápasech za použití k-nejbližších sousedů Metoda # Výsledné ‚matchs‘je počet podobných zápasech nalezené v obou obrazů zápasů = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Uložte dobré shody pomocí testu poměru Lowe good_matches = pro m, n v zápasech: pokud m.distance <0,7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Načtěte naši šablonu obrázku, toto je náš referenční obrázek image_template = cv2.imread ('phone.jpg', 0), zatímco True: # Získejte obrázky webkamer ret, frame = cap.read () # Zjistit výšku a šířku výšky rámu webové kamery , width = frame.shape # Definovat ROI Box Rozměry 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)) # Nakreslete obdélníkové okno pro naši oblast zájmu cv2.rectangle (frame, (top_left_x, top_left_y)), (bottom_right_x, bottom_right_y), 255, 3) # Ořezové okno pozorování, které jsme definovali výše oříznuto = rám # Otočit orientaci rámu vodorovně rám = cv2.flip (rám, 1) # Získat počet shod SIFT = sift_detector (oříznuto, image_template) # Zobrazit stavový řetězec zobrazující aktuální číslo. shod cv2.putText (frame, str (match), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Náš práh pro označení objektu deteciton # Používáme 10, protože detektor SIFT vrací málo falešných hodnot práh = 10 # Pokud shody překročí naši prahovou hodnotu, pak byl detekován objekt, pokud shody> prahová hodnota: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, '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 je Enter Key break cap. Release () cv2.destroyAllWindows ()
Detekce objektů pomocí ORB
Detekce objektů pomocí SIFT je docela v pohodě a přesná, protože generuje mnohem přesný počet shod na základě klíčových bodů, ať už je to jakkoli patentované a to ztěžuje jeho použití pro komerční aplikace, druhou cestou je algoritmus ORB pro detekci objektů.
Podobně jako metoda detekce objektů pomocí SIFT, ve které jsme program rozdělili na dvě části, se bude postupovat stejně.
Nejprve definujeme funkci ORB_detector, která bere dva vstupy, jeden je obraz živého přenosu pocházející z webové kamery a druhý je obrazová šablona, na základě které budeme odpovídat našemu obrazu. Poté náš webovou kameru nastavíme ve stupních šedi a poté inicializujeme náš detektor ORB a nastavíme jej zde na 1000 klíčových bodů a parametry měřítka 1,2. s těmito parametry můžete snadno hrát, poté detekovat klíčové body (kp) a deskriptory (des) pro oba obrázky a druhý parametr, který definujeme ve funkci detectANDCompute, je ŽÁDNÝ, žádá o použití obrazové masky nebo ne a zde to popíráme.
Poté se přesuňte na detektor, který jsme dříve používali pomocí porovnávače založeného na FLANN, ale zde budeme používat BFMatcher a uvnitř BFMatcher definujeme dva parametry, jeden je NORM_HAMMING a druhý je crossCheck, jehož hodnota je PRAVDA.
Poté vypočítejte shody zápasů mezi těmito dvěma obrázky pomocí výše definovaných deskriptorů, které ve všech vrátí počet shod, protože tyto shody nejsou přibližné, a proto není třeba provádět test poměru Lowe, místo toho třídíme zápasy podle vzdálenosti, nejmenší vzdálenost, tím lepší je shoda (zde vzdálenost znamená vzdálenost mezi body), a na konci vrátíme počet shod pomocí funkce délky.
A v hlavní funkci nastavíme prahovou hodnotu na mnohem vyšší hodnotu, protože detektor koule generuje hodně šumu.
Nyní se podívejme na kód pro detekci založenou na ORB
import cv2 import numpy jako np def ORB_detector (new_image, image_template): # Funkce, která porovnává vstupní obrázek se šablonou # Potom vrátí počet shod ORB mezi nimi image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Vytvořit detektor ORB pomocí 1000 klíčových bodů s měřítkem pyramidového faktoru 1,2 orb = cv2.ORB_create (1000, 1,2) # Detekce klíčových bodů původního obrázku (kp1, des1) = orb.detectAndCompute (obrázek1, Žádný) # Detekce klíčových bodů otočeného obrázku (kp2, des2) = orb.detectAndCompute (image_template, None) # Create matcher # Poznámka, že již nepoužíváme odpovídající Flannbased bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Do zápasů = bf.match (des1, des2) # Třídit zápasy podle vzdálenosti. Nejmenší vzdálenost # je lepší shody = seřazeno (shody, klíč = lambda val: val.distance) návrat len (shody) cap = cv2.VideoCapture (0) # Načtěte naši šablonu obrázku, toto je náš referenční obrázek image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) while True: # Get images webcam ret, frame = cap.read () # Get height and width of webcam frame height, width = frame.shape # Definujte ROI Box Rozměry (Všimněte si, že některé z těchto věcí by měly být mimo smyčku) top_left_x = int (width / 3) top_left_y = int ((výška / 2) + (výška / 4)) bottom_right_x = int ((šířka / 3) * 2) bottom_right_y = int ((výška / 2) - (výška / 4)) # Nakreslete obdélníkové okno pro naši oblast zájmu cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Ořezové okno pozorování, které jsme definovali výše, oříznuto = rám # Flip orientace rámečku vodorovně rám = cv2.flip (rám, 1) # Získejte počet shod ORB = ORB_detector (oříznuto, image_template) # Zobrazit stavový řetězec zobrazující aktuální číslo. zápasů output_string = "Zápasy =" + str (shody) cv2.putText (frame, output_string, (50 450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0 150), 2) # Naše prahová hodnota pro označení detekce objektu # U nových obrázků nebo světelných podmínek budete možná muset trochu experimentovat # Poznámka: Detektor ORB pro získání prvních 1 000 shod, 350 je v podstatě minimální 35% prahová hodnota shody = 250 # Pokud zápasy překročí naši prahová hodnota, pak byl objekt detekován, pokud odpovídá> prahová hodnota: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Object Found', (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Object Detector using ORB', frame), pokud cv2.waitKey (1) == 13: # 13 je Enter Enter break cap.release () cv2.destroyAllWindows ()
Histogram orientovaných gradientů (HOG)
Nyní si promluvme o jiném deskriptoru, kterým je Histogram orientovaných gradientů (HOG).
HOG jsou do značné míry skvělé a užitečné deskriptory a jsou široce a úspěšně používány pro detekci objektů, jak je vidět dříve, deskriptory obrázků jako SIFT a ORB, kde musíme vypočítat klíčové body a pak musíme vypočítat deskriptory z těchto klíčových bodů, HOG to dělá jinak. To představuje objekty jako jediné funkce vektoru, na rozdíl od množiny příznakových vektorů, kde každý z nich představuje segment obrazu. To znamená, že máme jedinou vektorovou funkci pro celý obrázek.
Vypočítává se to detektorem posuvného okna nad obrazem, kde je pro každou pozici počítán deskriptor HOG. A pak se každá pozice zkombinuje do jednoho vektoru prvku.
Stejně jako SIFT je měřítko obrazu upraveno pyramidováním.
Dříve jsme používali srovnávače jako FLANN a BFMatcher, ale HOG to dělají jinak pomocí klasifikátorů SVM (support vector machine), kde každý HOG deskriptor, který je počítán, je přiváděn do klasifikátoru SVM, aby se zjistilo, zda byl objekt nalezen nebo ne.
Zde je odkaz na skvělý dokument od Dalala & Triggse o používání HOG pro detekci člověka:
Histogram orientovaných gradientů (HOG), krok za krokem:
Pochopení HOG může být docela složité, ale zde se budeme zabývat teorií HOG, aniž bychom se hlouběji zabývali matematikou, která s ní souvisí.
Pojďme tedy pořídit tento obrázek, který je trochu pixelovaný a v horním rohu je pole 8x8 pixelů, takže v tomto poli spočítáme vektor přechodu nebo orientaci hran u každého pixelu. To znamená, že v tomto poli vypočítáme vektor přechodu obrazu pixelů uvnitř rámečku (jsou jakýmsi směrem nebo tokem samotné intenzity obrazu), a to vygeneruje 64 (8 x 8) přechodových vektorů, které jsou pak reprezentovány jako histogram. Představte si tedy histogram, který představuje každý gradientní vektor. Pokud by tedy všechny body nebo intenzity lhaly jedním směrem, histogram pro tento směr řekněme 45 stupňů, histogram by měl vrchol při 45 stupních.
Takže teď děláme to, že rozdělíme každou buňku na úhlové koše, kde každý koš odpovídá směru přechodu (např. X, y). V dokumentech Dalal a Triggs použili 9 přihrádek 0 - 180 ° (po 20 ° každý koš). Tím se efektivně sníží 64 vektorů na pouhých 9 hodnot. To, co jsme udělali, je zmenšení velikosti, ale ponechání všech klíčových informací, které jsou potřeba.
Dalším krokem při výpočtu prasete je normalizace, normalizujeme přechody, abychom zajistili invariantnost ke změnám osvětlení, tj. Jas a kontrast.
Na tomto obrázku jsou hodnoty intenzity zobrazeny ve čtverci podle příslušného směru a všechny mají mezi sebou rozdíl 50
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Vydělíme vektory gradientovými velikostmi, které dostaneme 0,707 pro všechny, to je normalizace.
Podobně, pokud změníme intenzitu nebo změníme kontrast, dostaneme níže uvedené hodnoty.
∆ 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
Normalizace neprobíhá na úrovni buněk, místo toho probíhá na úrovni bloků, takže zde jsou bloky v zásadě skupinou 4 buněk, to bere v úvahu sousední bloky, takže se normalizuje při zohlednění větších segmentů obrazu.
Nyní se podívejme na kód
import numpy jako np import cv2 import matplotlib.pyplot jako plt # Načíst obrázek a pak ve stupních šedi image = cv2.imread ('elephant.jpg') šedá = cv2.cvtColor (obrázek, cv2.COLOR_BGR2GRAY) # Zobrazit původní obrázek cv2.imshow (' Vstupní obrázek ', obrázek) cv2.waitKey (0) # definování parametrů, velikost buňky a velikost bloku # hxw v pixelech cell_size = (8, 8) # hxw v buňkách block_size = (2, 2) # počet orientačních košů nbins = 9 # Použití OpenCV deskriptoru HOG # winSize je velikost obrázku oříznutá na násobek velikosti buňky hog = cv2.HOGDescriptor (_winSize = (grey.shape // cell_size * cell_size, grey.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) # Vytvořit použití tvaru numpy pole k vytvoření hog_features n_cells = (grey.shape // cell_size, grey.shape // cell_size) # Nejprve indexujeme bloky podle řádků. # hog_feats nyní obsahuje amplitudy gradientu pro každý směr, # pro každou buňku její skupiny pro každou skupinu. Indexování probíhá podle řádků a poté sloupců. hog_feats = hog.compute (grey).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Vytvořte naše pole přechodů s rozměry nbin pro uložení přechodových orientací přechody = np.zeros ((n_cells, n_cells, nbins)) # Vytvořte pole dimenzí cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Normalizace bloku pro off_y v rozsahu (block_size): pro off_x v rozsahu (block_size): přechody - 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 # Průměrné přechody přechody / = cell_count # Plot HOG pomocí Matplotlib # úhel je 360 / nbins * směr color_bins = 5 plt.pcolor (přechody) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('stejný', nastavitelný = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Obrázek ukazuje, jak je vstupní obraz reprezentován jako HOG reprezentace.
Kaskádové klasifikátory HAAR
Jak již bylo řečeno, můžeme z obrázku extrahovat funkce a použít je ke klasifikaci nebo detekci objektů.
Co jsou kaskádové klasifikátory HAAR?
Metoda detekce objektů, která vstupuje do Haarových prvků do řady klasifikátorů (kaskáda) k identifikaci objektů v obraze. Jsou vyškoleni v identifikaci jednoho typu objektu, ale můžeme je použít několik paralelně, např. Společně detekovat oči a tváře.
Vysvětlení HAAR klasifikátorů:
Klasifikátory HAAR jsou trénovány pomocí mnoha pozitivních obrazů (tj. Obrazů s přítomným objektem) a
negativních obrazů (tj. Obrazů bez přítomného objektu).
Jakmile máme tyto obrázky, extrahujeme prvky pomocí posuvných oken obdélníkových bloků. Tyto prvky (funkce HAAR) mají jednu hodnotu a počítají se odečtením součtu intenzit pixelů pod bílými obdélníky od černých obdélníků.
Jedná se však o směšné množství výpočtů, dokonce i pro základní okno 24 x 24 pixelů (vygenerováno 180 000 funkcí).
Vědci tedy vymysleli metodu nazvanou Integral Images, která to spočítala se čtyřmi odkazy na pole. Stále však měli 180 000 funkcí a většina z nich nepřidávala žádnou skutečnou hodnotu.
Posílení bylo poté použito k určení nejinformativnějších funkcí pomocí AdaBoost od společnosti Freund & Schapire a našlo nejinformativnější funkce na obrázku. Posílení je proces, při kterém používáme slabé klasifikátory k vytváření silných klasifikátorů, jednoduše přidělením přísnějších vážených pokut za nesprávné klasifikace. Snížení 180 000 funkcí na 6000, což je stále docela dost funkcí.
V těchto 6000 funkcích budou některé informativní než jiné. Takže pokud jsme nejprve použili nejinformativnější funkce, abychom zkontrolovali, zda region může mít potenciálně tvář (falešné poplachy nebudou velký problém). To eliminuje potřebu výpočtu všech 6000 funkcí najednou. Tento koncept se nazývá kaskáda klasifikátorů - pro detekci obličeje použila metoda Violy Jonesové 38 stupňů.
Detekce obličeje a očí
Takže poté, co jsme získali nějaké teoretické znalosti o HAAR kaskádách, budeme je konečně implementovat, aby bylo vše docela jasné, rozbijeme lekce po částech, nejprve bychom detekovali čelní tvář, poté se přesuneme k detekci čelní tváře oči a nakonec provedeme živou detekci obličeje a očí prostřednictvím webové kamery.
K tomu tedy použijeme předem vyškolené klasifikátory, které byly poskytnuty OpenCV jako soubory.xml, xml znamená rozšiřitelný značkovací jazyk, tento jazyk se používá k ukládání obrovského množství dat, můžete na něm dokonce vytvořit databázi.
Přístup k těmto klasifikátorům můžete získat na tomto odkazu .
Detekce obličeje
Zkusme detekci čelního obličeje, zde můžete mít přístup ke kaskádě detektoru čelního obličeje. Jednoduše rozbalte soubor zip a získáte soubor xml.
import numpy jako np import cv2 # Poukážeme funkci CascadeClassifier OpenCV na místo, kde je uložen náš # klasifikátor (formát souboru XML), nezapomeňte ponechat kód a klasifikátor ve stejné složce face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Načíst náš obrázek jej poté převede na stupně šedi image = cv2.imread ('Trump.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Náš klasifikátor vrací ROI detekovaného obličeje jako n-tici # Uloží vlevo nahoře souřadnice a vpravo dole souřadnice # vrátí seznam seznamů, které jsou umístěním různých detekovaných ploch. tváře = face_cascade.detectMultiScale (šedá, 1,3, 5) # Když nejsou detekovány žádné tváře, vrátí se face_classifier a vyprázdní n - tici, pokud jsou tváře (): print ("Nebyly nalezeny žádné tváře") # Iterujeme naším polem tváří a nakreslíme obdélník # přes každý obličej v obličejích pro (x, y, w, h) ve tvářích: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0 255), 2) cv2.imshow ('Face Detection', image) cv2.waitKey (0) cv2.destroyAllWindows ()
Nyní pojďme kombinovat detekci obličeje a očí společně, můžete mít přístup ke kaskádě detektoru očí ve stejném souboru zip.
import numpy jako np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') šedá = cv2.cvtolo cv2.COLOR_BGR2GRAY) tváře = face_classifier.detectMultiScale (šedá, 1,3, 5) # Když nejsou detekovány žádné tváře, vrátí se face_classifier a vyprázdní n - tici, pokud jsou tváře (): print ("No Face Found") pro (x, y, w, h) ve tvářích: 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) pro (ex, ey, ew, eh) v očích: 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)
Tento kód je tedy stejný jako kód pro detekci obličeje, ale zde jsme přidali oční kaskády a metodu jejich detekce, jak vidíte, vybrali jsme šedou verzi obličeje jako parametr pro detekciMultiScale pro oči, což nás přivádí ke snížení výpočtu, protože oči budeme detekovat pouze v této oblasti.
Živá detekce obličeje a očí
Takže dosud jsme prováděli detekci obličeje a očí, nyní implementujme to samé s živým video streamem z webové kamery. V tomto provedeme stejnou detekci obličeje a očí, ale tentokrát to provedeme pro živý přenos z webové kamery. Ve většině aplikací najdete svůj obličej zvýrazněný rámečkem kolem něj, ale tady jsme udělali něco jiného, že byste našli svůj obličej oříznutý a oči by se identifikovaly pouze v tom.
Takže zde importujeme klasifikátor obličeje i očí a definovali jsme funkci pro veškeré zpracování detekce obličeje a očí. A poté začal stream webové kamery a zavolal funkci detektoru obličeje pro detekci obličeje a očí. Parametr, který definujeme uvnitř funkce detektoru obličeje, jsou spojité obrazy ze živého streamu webové kamery
import cv2 import numpy jako np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0,5): # Převést obrázek na šedou stupnici (img, cv2.COLOR_BGR2GRAY) tváře = face_classifier.detectMultiScale (šedá, 1,3, 5) pokud tváře jsou (): vrací img pro (x, y, w, h) v tvářích: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2. obdélník (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = šedá roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) pro (ex, ey, ew, eh) v očích: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) návrat 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 is the Enter Key break cap.release () cv2.destroyAllWindows ()
Ladění kaskádových klasifikátorů
Parametry definované uvnitř detectMultiScale jiné než vstupní obraz mají následující význam
náš klasifikátor. detectMultiScale (vstupní obrázek, faktor měřítka, minimální sousedé)
- Scale Factor Určuje, o kolik zmenšíme velikost obrázku při každém změně měřítka. Například při detekci obličeje obvykle používáme 1.3. To znamená, že při každém zvětšení zmenšíme obrázek o 30%. Menší hodnoty, například 1,05, budou výpočet trvat déle, ale zvýší rychlost detekce.
- Min Neighbors Určuje počet sousedů, které by každé potenciální okno mělo mít, aby bylo považováno za pozitivní detekci. Typicky nastaveno mezi 3-6. Funguje jako nastavení citlivosti, nízké hodnoty někdy detekují více tváří na jedné tváři. Vysoké hodnoty zajistí méně falešných poplachů, ale některé tváře vám mohou chybět.
Detekce automobilů a chodců ve videích
Nyní ve videích detekujeme chodce a automobily pomocí HAAR kaskád, ale v případě, že se nenačte žádné video a nezkompiluje se kód bez chyby, musíte postupovat podle následujících kroků:
Pokud se po spuštění kódu nenačte žádné video, možná budete muset zkopírovat náš opencv_ffmpeg.dl z : opencv \ sources \ 3rdparty \ ffmpeg a vložit jej tam, kde je nainstalován váš python, např. C: \ Anaconda2
Jakmile je zkopírován, budete muset soubor přejmenovat podle verze OpenCV, kterou používáte. Např. Pokud používáte OpenCV 2.4.13, přejmenujte soubor jako: opencv_ffmpeg2413_64.dll nebo opencv_ffmpeg2413.dll (pokud jste pomocí stroje X86) opencv_ffmpeg310_64.dll nebo opencv_ffmpeg310.dll (pokud používáte stroj X86)
Chcete-li zjistit, kde je nainstalován python.exe, stačí spustit tyto dva řádky kódu, vytiskne se místo, kde je nainstalován python.
import tisku sys (sys.executable)
Nyní, pokud jste tyto kroky provedli úspěšně, pojďme přejít na kód pro detekci chodců, Kaskádu pro detekci chodců můžete mít zde a ze souboru zip zde připojeného.
import cv2 import numpy jako np # Vytvořte náš klasifikátor těla body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Zahajte nahrávání videa pro video soubor, zde používáme video soubor, ve kterém by byli detekováni chodci cap = cv2.VideoCapture ('walking.avi') # Smyčka, jakmile je video úspěšně načteno, zatímco cap.isOpened (): # Čtení každého snímku videa ret, frame = cap.read () # zde měníme velikost rámečku na polovinu jeho velikosti děláme, abychom zrychlili klasifikaci #, protože větší obrázky mají mnohem více oken, která se mohou sklouznout, takže celkově snižujeme rozlišení #of video o polovinu, to znamená 0,5, a také používáme rychlejší interpolační metodu, která je #interlinear frame = cv2.resize (frame, None, fx = 0,5, fy = 0,5, interpolation = cv2.INTER_LINEAR) grey = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Předejte rámec našemu klasifikátoru těl body = body_classifier.detectMultiScale (šedá, 1,2, 3) # Extrahujte ohraničující rámečky pro všechna těla identifikovaná pro (x, y, w, h) v tělech: cv2. obdélník (rám, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Chodci', rám), pokud cv2.waitKey (1) == 13: # 13 je Enter Key break cap. Release () cv2.destroyAllWindows ()
Po úspěšné detekci chodce ve videu přejdeme ke kódu pro detekci automobilu. Odtud můžete mít kaskádu pro detekci chodců.
import cv2 čas importu import numpy jako np # Vytvořte náš klasifikátor těla car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Zahajte snímání videa pro soubor videa cap = cv2.VideoCapture ('cars.avi') # Opakujte video úspěšně načten zatímco cap.isOpened (): time.sleep (.05) # Číst první snímek ret, frame = cap.read () grey = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Předat snímek našemu klasifikátoru automobilů cars = car_classifier.detectMultiScale (šedá, 1,4, 2) # Extrahujte ohraničující rámečky pro všechny subjekty identifikované pro (x, y, w, h) v automobilech: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Cars', frame) if cv2.waitKey (1) == 13: # 13 is the Enter Key break cap.release () cv2.destroyAllWindows ()
Všimli jste si, že jsme přidali time.sleep (.05) , je to jen zpoždění ve snímkové frekvenci, takže můžete potvrdit, že jsou všechny vozy správně identifikovány, nebo jej můžete snadno odstranit přidáním štítku s komentářem.
Tento článek je odkazován na Master Computer Vision ™ OpenCV4 v Pythonu s kurzem Deep Learning na Udemy, vytvořeným Rajeevem Ratanem, přihlaste se k odběru a dozvíte se více o Computer Vision a Pythonu.