- Objektdetektion ved hjælp af SIFT
- Objektdetektion ved hjælp af ORB
- Histogram af orienterede gradienter (HOG'er)
- Histogram af orienterede gradienter (HOG'er), trin for trin:
- HAAR-kaskadeklassifikatorer
- Ansigts- og øjenregistrering
- Live ansigts- og øjenregistrering
- Tuning Cascade Classifiers
- Bil- og fodgængerregistrering i videoer
Vi startede med at installere python OpenCV på windows og hidtil lavet nogle grundlæggende billedbehandling, billedsegmentering og objektdetektering ved hjælp af Python, som er beskrevet i nedenstående tutorials:
- Kom godt i gang med Python OpenCV: Installation og grundlæggende billedbehandling
- Billedmanipulationer i Python OpenCV (del 1)
- Billedmanipulationer i OpenCV (del-2)
- Billedsegmentering ved hjælp af OpenCV - Udpakning af specifikke områder af et billede
Vi lærte også om forskellige metoder og algoritmer til objektdetektering, hvor nogle nøglepunkter blev identificeret for hvert objekt ved hjælp af forskellige algoritmer. I denne vejledning skal vi bruge disse algoritmer til at registrere objekter i det virkelige liv, her bruger vi SIFT og ORB til påvisning.
Objektdetektion ved hjælp af SIFT
Her registreres objektdetektering ved hjælp af live webcam-stream, så hvis den genkender objektet, nævner det objekt, der blev fundet. I koden spilles hoveddelen af den funktion, der kaldes SIFT-detektor, det meste af behandlingen udføres af denne funktion.
Og i den anden halvdel af koden begynder vi med at åbne webcam-strømmen og derefter indlæse billedskabelonen, dvs. referencebilledet, det vil sige programmet rent faktisk kigger gennem webcam-strømmen.
Dernæst optager vi kontinuerligt billederne fra webcamstrømmen ved hjælp af uendelig mens sløjfe, og fanger derefter den tilsvarende højde og bredde af webcam-rammen og definerer derefter parametrene i feltet af interesse (ROI), hvor vores objekt kan passe ind ved at tage den tilsvarende højde og bredde på webcam-rammen. Og så tegner vi rektanglet fra de ROI-parametre, som vi havde defineret ovenfor. Beskær derefter endelig rektanglet og før det ind i SWIFT-detektordelen af koden.
Nu har SIFT-detektoren stort set to indgange, den ene er det beskårne billede og den anden er den billedskabelon, som vi tidligere har defineret, og så giver det os nogle matches, så matches er dybest set antallet af objekter eller tastatur, der ligner det beskårne billede og målbilledet. Derefter definerer vi en tærskelværdi for matches, hvis matchesværdien er større end tærsklen, sætter vi et billede, der findes på vores skærm med grøn farve af ROI-rektangel.
Lad os nu gå tilbage til hoveddelen af koden, den funktion, der kaldes SIFT-detektor, det tager input, da to billeder er det billede, hvor det leder efter objektet, og det andet er det objekt, som vi prøver at matche til (billedskabelon). Derefter skalerer du det første billede grå, og definer billedskabelonen som andet billede. Derefter opretter vi et SIFT-detektorobjekt og kører OpenCV SIFT-detekterings- og beregningsfunktionen, således at detektering af tastaturet og beregning af deskriptorer, deskriptorer er dybest set de vektorer, der gemmer informationen om tastaturerne, og det er virkelig vigtigt, når vi gør matchningen mellem beskrivelserne af billederne.
Og definer derefter den FLANN-baserede matcher, vi går ikke ind i den matematiske teori om at matche bag den, men du kan nemt Google om det. For det første skal du definere indekset kdtree til nul, og derefter indstiller vi indekset og søgeparametrene i ordbogformatet , vi definerer bare den algoritme, vi skal bruge, som er KDTREE, og antallet af træer, vi skal bruge, jo mere træ vi bruger jo mere kompliceret det bliver og langsommere. Og i søgeparameter definerer antallet af kontrol, hvilket stort set er antallet af matches, det skal gennemføres.
Og lav derefter vores FLANN-baserede matcherobjekt ved at indlæse den parameter, vi tidligere definerede, der er indeksparametre og søgeparametre, og på baggrund heraf oprette vores FLANN-baserede matcher, som er en KNN-matcher, hvor KNN er K-nærmeste naboer, dybest set er det en måde, hvor vi ser efter nærmeste matchere og deskriptorer, og vi matcher med initialiseringskonstant k. Nu returnerer denne FLANN-baserede matcher antallet af kampe, vi får.
FLANN-baseret matchning er bare en tilnærmelse, for at øge nøjagtigheden af den FLANN-baserede matcher udfører vi en Lowes forholdstest, og hvad den gør, er at den ser ud til kampene fra den knn flann-baserede matcher og definerer nogle matriske parametre, som er afstanden her, for hvilken afstand er en bedøvet funktion, og når den først opfylder kriterierne, skal du føje matchene til de gode matches og returnere de fundne gode matches, og så fortæller live-videostrømmen antallet af matches, der findes i hjørnet af skærmen.
Lad os nu se på koden til ovenstående beskrivelse:
import cv2 import numpy som np def sift_detector (new_image, image_template): # Funktion, der sammenligner inputbillede med skabelon # Det returnerer derefter antallet af SIFT-matches mellem dem image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_skabelon # Opret SIFT-detektorobjekt #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Få tastaturet og deskriptorerne ved hjælp af SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2Acompute Ingen) # Definer parametre for vores Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algoritme = FLANN_INDEX_KDTREE, træer = 3) search_params = dict (checks = 100) # Opret Flann Matcher-objektet flann = cv2.FlannBasedMatcher (index_params, search_params) # Få match ved hjælp af K-nærmeste nabo-metode # resultatet 'matches' er antallet af lignende matches, der findes i begge billedkampe = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Gem gode matches ved hjælp af Lowes forholdstest good_matches = for m, n i matches: hvis m.distance <0,7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Indlæs vores billedskabelon, dette er vores referencebillede image_template = cv2.imread ('phone.jpg', 0) mens True: # Få webcam-billeder ret, frame = cap.read () # Få højde og bredde på webcam rammehøjde, bredde = frame.shape # Definer ROI Box Dimensioner top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((bredde / 3) * 2) bottom_right_y = int ((højde / 2) - (højde / 4)) # Tegn rektangulært vindue til vores interesseområde cv2. Rektangel (ramme, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Beskæringsvindue til observation, vi definerede ovenfor beskåret = ramme # Vend rammens retning vandret ramme = cv2.flip (ramme, 1) # Få antal SIFT-matches matches = sift_detector (beskåret, image_template) # Vis statusstreng, der viser det aktuelle nr. af matches cv2.putText (frame, str (matches), (450.450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Vores tærskel til at indikere objektdeteciton # Vi bruger 10, da SIFT-detektoren returnerer små falske positiver tærskel = 10 # Hvis tændstikker overstiger vores tærskel, er objekt blevet detekteret, hvis tændstikker> tærskel: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Objekt fundet', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Objektdetektor ved hjælp af SIFT', ramme) hvis cv2.waitKey (1) == 13: # 13 er Enter Key break cap. Release () cv2.destroyAllWindows ()
Objektdetektion ved hjælp af ORB
Objektdetektering ved hjælp af SIFT er temmelig cool og nøjagtig, da det genererer et meget nøjagtigt antal matches baseret på tastatur, men det er patenteret, og det gør det svært at bruge det til kommercielle applikationer, den anden vej ud for det er ORB-algoritmen til genstandsdetektion.
Svarende til metoden til genkendelse af objekt ved SIFT, hvor vi delte programmet i to dele, vil det samme blive fulgt her.
For det første definerer vi funktionen ORB_detector, der tager to indgange, den ene er live stream-billedet, der kommer fra webkameraet, og det andet er billedskabelonen, på basis af hvilken vi skal matche vores billede. Derefter gråtoner vi vores webcam-billede og initialiserer derefter vores ORB-detektor, og vi indstiller det her til 1000 nøglepunkter og skaleringsparametre på 1,2. du kan nemt lege med disse parametre og derefter registrere tastaturet (kp) og deskriptorer (des) for både billederne, og den anden parameter, vi definerer i detectANDCompute- funktionen, er INGEN, det beder om brug af billedmaske eller ej og vi benægter det her.
Flyt derefter til detektoren tidligere, vi har brugt FLANN-baseret matcher, men her bruger vi BFMatcher, og inden i BFMatcher definerer vi to parametre, den ene er NORM_HAMMING, og den anden er krydskontrollen, hvis værdi er SAND.
Beregn derefter matchene matches mellem disse to billeder ved hjælp af beskrivelserne defineret ovenfor, som i alt returnerer antallet af matches, da disse matches ikke er tilnærmelsesvis, og derfor er der ikke behov for at lave Lowes forholdstest, i stedet sorterer vi matches baseret på afstand, mindst afstanden mere match er bedre (her betyder afstanden afstand mellem punkterne), og i slutningen returnerer vi antallet af matches ved hjælp af længdefunktionen.
Og i hovedfunktionen indstiller vi tærsklen til en meget højere værdi, da orb-detektor genererer meget støj.
Lad os nu se på kode til ORB-baseret detektion
import cv2 import numpy som np def ORB_detector (new_image, image_template): # Funktion, der sammenligner inputbillede med skabelon # Det returnerer derefter antallet af ORB-matches mellem dem image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Opret ORB-detektor med 1000 tastaturer med en skaleringspyramidefaktor på 1,2 orb = cv2.ORB_create (1000, 1.2) # Registrer tastaturet for det originale billede (kp1, des1) = orb.detectAndCompute (image1, None) # Registrer tastaturet for det roterede billede (kp2, des2) = orb.detectAndCompute (image_template, None) # Opret matcher # Bemærk, vi bruger ikke længere Flannbased matching bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Gør matchende matches = bf.match (des1, des2) # Sorter matches baseret på afstand. Mindste afstand # er bedre matches = sorteret (matches, key = lambda val: val.distance) return len (matches) cap = cv2.VideoCapture (0) # Indlæs vores billedskabelon, dette er vores referencebillede image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) mens True: # Få webcam-billeder ret, frame = cap.read () # Få højde og bredde på webcam-frame højde, width = frame.shape # Define ROI Box Dimensions (Bemærk, nogle af disse ting skal være uden for sløjfen) top_left_x = int (width / 3) top_left_y = int ((højde / 2) + (højde / 4)) bottom_right_x = int ((bredde / 3) * 2) bottom_right_y = int ((højde / 2) - (højde / 4)) # Tegn rektangulært vindue til vores interesseområde cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Beskæringsvindue for observation, vi definerede ovenfor beskåret = ramme # Vend rammens retning vandret ramme = cv2.flip (ramme, 1) # Få antal ORB-matches matches = ORB_detector (beskåret, image_template) # Vis statusstreng, der viser det aktuelle nr. af matches output_string = "Matches =" + str (matches) cv2.putText (frame, output_string, (50.450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Vores tærskel for at indikere objekt deteciton # For nye billeder eller lynnedslag betingelser, du kan få brug for at eksperimentere lidt # Bemærk: ORB detektor for at få de øverste 1000 kampe, 350 er i alt væsentligt en min match 35% tærskel = 250 # Hvis kampe overskrider vores tærskel så er detekteret objekt, hvis det matcher> tærskel: 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 ('Objektdetektor ved hjælp af ORB', ramme) hvis cv2.waitKey (1) == 13: # 13 er Enter Key break break cap.release () cv2.destroyAllWindows ()
Histogram af orienterede gradienter (HOG'er)
Lad os nu tale om en anden deskriptor, som er histogram af orienterede gradienter (HOG'er).
HOG'er er stort set seje og nyttige deskriptorer, og de bruges i vid udstrækning og med succes til objektdetektering, som tidligere set billedbeskrivere som SIFT og ORB, hvor vi skal beregne tastaturet og derefter skulle beregne deskriptorer ud af disse tastaturer, HOG'er gør den proces anderledes. Det repræsenterer objekter som en enkelt funktionsvektor i modsætning til et sæt funktionsvektorer, hvor hver repræsenterer et segment af billedet. Det betyder, at vi har en enkelt vektorfunktion til hele billedet.
Det beregnes af en glidende vinduesdetektor over et billede, hvor en HOG-deskriptor beregnes for hver position. Og så kombineres hver position til en enkelt funktionsvektor.
Ligesom SIFT justeres billedets skala ved pyramiding.
Tidligere har vi brugt matchere som FLANN og BFMatcher, men HOG'er gør det forskelligt ved hjælp af SVM-klassifikatorer (support vector machine), hvor hver HOG-deskriptor, der beregnes, føres til en SVM-klassifikator for at bestemme, om objektet blev fundet eller ej.
Her er linket til et stort papir fra Dalal & Triggs om brug af HOG'er til human detektion:
Histogram af orienterede gradienter (HOG'er), trin for trin:
At forstå HOG'er kunne være ret kompleks, men her vil vi kun beskæftige os med HOG's teori uden at gå dybere ind i matematikken, der er relateret til den.
Så lad os tage dette billede, det er lidt pixeleret lidt, og i det øverste hjørne er der 8x8 pixelboks her, så i dette felt beregner vi gradientvektoren eller kantorienteringen ved hver pixel. Så det betyder, at i dette felt beregner vi billedgradientvektoren for pixels inde i boksen (de er en slags retning eller flow af selve billedintensiteten), og dette genererer 64 (8 x 8) gradientvektorer, som derefter er repræsenteret som et histogram. Så forestil dig et histogram, der repræsenterer hver gradientvektor. Så hvis alle punkter eller intensiteter løj i en retning, lad os sige histogram for den retning 45 grader, histogrammet ville have en top på 45 grader.
Så hvad vi gør nu er, at vi deler hver celle i vinklede kasser, hvor hver kasse svarer til en gradientretning (f.eks. X, y). I Dalal- og Triggs-papiret brugte de 9 kasser 0-180 ° (20 ° hver kasse). Dette reducerer effektivt 64 vektorer til kun 9 værdier. Så hvad vi har gjort er reduceret størrelse, men gemt alle de nøgleoplysninger, der er nødvendige.
Næste trin i beregningen af svinene er normaliseringen, vi normaliserer gradienterne for at sikre uforanderlighed til lysændringer, dvs. lysstyrke og kontrast.
I dette billede vises intensitetsværdierne i firkanten i henhold til den respektive retning og har alle forskellen på 50 mellem hinanden
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Vi deler vektorerne med gradientstørrelserne, vi får 0,707 for alle, dette er normalisering.
Tilsvarende, hvis vi ændrer intensiteten eller ændrer kontrasten, får vi nedenstående værdier.
∆ 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
Normalisering finder ikke sted på celleniveau, men i stedet foregår det på et blokniveau, så her er blokkene grundlæggende en gruppe på 4 celler, dette tager højde for naboblokke, så normaliser under hensyntagen til større segmenter af billedet.
Lad os nu se på koden
import numpy som np import cv2 import matplotlib.pyplot som plt # Indlæs billede og derefter gråtonebillede = cv2.imread ('elephant.jpg') grå = cv2.cvtColor (billede, cv2.COLOR_BGR2GRAY) # Vis originalbillede cv2.imshow (' Inputbillede ', billede) cv2.waitKey (0) #definerer parametre, cellestørrelse og blokstørrelse # hxw i pixels cell_size = (8, 8) # hxw i celler block_size = (2, 2) # antal orienteringsbakker nbins = 9 # Brug af OpenCVs HOG-deskriptor # winSize er størrelsen på billedet, der er beskåret til et multipel af cellestørrelsen hog = cv2.HOGDescriptor (_winSize = (grå.form // cellestørrelse * cellestørrelse, grå.form // cellestørrelse * cellestørrelse), _blockSize = (blokstørrelse * cellestørrelse, blokstørrelse * cellestørrelse), _blockStride = (cellestørrelse, cellestørrelse), _cellSize = (cellestørrelse, cellestørrelse), _nbins = nbins) # Opret numpy arrayform, som vi bruger for at oprette hog_features n_cells = (grå.form // cellestørrelse, grå.form // cellestørrelse) # Vi indekserer blokke efter rækker først. # hog_feats indeholder nu gradientamplituderne for hver retning, # for hver celle i sin gruppe for hver gruppe. Indeksering sker efter rækker og derefter kolonner. hog_feats = hog.compute (grå). reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Opret vores gradienter-array med nbin-dimensioner for at gemme gradientorienteringsgradienter = np.zeros ((n_cells, n_cells, nbins)) Opret array af dimensioner cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Blok Normalisering for off_y i rækkevidde (block_size): for off_x i range (block_size): gradienter - 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 # Gennemsnitlige gradienter gradienter / = celletal # Plot HOG'er ved hjælp af Matplotlib # vinkel er 360 / nbins * retning color_bins = 5 plt.pfarve (gradienter) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('lige', justerbar = 'boks') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Billedet viser, hvordan inputbilledet er repræsenteret som HOG-repræsentation.
HAAR-kaskadeklassifikatorer
Som tidligere diskuteret kan vi udtrække funktioner fra et billede og bruge disse funktioner til at klassificere eller opdage objekter.
Hvad er HAAR Cascade Classifiers?
En metode til genkendelse af objekter, der indsætter Haar-funktioner i en række klassifikatorer (kaskade) for at identificere objekter i et billede. De er trænet i at identificere en type genstand, men vi kan bruge flere af dem parallelt, fx at opdage øjne og ansigter sammen.
HAAR-klassifikatorer forklaret:
HAAR-klassifikatorer trænes ved hjælp af masser af positive billeder (dvs. billeder med objektet til stede) og
negative billeder (dvs. billeder uden objektet til stede).
Når vi først har disse billeder, udtrækker vi derefter funktioner ved hjælp af glidende vinduer i rektangulære blokke. Disse funktioner (HAAR-funktioner) er enkeltværdierede og beregnes ved at trække summen af pixelintensiteter under de hvide rektangler fra de sorte rektangler.
Dette er dog et latterligt antal beregninger, selv for et basisvindue på 24 x 24 pixels (180.000 genererede funktioner).
Så forskerne udtænkte en metode kaldet Integral Images, der beregnede dette med fire matrixreferencer. De havde dog stadig 180.000 funktioner, og de fleste tilføjede ingen reel værdi.
Boosting blev derefter brugt til at bestemme de mest informative træk med Freund & Schapires AdaBoost, og det fandt mest informative træk i billedet. Boosting er den proces, hvor vi bruger svage klassifikatorer til at opbygge stærke klassifikatorer, simpelthen ved at tildele tungere vægtede sanktioner på forkerte klassifikationer. At reducere de 180.000 funktioner til 6000, hvilket stadig er en hel del funktioner.
I disse 6000 funktioner vil nogle være mere informative end andre. Så hvis vi brugte de mest informative funktioner til først at kontrollere, om regionen potentielt kan have et ansigt (falske positive vil ikke være noget stort problem). Dette eliminerer behovet for at beregne alle 6000 funktioner på én gang. Dette koncept kaldes Cascade of Classifiers - til ansigtsgenkendelse brugte Viola Jones-metoden 38 faser.
Ansigts- og øjenregistrering
Så efter at have fået noget teoretisk viden om HAAR-kaskaderne, vil vi endelig implementere det, for at gøre tingene ret meget klare, vil vi bryde lektionerne i dele, først opdager vi frontal ansigt efter det, vi bevæger os for at opdage frontal face med og til sidst ville vi live registrere ansigt og øjne gennem webkameraet.
Så til dette vil vi bruge foruddannede klassificeringsapparater, der er leveret af OpenCV som.xml-filer, xml står for udvideligt markup-sprog, dette sprog bruges til at gemme store mængder data, du kan endda bygge en database på det.
Du kan få adgang til disse klassifikatorer på dette link .
Ansigtsgenkendelse
Lad os prøve at registrere frontal ansigt, du kan få adgang til kaskaden af frontal face detector her. Uddrag bare zip-filen for at hente xml-filen.
import numpy som np import cv2 # Vi peger OpenCVs CascadeClassifier- funktion, hvor vores # classifier (XML-filformat) er gemt, husk at opbevare koden og klassifikatoren i den samme mappe face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load vores billede konverter det derefter til gråtonebillede = cv2.imread ('Trump.jpg') grå = cv2.cvtColor (billede, cv2.COLOR_BGR2GRAY) # Vores klassifikator returnerer ROI for det opdagede ansigt som en tuple # Det gemmer øverst til venstre koordinere og nederst til højre koordinater # det returnerer listen over lister, som er placeringen af forskellige opdagede ansigter. ansigter = face_cascade.detectMultiScale (grå, 1.3, 5) # Når der ikke registreres ansigter, vender ansigt_klassifikator tilbage og tom tuple, hvis ansigter er (): udskriv ("Ingen ansigter fundet") # Vi gentages gennem vores ansigtsarray og tegner et rektangel # over hvert ansigt i ansigter for (x, y, w, h) i ansigter: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Face Detection', image) cv2.waitKey (0) cv2.destroyAllWindows ()
Lad os nu kombinere ansigt og øjenregistrering sammen, du kan få adgang til kaskaden af øjendetektor i den samme zip-fil.
importer numpy som np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') grå = cv2.cread cv2.COLOR_BGR2GRAY) ansigter = face_classifier.detectMultiScale (grå, 1.3, 5) # Når der ikke registreres ansigter, returneres face_classifier og tom tuple, hvis ansigter er (): udskriv ("Intet ansigt fundet") for (x, y, w, h) i ansigter: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = grå roi_color = img øjne = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) til (ex, ey, ew, eh) i øjnene: 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)
Så denne kode er lige så meget som koden til ansigtsgenkendelse, men her har vi tilføjet øjenkaskader og metode til at detektere dem, som du kan se, har vi valgt den grå skalerede version af ansigtet som parameter for detekterMultiScale for øjnene, hvilket bringer os til reduktionen i beregningen, da vi kun kun registrerer øjne i dette område.
Live ansigts- og øjenregistrering
Så indtil nu har vi gjort ansigts- og øjenregistrering, lad os nu implementere det samme med live-videostrømmen fra webkameraet. I dette vil vi udføre den samme detektion af ansigt og øjne, men denne gang vil vi gøre det for live stream fra webkameraet. I det meste af applikationen ville du finde dit ansigt fremhævet med en boks omkring det, men her har vi gjort noget anderledes, som du ville finde dit ansigt beskåret ud, og øjnene kun kunne identificere sig i det.
Så herinde importerer vi både ansigts- og øjenklassifikatoren og definerede en funktion til at udføre al behandling til ansigt og øjenregistrering. Og derefter startede webcamstrømmen og kaldte ansigtsdetektorfunktionen for at få ansigt og øjne registreret. Parameteren, vi definerer inde i ansigtsdetektorfunktionen, er de kontinuerlige billeder fra live web cam stream
import cv2 import numpy som np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, størrelse = 0.5): # Konverter billede til cvcale. (img, cv2.COLOR_BGR2GRAY) ansigter = face_classifier.detectMultiScale (grå, 1.3, 5) hvis ansigter er (): returner img for (x, y, w, h) i ansigter: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2. rektangel (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = grå roi_color = img øjne = eye_classifier.detectMultiScale (roi_gray) for (ex, ey, ew, eh) i øjnene: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) returner roi_color cap = cv2.VideoCapture (0) mens True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) hvis cv2.waitKey (1) == 13: # 13 er Enter Key break cap.release () cv2.destroyAllWindows ()
Tuning Cascade Classifiers
De parametre, der er defineret i detectMultiScale bortset fra inputbilledet, har følgende betydning
vores klassifikator. detectMultiScale (inputbillede, skaleringsfaktor, min naboer)
- Scale Factor Angiver, hvor meget vi reducerer billedstørrelsen, hver gang vi skalerer. F.eks. I ansigtsgenkendelse bruger vi typisk 1.3. Dette betyder, at vi reducerer billedet med 30%, hver gang det skaleres. Mindre værdier, som 1.05, tager længere tid at beregne, men vil øge detektionsgraden.
- Min naboer Angiver antallet af naboer, som hvert potentielt vindue skal have for at betragte det som en positiv detektion. Indstilles typisk mellem 3-6. Det fungerer som følsomhedsindstilling, lave værdier registrerer undertiden flere ansigter over et enkelt ansigt. Høje værdier vil sikre mindre falske positive, men du kan gå glip af nogle ansigter.
Bil- og fodgængerregistrering i videoer
Nu registrerer vi fodgængere og biler i videoer ved hjælp af HAAR-kaskaderne, men i tilfælde af at ingen video indlæses, og kodekompilering uden en fejl skal du følge følgende trin:
Hvis der ikke indlæses nogen video efter kørsel af kode, skal du muligvis kopiere vores opencv_ffmpeg.dl fra : opencv \ sources \ 3rdparty \ ffmpeg for at indsætte den, hvor din python er installeret, f.eks. C: \ Anaconda2
Når den er kopieret, skal du omdøbe filen i henhold til den version af OpenCV, du bruger. Eg, hvis du bruger OpenCV 2.4.13, og omdøb derefter filen til: opencv_ffmpeg2413_64.dll eller opencv_ffmpeg2413.dll (hvis du er ved hjælp af en X86-maskine) opencv_ffmpeg310_64.dll eller opencv_ffmpeg310.dll (hvis du bruger en X86-maskine)
For at finde ud af, hvor du python.exe er installeret, skal du bare køre disse to linier kode, det vil udskrive det sted, hvor python er installeret.
importer sys- udskrivning (sys.executable)
Nu, hvis du har udført disse trin med succes, lad os gå til koden til detektering af fodgængere, Du kan få kaskaden til detektering af fodgængere og fra zip-filen vedhæftet her.
import cv2 import numpy som np # Opret vores body classifier body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Start videooptagelse til videofil, her bruger vi den videofil, hvor fodgængere vil blive opdaget cap = cv2.VideoCapture ('walking.avi') # Sløjfe, når videoen er indlæst med succes, mens cap.isOpened (): # Læsning af hvert billede i videoen ret, frame = cap.read () # her ændrer vi størrelsen på rammen til halvdelen af dens størrelse, vi gør for at fremskynde klassificeringen #, da større billeder har meget flere vinduer at glide over, så generelt reducerer vi opløsningen # af video med det halve, det er, hvad 0,5 indikerer, og vi bruger også hurtigere interpolationsmetode, der er #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) grå = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Send ramme til vores kropsklassifikationslegemer = body_classifier.detectMultiScale (grå, 1.2, 3) # Uddrag afgrænsningsfelter for alle organer identificeret for (x, y, w, h) i kroppe: cv2 rektangel (ramme, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('fodgængere', ramme) hvis cv2.waitKey (1) == 13: # 13 er Enter Key break cap. Release () cv2.destroyAllWindows ()
Efter at have fundet en fodgænger i video, lad os gå til koden til bilregistrering. Du kan få kaskaden til detektering af fodgængere herfra.
import cv2 importtid import numpy som np # Opret vores body classifier car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Start videooptagelse til videofil cap = cv2.VideoCapture ('cars.avi') # Loop, når videoen er vellykket indlæst mens cap.isOpened (): time.sleep (.05) # Læs første frame ret, frame = cap.read () grå = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Videregiv ramme til vores bilklassificeringsbiler = car_classifier.detectMultiScale (grå, 1.4, 2) # Uddrag afgrænsningsfelter for alle organer identificeret for (x, y, w, h) i biler: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Biler', ramme) hvis cv2.waitKey (1) == 13: # 13 er Enter Key break break cap. release () cv2.destroyAllWindows ()
Du har bemærket, at vi har tilføjet time.sleep (.05) , det er bare en forsinkelse i billedhastighed, så du kan bekræfte, at alle biler er korrekt identificeret, eller du kan nemt fjerne det bare ved at tilføje en kommentaretiket til det.
Denne artikel henvises fra Master Computer Vision ™ OpenCV4 i Python med Deep Learning kursus om Udemy, oprettet af Rajeev Ratan, abonner på den for at lære mere om Computer Vision og Python.