- Objektdeteksjon ved hjelp av SIFT
- Objektdeteksjon ved hjelp av ORB
- Histogram av orienterte gradienter (HOG)
- Histogram av orienterte gradienter (HOG), trinn for trinn:
- HAAR kaskadeklassifiserere
- Ansikts- og øyedeteksjon
- Live ansikts- og øyedeteksjon
- Tuning Cascade Classifiers
- Bil- og fotgjengeroppdagelse i videoer
Vi startet med å installere python OpenCV på windows og har så langt gjort noen grunnleggende bildebehandling, bildesegmentering og gjenkjenning av objekter ved hjelp av Python, som er beskrevet i tutorials nedenfor:
- Komme i gang med Python OpenCV: Installasjon og grunnleggende bildebehandling
- Bildemanipulasjoner i Python OpenCV (del 1)
- Bildemanipulasjoner i OpenCV (del 2)
- Bildesegmentering ved hjelp av OpenCV - trekker ut spesifikke områder av et bilde
Vi lærte også om ulike metoder og algoritmer for objektgjenkjenning der noen viktige punkter ble identifisert for hvert objekt ved hjelp av forskjellige algoritmer. I denne opplæringen skal vi bruke disse algoritmene til å oppdage virkelige objekter, her bruker vi SIFT og ORB for deteksjonen.
Objektdeteksjon ved hjelp av SIFT
Her vil objektgjenkjenning gjøres ved hjelp av live webcam-strøm, så hvis den gjenkjenner objektet, vil det nevne at objektet ble funnet. I koden spilles hoveddelen av funksjonen som kalles SIFT-detektor, det meste av behandlingen gjøres av denne funksjonen.
Og i den andre halvdelen av koden begynner vi med å åpne webkamera-strømmen, og laster deretter inn bildemalen, dvs. referansebildet, det vil si at programmet faktisk ser gjennom webkamera-strømmen.
Deretter tar vi kontinuerlig bildene fra webkamera-strømmen ved hjelp av uendelig mens sløyfe, og tar deretter den tilsvarende høyden og bredden på webkamera-rammen, og definerer deretter parametrene for regionen av interesse (ROI) der objektet vårt kan passe inn ved å ta tilsvarende høyde og bredde på webkamera-rammen. Og så tegner vi rektangelet fra ROI-parameterne som vi hadde definert ovenfor. Deretter til slutt beskjære rektangelet og mate det inn i SWIFT-detektoren av koden.
Nå har SIFT-detektoren i utgangspunktet to innganger, den ene er det beskårne bildet og det andre er bildemalen som vi tidligere har definert, og så gir det oss noen treff, så fyrstikker er i utgangspunktet antall objekter eller tastatur som er like i det beskårne bildet og målbildet. Deretter definerer vi en terskelverdi for treffene, hvis treffverdien er større enn terskelen, setter vi et bilde funnet på skjermen vår med en grønn farge på ROI-rektangelet.
La oss nå gå tilbake til hoveddelen av koden, funksjonen som kalles SIFT-detektor, den tar inngangen som to bilder, det ene er bildet der det leter etter objektet, og det andre er objektet som vi prøver å matche til (bildemal). Grå skaler deretter det første bildet og definer bildemalen som andre bilde. Deretter oppretter vi et SIFT-detektorobjekt og kjører OpenCV SIFT-deteksjons- og beregningsfunksjonen, for å oppdage tastaturene og beregne deskriptorene, deskriptorene er i utgangspunktet vektorene som lagrer informasjonen om tastaturene, og det er veldig viktig når vi gjør matching mellom beskrivelsene av bildene.
Og så definer FLANN-basert matcher, vi går ikke inn på den matematiske teorien om å matche bak den, men du kan enkelt Google om det. For det første definerer du indeksen kdtree til null og deretter setter vi indeksen og søkeparametrene i ordbokformatet, vi definerer bare algoritmen vi skal bruke som er KDTREE, og antall trær vi skal bruke, jo mer tre vi bruker jo mer komplisert det blir og tregere. Og i søkeparameter definerer du antall sjekker, som i utgangspunktet er antall treff det skal fullføres.
Og lag deretter vårt FLANN-baserte matcherobjekt ved å laste inn parameteren vi tidligere definerte, som er indeksparametere og søkeparametere, og basert på dette oppretter vi vårt FLANN-baserte matcher, som er en KNN-matcher der KNN er K-nærmeste naboer, i utgangspunktet er det en måte der vi ser etter nærmeste matchere og beskrivere, og vi gjør matching med initialiseringskonstant k. Nå returnerer denne FLANN-baserte matcheren antall kamper vi får.
FLANN-basert matching er bare en tilnærming, slik at vi øker nøyaktigheten til den FLANN-baserte matcheren, vi utfører en Lowes ratio-test, og hva den gjør er at den ser etter kampene fra den knn flann-baserte matcheren og definerer noen matrikkeparametere som er avstanden her, for hvilken avstand er en nummen funksjon, og når den oppfyller kriteriene, legg kampene til de gode kampene og returnerer de gode kampene som er funnet, og slik forteller live videostrømmen antall treff som er funnet på hjørnet av skjermen.
La oss nå se på koden for beskrivelsen ovenfor:
import cv2 import numpy as np def sift_detector (new_image, image_template): # Funksjon som sammenligner inngangsbilde med mal # Den returnerer deretter antall SIFT-treff mellom dem image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Create SIFT-detektorobjekt #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Skaff tastaturene og deskriptorene ved hjelp av SIFT- tastatur_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2Acompute Ingen) # Definer parametere for Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algoritme = FLANN_INDEX_KDTREE, trær = 3) search_params = dict (sjekker = 100) # Lag Flann Matcher objektet Flann = cv2.FlannBasedMatcher (index_params, search_params) # Skaff kampene ved hjelp av K-Nærmeste nabo Metode # resultat 'matchs' er antall lignende treff i både bilder kampene = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Lagre gode treff ved bruk av Lowes forholdstest good_matches = for m, n i treff: hvis m avstand <0,7 * n avstand: god_matches.append (m) returner len (good_matches) cap = cv2.VideoCapture (0) # Last inn bildemalen vår, dette er vårt referansebilde image_template = cv2.imread ('phone.jpg', 0) mens True: # Få bilder av webkamera ret, frame = cap.read () # Få høyde og bredde på webkamera rammehøyde , width = frame.shape # Definer ROI Box Dimensjoner top_left_x = int (width / 3) top_left_y = int ((høyde / 2) + (høyde / 4)) bottom_right_x = int ((bredde / 3) * 2) bottom_right_y = int ((høyde / 2) - (høyde / 4)) # Tegn rektangulært vindu for vår region av interesse cv2. Rektangel (ramme, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Beskjæringsvindu for observasjon vi definerte ovenfor beskåret = ramme # Vend rammeorientering horisontalt ramme = cv2.flip (ramme, 1) # Få antall SIFT- treff = sift_detector (beskåret, image_template) # Vis statusstreng som viser gjeldende nr. av treff cv2.putText (ramme, str (treff), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Vår terskel for å indikere objektdeteksjon # Vi bruker 10 siden SIFT-detektoren returnerer lite falske positiver terskel = 10 # Hvis treff overstiger terskelen vår, så har objektet blitt oppdaget hvis treff: terskel: cv2.rectangle (ramme, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2., '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 er Enter Key break cap. Release () cv2.destroyAllWindows ()
Objektdeteksjon ved hjelp av ORB
Objektdeteksjon ved hjelp av SIFT er ganske kult og nøyaktig, siden det genererer et mye nøyaktig antall treff basert på tastatur, men det er patentert, og det gjør det vanskelig å bruke det til kommersielle applikasjoner, den andre veien ut for det er ORB-algoritmen for gjenkjenning av objekter.
I likhet med metoden for gjenkjenning av SIFT der vi delte programmet i to deler, vil det samme bli fulgt her.
For det første definerer vi funksjonen ORB_detector som tar to innganger, den ene er live stream-bildet som kommer fra webkameraet, og det andre er bildemalen på grunnlag av hvilken vi skal matche bildet vårt. Deretter gråtoner vi webkameraet vårt og initialiserer deretter ORB-detektoren, og vi setter den her til 1000 nøkkelpunkter og skaleringsparametere på 1,2. du kan enkelt leke med disse parametrene, og deretter oppdage tastaturene (kp) og deskriptorene (des) for begge bildene, og den andre parameteren vi definerer i detectANDCompute- funksjonen er INGEN, det ber om bruk av bildemaske eller ikke og vi benekter det her.
Gå deretter til detektoren tidligere, vi har brukt FLANN-basert matcher, men her skal vi bruke BFMatcher, og inne i BFMatcher definerer vi to parametere, den ene er NORM_HAMMING og den andre er kryssjekken hvis verdi er SANT.
Deretter beregner du treffene mellom de to bildene ved hjelp av beskrivelsene som er definert ovenfor, som i alt returnerer antall treff siden disse treffene ikke er tilnærmet, og det er derfor ikke nødvendig å gjøre Lowes forholdstest, i stedet sorterer vi treffene basert på avstand, minst avstanden mer kampen er bedre (her betyr avstanden avstand mellom poengene), og til slutt returnerer vi antall kamper ved hjelp av lengdefunksjon.
Og i hovedfunksjonen setter vi terskelen til en mye høyere verdi, siden orbdetektor genererer mye støy.
La oss nå se på koden for ORB-basert gjenkjenning
importer cv2 import numpy som np def ORB_detector (new_image, image_template): # Funksjon som sammenligner inngangsbilde med mal # Den returnerer deretter antall ORB-samsvar mellom dem image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Lag ORB-detektor med 1000 tastatur med en skaleringspyramidefaktor på 1,2 orb = cv2.ORB_create (1000, 1.2) # Oppdag tastaturene til det originale bildet (kp1, des1) = orb.detectAndCompute (image1, None) # Oppdag tastaturene for rotert bilde (kp2, des2) = orb.detectAndCompute (image_template, None) # Lag matcher # Merk at vi ikke lenger bruker Flannbasert matching bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Gjør samsvarende treff = bf.match (des1, des2) # Sorter kampene basert på avstand. Minste avstand # er bedre treff = sortert (treff, nøkkel = lambda val: val. Avstand) returner len (treff) cap = cv2.VideoCapture (0) # Last inn bildemalen vår, dette er vårt referansebilde image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('bilder / kitkat.jpg', 0) mens oppfylt: # get webkamera bilder ret, rammen = cap.read () # get høyde og bredde av webkamera rammehøyden, width = frame.shape # Define ROI Box Dimensions (Merk at noen av disse tingene skal være utenfor løkken) top_left_x = int (width / 3) top_left_y = int ((høyde / 2) + (høyde / 4)) bottom_right_x = int ((bredde / 3) * 2) bottom_right_y = int ((høyde / 2) - (høyde / 4)) # Tegn rektangulært vindu for vår interesseområde cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Beskjæringsvindu for observasjon vi definerte ovenfor beskåret = ramme # Vend rammeorientering horisontalt ramme = cv2.flip (ramme, 1) # Få antall ORB-treff = ORB_detector (beskåret, bildemal) # Vis statusstreng som viser gjeldende nr. av treff output_string = "Matches =" + str (matches) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Terskelen vår for å indikere objektdeteksjon # For nye bilder eller lysforhold kan det hende du må eksperimentere litt # Merk: ORB-detektoren for å få de 1000 beste treffene, er 350 egentlig en terskel på minst 35% = 250 # Hvis fyrstikker overstiger terskel så har objekt blitt oppdaget hvis samsvarer med> terskel: 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) if cv2.waitKey (1) == 13: # 13 er Enter Key break break cap.release () cv2.destroyAllWindows ()
Histogram av orienterte gradienter (HOG)
La oss nå snakke om en annen deskriptor som er Histogram of Oriented Gradients (HOG).
HOG-er er ganske kule og nyttige beskrivelser, og de brukes mye og vellykket for gjenkjenning av objekter, som tidligere sett er bildebeskrivere som SIFT og ORB der vi må beregne tastatur og deretter må beregne beskrivelser ut av disse tastene, HOG gjør den prosessen annerledes. Den representerer objekter som en enkelt funksjonsvektor i motsetning til et sett med funksjonsvektorer der hver representerer et segment av bildet. Det betyr at vi har en enkelt vektorfunksjon for hele bildet.
Den beregnes av en skyvevinduetektor over et bilde, hvor en HOG-deskriptor beregnes for hver posisjon. Og så kombineres hver posisjon for en enkelt funksjonsvektor.
Som SIFT justeres skalaen på bildet ved pyramidering.
Tidligere har vi brukt matchere som FLANN og BFMatcher, men HOG-er gjør det annerledes ved hjelp av SVM-klassifikatorer (support vector machine), der hver HOG-deskriptor som beregnes blir matet til en SVM-klassifikator for å bestemme om objektet ble funnet eller ikke.
Her er lenken til et flott papir av Dalal & Triggs om bruk av HOGs for menneskelig påvisning:
Histogram av orienterte gradienter (HOG), trinn for trinn:
Å forstå HOG-er kan være ganske komplisert, men her skal vi bare håndtere teorien om HOG-er uten å gå dypere inn i matematikken knyttet til den.
Så la oss ta dette bildet, det er litt pikselert litt, og i øvre hjørne er det 8x8 pikselboks her, så i denne boksen beregner vi gradientvektoren eller kantorienteringen på hver piksel. Så det betyr at i denne boksen beregner vi bildegradientvektoren til piksler inne i boksen (de er en slags retning eller flyt av selve bildeintensiteten), og dette genererer 64 (8 x 8) gradientvektorer som deretter blir representert som et histogram. Så forestill deg et histogram som representerer hver gradientvektor. Så hvis alle punktene eller intensitetene løy i en retning, vil histogrammet for den retningen la oss si 45 grader, ville histogrammet ha en topp på 45 grader.
Så det vi gjør nå er at vi deler hver celle i vinkelfunksjoner, hvor hver søppel tilsvarer en gradientretning (f.eks. X, y). I papiret Dalal og Triggs brukte de 9 kasser 0-180 ° (20 ° hver søppel). Dette reduserer effektivt 64 vektorer til bare 9 verdier. Så det vi har gjort er å redusere størrelsen, men beholde all nøkkelinformasjonen som er nødvendig.
Neste trinn i beregningen av grisene er normaliseringen. Vi normaliserer gradientene for å sikre uforanderlighet til lysendringer, dvs. lysstyrke og kontrast.
I dette bildet vises intensitetsverdiene i firkanten i henhold til den respektive retningen, og alle har forskjell på 50 mellom hverandre
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Vi deler vektorene med gradientstørrelsene vi får 0,707 for alle, dette er normalisering.
Tilsvarende, hvis vi endrer intensiteten eller endrer kontrasten, får vi verdiene nedenfor.
∆ 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 finner ikke sted på cellenivå, men i stedet på blokkeringsnivå, så her er blokkene i utgangspunktet en gruppe på 4 celler, dette tar hensyn til naboblokker så normaliserer mens man tar i betraktning større deler av bildet.
La oss nå se på koden
importer numpy som np import cv2 importer matplotlib.pyplot som plt # Last inn bilde og deretter gråtonebilde = cv2.imread ('elephant.jpg') grå = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Vis originalbilde cv2.imshow (' Input Image ', image) cv2.waitKey (0) #defining the parameters, cell size and block size # hxw in pixels cell_size = (8, 8) # hxw in celler block_size = (2, 2) # antall orienteringsbøtter nbins = 9 # Ved å bruke OpenCVs HOG Descriptor # winSize er størrelsen på bildet beskåret til et multiplum av cellestørrelsen hog = cv2.HOGDescriptor (_winSize = (grå.form // cellestørrelse * cellestørrelse, grå.form // cellestørrelse * cellestørrelse), _blockSize = (blokkstørrelse * cellestørrelse, blokkstørrelse * cellestørrelse), _blockStride = (cellestørrelse, cellestørrelse), _cellSize = (cellestørrelse, cellestørrelse), _nbins = nbins) # Lag nummy matriseform for å lage hog_features n_cells = (grå.form // celle_størrelse, grå.form // celle_størrelse) # Vi indekserer blokker etter rader først. # hog_feats inneholder nå gradientamplitudene for hver retning, # for hver celle i gruppen for hver gruppe. Indeksering skjer etter rader og deretter kolonner. hog_feats = hog.compute (grå). omforming (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Lag vår gradientmatrise med nbin-dimensjoner for å lagre gradientorienteringsgradienter = np.zeros ((n_cells, n_cells, nbins)) # Lag array av dimensjoner cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Block Normalization for 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 # Gjennomsnittlig gradientgradienter / = celletall # Plott HOGer ved bruk av Matplotlib # vinkel er 360 / nbins * retning color_bins = 5 plt.pfarge (graderinger) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('equal', adjustable = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Bildet viser hvordan inngangsbildet er representert som HOG-representasjon.
HAAR kaskadeklassifiserere
Som tidligere diskutert, kan vi trekke ut funksjoner fra et bilde og bruke disse funksjonene til å klassifisere eller oppdage objekter.
Hva er HAAR Cascade Classifiers?
En objektgjenkjenningsmetode som legger inn Haar-funksjoner i en serie klassifiseringskilder (kaskade) for å identifisere objekter i et bilde. De er opplært i å identifisere en type gjenstand, men vi kan bruke flere av dem parallelt, for eksempel å oppdage øyne og ansikter sammen.
HAAR-klassifikatorer forklart:
HAAR-klassifiserere blir trent med mange positive bilder (dvs. bilder med objektet til stede) og
negative bilder (dvs. bilder uten objektet til stede).
Når vi har disse bildene, trekker vi ut funksjoner ved hjelp av skyvevinduer i rektangulære blokker. Disse funksjonene (HAAR-funksjoner) er enkeltverdivurderte og beregnes ved å trekke summen av pikselintensiteter under de hvite rektanglene fra de svarte rektanglene.
Dette er imidlertid et latterlig antall beregninger, selv for et grunnvindu på 24 x 24 piksler (180 000 genererte funksjoner).
Så forskerne utviklet en metode kalt Integral Images som beregnet dette med fire matrisereferanser. Imidlertid hadde de fortsatt 180 000 funksjoner, og flertallet av dem tilføyde ingen reell verdi.
Boosting ble deretter brukt til å bestemme de mest informative funksjonene, med Freund & Schapires AdaBoost, og den fant de mest informative funksjonene i bildet. Boosting er prosessen der vi bruker svake klassifikatorer til å bygge sterke klassifikatorer, ganske enkelt ved å tildele tyngre vektede straffer på feil klassifisering. Å redusere de 180 000 funksjonene til 6000, som fremdeles er ganske mange funksjoner.
I de 6000 funksjonene vil noen være mer informative enn andre. Så hvis vi brukte de mest informative funksjonene til å først sjekke om regionen potensielt kan ha et ansikt (falske positive vil ikke være noen stor sak). Dette eliminerer behovet for å beregne alle 6000 funksjonene samtidig. Dette konseptet kalles Cascade of Classifiers - for ansiktsgjenkjenning brukte Viola Jones-metoden 38 trinn.
Ansikts- og øyedeteksjon
Så etter å ha fått litt teoretisk kunnskap om HAAR-kaskadene, skal vi endelig implementere den, for å gjøre ting ganske mye klare, vil vi bryte leksjonene i deler, først vil vi oppdage frontansiktet etter det, vi vil bevege oss for å oppdage frontal face med og til slutt ville vi gjøre live oppdagelse av ansikt og øyne gjennom webkameraet.
Så for dette skal vi bruke forhåndstrente klassifiserere som er levert av OpenCV som.xml-filer, xml står for utvidbart markeringsspråk. Dette språket brukes til å lagre store mengder data, du kan til og med bygge en database på den.
Du kan få tilgang til disse klassifikatorene på denne lenken .
Ansiktsgjenkjennelse
La oss prøve for frontal ansiktsdeteksjon, du kan få tilgang til kaskaden til frontal face detector her. Bare trekk ut zip-filen for å få xml-filen.
import numpy as np import cv2 # Vi peker OpenCVs CascadeClassifier- funksjon der hvor # classifier (XML-filformat) er lagret, husk å holde koden og klassifisereren i samme mappe face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load bildet vårt konverterer det deretter til gråtonebilde = cv2.imread ('Trump.jpg') grå = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Klassifisereren vår returnerer avkastningen på det oppdagede ansiktet som en tuple # Den lagrer øverst til venstre koordinat og nederst til høyre koordinater # den returnerer listen over lister, som er plasseringen til forskjellige ansikter oppdaget. ansikter = face_cascade.detectMultiScale (grå, 1.3, 5) # Når ingen ansikter oppdages, returnerer ansiktsklassifiseringen og tømmer tufsen hvis ansiktene er (): utskrift ("Ingen ansikter funnet") # Vi gjentar oss gjennom ansiktsmatrisen og tegner et rektangel # over hvert ansikt i ansiktene for (x, y, w, h) i ansikter: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Face Detection', image) cv2.waitKey (0) cv2.destroyAllWindows ()
La oss nå kombinere ansikts- og øyedeteksjonen sammen, du kan få tilgang til kaskaden av øyedetektoren i samme zip-fil.
import 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) ansikter = face_classifier.detectMultiScale (grå, 1.3, 5) # Når ingen ansikter oppdages, returnerer face_classifier og tom tuple hvis ansiktene er (): skriv ut ("No Face Found") for (x, y, w, h) i ansikter: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = grå roi_color = img øyne = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) for (ex, ey, ew, eh) i øynene: 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 koden er like mye som koden for ansiktsgjenkjenning, men her har vi lagt til øyekaskader og metode for å oppdage dem, som du kan se, har vi valgt den grå skalerte versjonen av ansiktet som parameter for detekterMultiScale for øynene, noe som bringer oss til reduksjonen i beregning da vi bare bare vil oppdage øyne i det området.
Live ansikts- og øyedeteksjon
Så til nå har vi gjort ansikts- og øyedeteksjon, la oss nå implementere det samme med live videostrøm fra webkameraet. I dette vil vi gjøre det samme påvisning av ansikt og øyne, men denne gangen vil vi gjøre det for live stream fra webkameraet. I det meste av applikasjonen vil du finne ansiktet ditt uthevet med en ramme rundt det, men her har vi gjort noe annerledes som du vil finne ansiktet ditt beskåret ut, og øynene bare vil identifisere seg i det.
Så her importerer vi både ansikts- og øyeklassifisereren, og definerte en funksjon for å gjøre all behandlingen for ansikts- og øyedeteksjon. Og etter det startet webkamera-strømmen og kalte ansiktsdetektorfunksjonen for å få ansiktet og øynene oppdaget. Parameteren vi definerer inne i ansiktsdetektorfunksjonen er de kontinuerlige bildene fra live web cam stream
importer 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 bilde til cvcale. (img, cv2.COLOR_BGR2GRAY) ansikter = face_classifier.detectMultiScale (grå, 1.3, 5) hvis ansikter er (): returner img for (x, y, w, h) i ansikter: 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 øyne = eye_classifier.detectMultiScale (roi_gray) for (ex, ey, ew, eh) i øynene: 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
Parametrene som er definert i detectMultiScale annet enn inngangsbildet, har følgende betydning
vår klassifisering. detectMultiScale (input image, Scale Factor, Min Neighbors)
- Scale Factor Angir hvor mye vi reduserer bildestørrelsen hver gang vi skalerer. F.eks. I ansiktsgjenkjenning bruker vi vanligvis 1.3. Dette betyr at vi reduserer bildet med 30% hver gang det skaleres. Mindre verdier, som 1.05, vil ta lengre tid å beregne, men vil øke deteksjonsgraden.
- Min naboer Angir antall naboer hvert potensielt vindu skal ha for å anse det som en positiv deteksjon. Vanligvis settes mellom 3-6. Det fungerer som følsomhetsinnstilling, lave verdier vil noen ganger oppdage flere ansikter over et enkelt ansikt. Høye verdier vil sikre færre falske positive, men du kan savne noen ansikter.
Bil- og fotgjengeroppdagelse i videoer
Nå vil vi oppdage fotgjengere og biler i videoer ved hjelp av HAAR-kaskadene, men i tilfelle ingen video lastes inn og kodekompilering uten en feil, må du følge følgende trinn:
Hvis ingen video lastes inn etter at du har kjørt kode, kan det hende du må kopiere opencv_ffmpeg.dl fra : opencv \ sources \ 3rdparty \ ffmpeg for å lime den inn der din python er installert, for eksempel C: \ Anaconda2
Når den er kopiert, må du gi filen nytt navn i henhold til versjonen av OpenCV du bruker. Eg hvis du bruker OpenCV 2.4.13, og deretter gi filen nytt navn som: opencv_ffmpeg2413_64.dll eller opencv_ffmpeg2413.dll (hvis du er bruker en X86-maskin) opencv_ffmpeg310_64.dll eller opencv_ffmpeg310.dll (hvis du bruker en X86-maskin)
For å finne ut hvor du python.exe er installert, bare kjør disse to kodelinjene, det vil skrive ut stedet der python er installert.
importer sys- utskrift (sys.executable)
Nå hvis du har gjort disse trinnene med suksess, la oss gå til koden for deteksjon av fotgjengere, Du kan få kaskaden for deteksjon av fotgjengere og fra zip-filen vedlagt her.
import cv2 import numpy as np # Create our body classifier body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Start videoopptak for videofil, her bruker vi videofilen der fotgjengere vil bli oppdaget cap = cv2.VideoCapture ('walking.avi') # Loop når videoen er vellykket lastet mens cap.isOpened (): # Leser hver ramme av videoen ret, frame = cap.read () # her endrer vi størrelsen på rammen, til halvparten av størrelsen, gjør vi for å øke klassifiseringen # ettersom større bilder har mange flere vinduer å skyve over, så generelt sett reduserer vi oppløsningen # av halvparten av video, det er det som 0,5 indikerer, og vi bruker også raskere interpolasjonsmetode som er #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) grå = cv2. cvtColor (ramme, cv2.COLOR_BGR2GRAY) # Send ramme til kroppsklassifiseringslegemene våre = body_classifier.detectMultiScale (grå, 1.2, 3) # Trekk ut avgrensningsbokser for kroppene som er identifisert for (x, y, w, h) i kroppene: cv2. rektangel (ramme, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Fotgjengere', ramme) hvis cv2.waitKey (1) == 13: # 13 er Enter Key break cap.release () cv2.destroyAllWindows ()
Etter å ha oppdaget fotgjengere i video, la oss gå til koden for biloppdagelse. Du kan få kaskaden for fotgjengeroppdagelse herfra.
import cv2 import time import numpy as np # Create our body classifier car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Start videoopptak for videofil cap = cv2.VideoCapture ('cars.avi') # Loop når videoen er vellykket lastet mens cap.isOpened (): time.sleep (.05) # Les første ramme ret, frame = cap.read () grå = cv2.cvtColor (ramme, cv2.COLOR_BGR2GRAY) # Pass ramme til våre bil klassifiseringsbiler = car_classifier.detectMultiScale (grå, 1.4, 2) # Trekk ut avgrensningsbokser for alle kropper som er identifisert for (x, y, w, h) i biler: cv2. rektangel (ramme, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Cars', frame) if cv2.waitKey (1) == 13: # 13 er Enter Key break break cap. release () cv2.destroyAllWindows ()
Du har lagt merke til at vi har lagt til time.sleep (.05) , det er bare en forsinkelse i bildefrekvens, slik at du kan bekrefte at alle bilene er riktig identifisert, eller du kan enkelt fjerne den bare ved å legge til en merkelapp til den.
Denne artikkelen er henvist fra Master Computer Vision ™ OpenCV4 i Python med Deep Learning-kurs på Udemy, opprettet av Rajeev Ratan, abonner på den for å lære mer om Computer Vision og Python.