- Objektdetektering med SIFT
- Objektdetektering med ORB
- Histogram av orienterade lutningar (HOG)
- Histogram av orienterade lutningar (HOG), steg för steg:
- HAAR-kaskadklasser
- Ansikts- och ögondetektering
- Live ansikts- och ögondetektering
- Tuning Cascade Classifiers
- Upptäckt av bil och fotgängare i videor
Vi började med att installera python OpenCV på Windows och hittills gjort grundläggande bildbehandling, bildsegmentering och objektdetektering med Python, som beskrivs i nedanstående självstudier:
- Komma igång med Python OpenCV: Installation och grundläggande bildbehandling
- Bildmanipulationer i Python OpenCV (del 1)
- Bildmanipulationer i OpenCV (del 2)
- Bildsegmentering med OpenCV - extraherar specifika områden i en bild
Vi lärde oss också om olika metoder och algoritmer för objektdetektion där några viktiga punkter identifierades för varje objekt med olika algoritmer. I denna handledning ska vi använda dessa algoritmer för att upptäcka verkliga objekt, här skulle vi använda SIFT och ORB för detekteringen.
Objektdetektering med SIFT
Här kommer objektdetektering att ske med livestreaming av webbkameror, så om den känner igen objektet skulle det nämnas att objekt hittades. I koden spelas huvuddelen av den funktion som kallas SIFT-detektor, det mesta av bearbetningen sker med denna funktion.
Och i den andra halvan av koden börjar vi med att öppna webbkameraströmmen, ladda sedan bildmallen, dvs. referensbilden, det vill säga programmet faktiskt tittar genom webbkameraströmmen.
Därefter tar vi kontinuerligt bilderna från webbkameraströmmen med hjälp av oändlig medan slinga, och tar sedan motsvarande höjd och bredd på webbkameroramen och definierar sedan parametrarna för den intressanta regionen (ROI) i vilken vårt objekt kan passa in genom att ta motsvarande höjd och bredd på webbkameran. Och sedan drar vi rektangeln från de ROI-parametrar som vi hade definierat ovan. Skär äntligen ut rektangeln och mata in den i SWIFT-detektordelen av koden.
Nu har SIFT-detektorn i princip två ingångar, den ena är den beskurna bilden och den andra är bildmallen som vi tidigare definierade och sedan ger det oss några matchningar, så matchningar är i princip antalet objekt eller tangentpunkter som liknar den beskurna bilden och målbilden. Sedan definierar vi ett tröskelvärde för matchningarna, om matchningsvärdet är större än tröskeln, lägger vi bilden som finns på vår skärm med grön färg av ROI-rektangel.
Låt oss nu gå tillbaka till huvuddelen av koden, funktionen som kallas SIFT-detektor, det tar ingången eftersom två bilder en är bilden där den letar efter objektet och andra är objektet som vi försöker matcha till (bildmall). Gråskala sedan den första bilden och definiera bildmallen som andra bilden. Sedan skapar vi ett SIFT-detektorobjekt och kör OpenCV SIFT-detekterings- och beräkningsfunktionen, för att upptäcka tangentpunkterna och beräkna deskriptorerna, deskriptorerna är i grunden vektorerna som lagrar informationen om tangentpunkterna, och det är verkligen viktigt när vi gör matchningen mellan bilderna.
Och definiera sedan den FLANN-baserade matcharen, vi går inte in i den matematiska teorin om att matcha bakom den, men du kan enkelt Google om den. Definiera först index kdtree till noll och sedan ställer vi in index och sökparametrar i ordboksformatet, vi definierar bara algoritmen vi ska använda som är KDTREE, och antalet träd vi ska använda, desto mer träd vi använder ju mer komplicerat det blir och långsammare. Och i sökparametern definierar du antalet kontroller, vilket i grunden är antalet matchningar som det kommer att slutföra.
Och skapa sedan vårt FLANN-baserade matchningsobjekt genom att ladda parametern som vi tidigare definierat som är indexparametrar och sökparametrar och baserat på detta skapa vårt FLANN-baserade matcher, som är en KNN-matchare där KNN är K-närmaste grannar, i princip är det ett sätt där vi letar efter närmaste matchare och deskriptorer och vi gör matchningen med initialiseringskonstanten k. Nu returnerar denna FLANN-baserade matcher antalet matchningar vi får.
FLANN-baserad matchning är bara en approximation, för att öka noggrannheten för den FLANN-baserade matcharen utför vi ett Lowes ratio-test och vad det gör är att det letar efter matchningarna från den knn flann-baserade matcharen och definierar några matriska parametrar som är avståndet här, för vilket avstånd är en bedövad funktion, och när den väl uppfyller kriterierna, lägg till matchningarna till de bra matchningarna och returnera de hittade bra matchningarna, och så berättar livevideoströmmen hur många matchningar som finns i hörnet av skärmen.
Låt oss nu titta på koden för beskrivningen ovan:
importera cv2 import numpy som np def sift_detector (new_image, image_template): # Funktion som jämför ingångsbild med mall # Den returnerar sedan antalet SIFT-matchningar mellan dem image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Create SIFT-detektorobjekt #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Skaffa tangentpunkter och deskriptorer med hjälp av SIFT- tangentpunkter_1, descriptors_1 = sift.detectAndCompute (image1, None) tangentpunkter_2, descriptors_2A sift.data Ingen) # Definiera parametrar för vår Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algoritm = FLANN_INDEX_KDTREE, träd = 3) search_params = dict (kontroller = 100) # Skapa det Flann Matcher objektet Flann = cv2.FlannBasedMatcher (index_params, search_params) # Erhåll matchningar med hjälp av K-Nearest Neighbor Metod # resultat 'matchs' är det antal likadana matchningar hittas i båda bilder matchningar = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Lagra bra matchningar med Lowes förhållande test good_matches = för m, n i matchningar: om m avstånd <0,7 * n avstånd: bra_matches.append (m) returnera len (good_matches) cap = cv2.VideoCapture (0) # Ladda vår bildmall, det här är vår referensbild image_template = cv2.imread ('phone.jpg', 0) medan True: # Få webbkamerabilder ret, frame = cap.read () # Få höjd och bredd på webbkamera ramhöjd , bredd = frame.shape # Definiera ROI Box Dimensioner top_left_x = int (width / 3) top_left_y = int ((höjd / 2) + (höjd / 4)) bottom_right_x = int ((bredd / 3) * 2) bottom_right_y = int ((höjd / 2) - (höjd / 4)) # Rita rektangulärt fönster för vår region av intresse cv2. Rektangel (ram, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Beskärningsfönster för observation som vi definierade ovan beskurna = ram # Vänd ramorientering horisontellt ram = cv2.flip (ram, 1) # Få antal SIFT- matchningar = sift_detector (beskuren, bild_mall) # Visa statussträng som visar nuvarande nr. av matchningar cv2.putText (ram, str (matchningar), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Vår tröskel för att indikera objektdetektion # Vi använder 10 eftersom SIFT-detektorn returnerar lite falska tröskel = 10 # Om matchningar överstiger vår tröskel har objekt upptäckts om matchningar> tröskel: 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 är Enter Key break cap. Release () cv2.destroyAllWindows ()
Objektdetektering med ORB
Objektdetektering med SIFT är ganska coolt och korrekt, eftersom det genererar ett mycket exakt antal matchningar baserat på tangentpunkter, men dess patenterade och det gör det svårt att använda det för kommersiella applikationer, den andra vägen för det är ORB-algoritmen för detektering av objekt.
I likhet med metoden för objektdetektering med SIFT där vi delade programmet i två delar kommer detsamma att följas här.
För det första definierar vi funktionen ORB_detector som tar två ingångar, den ena är livestreambilden som kommer från webbkameran och den andra är bildmallen på grundval av vilken vi ska matcha vår bild. Sedan gråskalar vi vår webbkamerabild och initialiserar sedan vår ORB-detektor, och vi sätter den här till 1000 nyckelpunkter och skalningsparametrar på 1,2. du kan enkelt leka med dessa parametrar och sedan upptäcka tangentpunkterna (kp) och deskriptorerna (des) för både bilderna och den andra parametern som vi definierar i detectANDCompute- funktionen är INGEN, det ber om användning av bildmask eller inte och vi förnekar det här.
Flytta sedan till detektorn tidigare, vi har använt FLANN-baserad matcher, men här kommer vi att använda BFMatcher och inuti BFMatcher definierar vi två parametrar, den ena är NORM_HAMMING och den andra är korskontrollen vars värde är SANT.
Beräkna sedan matchningarna matchningarna mellan dessa två bilder med hjälp av de beskrivningar som definierats ovan, som i sin helhet returnerar antalet matchningar eftersom dessa matchningar inte är ungefärliga och därför finns det inget behov av att göra Lowes förhållande test, istället sorterar vi matchningarna baserat på avstånd, minst avståndet mer match är bättre (här betyder avståndet avståndet mellan punkterna), och i slutet returnerar vi antalet matchningar med hjälp av längdfunktionen.
Och i huvudfunktionen ställer vi in tröskeln till ett mycket högre värde, eftersom orbdetektor genererar mycket brus.
Låt oss nu titta på kod för ORB-baserad detektering
importera cv2 importera numpy som np def ORB_detector (new_image, image_template): # Funktion som jämför ingångsbilden till mall # Den returnerar sedan antalet ORB-matchningar mellan dem image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Skapa ORB-detektor med 1000 tangentpunkter med en skalpyramidfaktor på 1,2 orb = cv2.ORB_create (1000, 1.2) # Detektera tangentpunkter för originalbilden (kp1, des1) = orb.detectAndCompute (image1, None) # Detektera tangentpunkter för roterad bild (kp2, des2) = orb.detectAndCompute (image_template, None) # Skapa matcher # Obs! Vi använder inte längre Flannbased matching bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Gör matchande matchningar = bf.match (des1, des2) # Sortera matchningar baserat på avstånd. Minsta avstånd # är bättre matchningar = sorterade (matchningar, tangent = lambda val: val. Avstånd) returnera len (matchningar) cap = cv2.VideoCapture (0) # Ladda vår bildmall, det här är vår referensbild image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) medan Sann: # Få webbkameran bilder ret, ram = cap.read () # Få höjd och bredd av webbkameran ram höjd, width = frame.shape # Define ROI Box Dimensions (Obs, några av dessa saker ska vara utanför slingan) top_left_x = int (width / 3) top_left_y = int ((höjd / 2) + (höjd / 4)) bottom_right_x = int ((bredd / 3) * 2) bottom_right_y = int ((höjd / 2) - (höjd / 4)) # Rita rektangulärt fönster för vår intresseområde cv2.rectangle (ram, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Beskärningsfönster för observation vi definierade ovan beskurna = ram # Vänd ramorientering horisontellt ram = cv2.flip (ram, 1) # Få antal ORB-matchningar = ORB_detector (beskuren, bild_mall) # Visa statussträng som visar det aktuella nr. av matchningar output_string = "Matchar =" + str (matchar) cv2.putText (ram, output_string, (50.450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Vår tröskel för att indikera objektdeteciton # För nya bilder eller ljusförhållanden kan du behöva experimentera lite # Obs: ORB-detektorn för att få de 1000 bästa matchningarna, 350 är i huvudsak en matchningströskel på minst 35% = 250 # Om matchningar överstiger vår tröskel då objekt har detekterats om matchar> tröskel: cv2.rectangle (ram, (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 med ORB', ram) om cv2.waitKey (1) == 13: # 13 är Enter Key break cap.release () cv2.destroyAllWindows ()
Histogram av orienterade lutningar (HOG)
Låt oss nu prata om en annan deskriptor som är histogram av orienterade lutningar (HOG).
HOG är ganska coola och användbara deskriptorer och de används i stor utsträckning och framgångsrikt för objektdetektering, som tidigare sett bildbeskrivare som SIFT och ORB där vi måste beräkna tangentpunkter och sedan måste beräkna deskriptorer ur dessa tangentpunkter, HOG gör den processen annorlunda. Den representerar objekt som en enda funktionsvektor i motsats till en uppsättning funktionsvektorer där var och en representerar ett segment av bilden. Det betyder att vi har en enda vektorfunktion för hela bilden.
Den beräknas av en glidande fönsterdetektor över en bild, där en HOG-deskriptor är beräknad för varje position. Och sedan kombineras varje position för en enda funktionsvektor.
Precis som SIFT justeras bildens skala genom pyramidering.
Tidigare har vi använt matchare som FLANN och BFMatcher, men HOG gör det annorlunda med hjälp av SVM-klassificeringsapparater (support vector machine), där varje HOG-deskriptor som beräknas matas till en SVM-klassificering för att avgöra om objektet hittades eller inte.
Här är länken till ett stort dokument av Dalal & Triggs om hur man använder HOGs för mänsklig detektion:
Histogram av orienterade lutningar (HOG), steg för steg:
Att förstå HOG kan vara ganska komplicerat, men här kommer vi bara att ta itu med teorin om HOG utan att gå djupare in i den matematik som är relaterad till den.
Så låt oss ta den här bilden, den är lite pixelerad lite, och i det övre hörnet finns en 8x8 pixelruta här, så i den här rutan beräknar vi lutningsvektorn eller kantorienteringen vid varje pixel. Så det betyder att i den här rutan beräknar vi bildgradientvektorn för pixlar inuti rutan (de är typ av riktning eller flöde av själva bildintensiteten), och detta genererar 64 (8 x 8) gradientvektorer som sedan representeras som ett histogram. Så tänk dig ett histogram som representerar varje gradientvektor. Så om alla punkter eller intensiteter ljög i en riktning, antar histogrammet för den riktningen 45 grader, histogrammet skulle ha en topp på 45 grader.
Så vad vi gör nu är att vi delar upp varje cell i vinkelfack, där varje fack motsvarar en lutningsriktning (t.ex. x, y). I papperet Dalal och Triggs använde de 9 lagerplatser0-180 ° (20 ° vardera fack). Detta reducerar effektivt 64 vektorer till bara 9 värden. Så vad vi har gjort är att minska storleken men behålla all viktig information som behövs.
Nästa steg i beräkningen av grisarna är normaliseringen, vi normaliserar lutningarna för att säkerställa invarians till ljusförändringar, dvs. ljusstyrka och kontrast.
I den här bilden visas intensitetsvärdena i kvadraten enligt respektive riktning och alla har en skillnad på 50 mellan varandra
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Vi delar vektorerna med gradientstorlekarna vi får 0,707 för alla, detta är normalisering.
På samma sätt, om vi ändrar intensiteten eller ändrar kontrasten får vi nedanstående värden.
∆ 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 sker inte på cellnivå, utan sker i blocknivå, så här är blocken i grunden en grupp på 4 celler, detta tar hänsyn till angränsande block så normaliseras samtidigt som man tar hänsyn till större delar av bilden.
Låt oss nu titta på koden
importera numpy som np importera cv2 importera matplotlib.pyplot som plt # Ladda bild sedan gråskala bild = cv2.imread ('elephant.jpg') grå = cv2.cvtColor (bild, cv2.COLOR_BGR2GRAY) # Visa originalbild cv2.imshow (' Inmatningsbild ', bild) cv2.waitKey (0) #definiera parametrar, cellstorlek och blockstorlek # hxw i pixlar cell_size = (8, 8) # hxw i celler block_size = (2, 2) # antal orienteringsfack nbins = 9 # Använda OpenCVs HOG Descriptor # winSize är storleken på bilden som beskärs till en multipel av cellstorleken hog = cv2.HOGDescriptor (_winSize = (grå. Form // cellstorlek * cellstorlek, grå.form // cellstorlek * cellstorlek), _blockSize = (blockstorlek * cellstorlek, blockstorlek * cellstorlek), _blockStride = (cellstorlek, cellstorlek), _cellSize = (cellstorlek, cellstorlek), _nbins = nbins) # Skapa suddig matrisform som vi använder för att skapa hog_features n_cells = (grey.shape // cell_size, grey.shape // cell_size) # Vi indexerar block efter rader först. # hog_feats innehåller nu gradientamplituderna för varje riktning, # för varje cell i sin grupp för varje grupp. Indexering sker efter rader och sedan kolumner. hog_feats = hog.compute (grå). omforma (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Skapa vår gradientmatris med nbin-dimensioner för att lagra gradientorienteringsgradienter = np.zeros ((n_cells, n_cells, nbins)) # Skapa array med dimensioner 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 # Genomsnittliga gradienter gradienter / = cellantal # Plot HOGs med Matplotlib # vinkel är 360 / nbins * riktning color_bins = 5 plt.pcolor (gradienter) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('lika', justerbar = 'box') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Bilden visar hur den inmatade bilden representeras som HOG-representation.
HAAR-kaskadklasser
Som tidigare diskuterat kan vi extrahera funktioner från en bild och använda dessa funktioner för att klassificera eller upptäcka objekt.
Vad är HAAR Cascade Classifiers?
En objektdetekteringsmetod som matar in Haar-funktioner i en serie klassificerare (kaskad) för att identifiera objekt i en bild. De är utbildade för att identifiera en typ av objekt, men vi kan använda flera av dem parallellt, t.ex. upptäcka ögon och ansikten tillsammans.
HAAR-klassificatorer förklarade:
HAAR-klassificerare tränas med hjälp av många positiva bilder (dvs. bilder med objektet närvarande) och
negativa bilder (dvs. bilder utan objektet närvarande).
När vi väl har bilderna extraherar vi funktioner med hjälp av skjutfönster i rektangulära block. Dessa funktioner (HAAR-funktioner) värderas enstaka och beräknas genom att subtrahera summan av pixelintensiteter under de vita rektanglarna från de svarta rektanglarna.
Detta är dock ett löjligt antal beräkningar, även för ett basfönster på 24 x 24 pixlar (180 000 funktioner genererade).
Så forskarna tog fram en metod som heter Integral Images som beräknade detta med fyra matrisreferenser. Men de hade fortfarande 180 000 funktioner och majoriteten av dem tillförde inget verkligt värde.
Boosting användes sedan för att bestämma de mest informativa funktionerna, med Freund & Schapires AdaBoost och det hittade mest informativa funktioner i bilden. Boosting är den process genom vilken vi använder svaga klassificeringsapparater för att bygga starka klassificeringsapparater, helt enkelt genom att tilldela tyngre viktade påföljder för felaktiga klassificeringar. Minska 180 000 funktioner till 6000, vilket fortfarande är en hel del funktioner.
I dessa 6000 funktioner kommer vissa att vara mer informativa än andra. Så om vi använde de mest informativa funktionerna för att först kontrollera om regionen potentiellt kan ha ett ansikte (falska positiva saker kommer inte att vara någon stor sak). Om du gör det elimineras behovet av att beräkna alla 6000 funktioner samtidigt. Detta koncept kallas Cascade of Classifiers - för ansiktsdetektering använde Viola Jones-metoden 38 steg.
Ansikts- och ögondetektering
Så efter att ha fått lite teoretisk kunskap om HAAR-kaskaderna kommer vi äntligen att implementera den, för att göra saker ganska mycket tydliga kommer vi att bryta lektionerna i delar, först skulle vi upptäcka frontal ansikte efter det kommer vi att flytta för att upptäcka frontal face med och slutligen skulle vi göra detektering av ansikte och ögon live via webbkameran.
Så för detta kommer vi att använda förutbildade klassificeringsapparater som tillhandahålls av OpenCV som.xml-filer, xml står för utbyggbart markeringsspråk, det här språket används för att lagra stora mängder data, du kan till och med bygga en databas på den.
Du kan få tillgång till dessa klassificeringsapparater på den här länken .
Ansiktsigenkänning
Låt oss försöka upptäcka frontal ansikte, du kan få tillgång till kaskaden för frontal ansiktsdetektor här. Extrahera bara zip-filen för att hämta xml-filen.
importera numpy som np import cv2 # Vi pekar OpenCVs CascadeClassifier-funktion till där vår # classifier (XML-filformat) är lagrad, kom ihåg att behålla koden och klassificeringen i samma mapp face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load vår bild konverterar den sedan till gråskalebild = cv2.imread ('Trump.jpg') grå = cv2.cvtColor (bild, cv2.COLOR_BGR2GRAY) # Vår klassificering returnerar ROI för det detekterade ansiktet som en tuple # Den lagrar det övre vänstra hörnet koordinat och nedre högra koordinater # det returnerar listan med listor, som är platsen för olika ansikten som upptäcks. ansikten = face_cascade.detectMultiScale (grå, 1.3, 5) # När inga ansikten detekteras, returnerar ansiktsklassificering och tömmer tupeln om ansikten är (): skriv ut ("Inga ansikten hittades") # Vi itererar genom vårt ansiktsarray och ritar en rektangel # över varje ansikte i ansikten för (x, y, w, h) i ansikten: cv2.rectangle (image, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Face Detection', image) cv2.waitKey (0) cv2.destroyAllWindows ()
Låt oss nu kombinera ansikts- och ögondetektering tillsammans, du kan få åtkomst till ögondetektorns kaskad i samma zip-fil.
importera 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.cv2.imread cv2.COLOR_BGR2GRAY) ansikten = face_classifier.detectMultiScale (grå, 1.3, 5) # När inga ansikten detekteras, returneras face_classifier och tom tuple om ansikten är (): skriv ut ("No Face Found") för (x, y, w, h) i ansikten: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img) roi_gray = grå roi_color = img ögon = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) för (ex, ey, ew, eh) i ögonen: 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å den här koden är lika mycket som koden för ansiktsdetektering, men här har vi lagt till ögonkaskader och metod för att upptäcka dem, som du kan se har vi valt den gråskalade versionen av ansiktet som parameter för detekteraMultiScale för ögonen, vilket leder oss till minskningen av beräkningen eftersom vi bara kommer att upptäcka ögon bara i det området.
Live ansikts- och ögondetektering
Så hittills har vi gjort ansikts- och ögondetektering, låt oss nu implementera detsamma med livevideoströmmen från webbkameran. I detta kommer vi att göra samma upptäckt av ansikte och ögon men den här gången kommer vi att göra det för livestream från webbkameran. I det mesta av applikationen skulle du hitta ditt ansikte markerat med en ruta runt det, men här har vi gjort något annorlunda som du skulle hitta ditt ansikte klippt ut och ögonen skulle identifiera i det bara.
Så här importerar vi både ansikts- och ögonklassificeraren och definierade en funktion för att göra all bearbetning för ansikts- och ögondetektering. Och efter det startade webbkameraströmmen och kallade ansiktsdetektorfunktionen för att få ansiktet och ögonen upptäckta. Parametern vi definierar inuti ansiktsdetektorfunktionen är de kontinuerliga bilderna från live webbkamera
importera cv2 importera numpy som np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5): # Konvertera bild till grayscale. (img, cv2.COLOR_BGR2GRAY) ansikten = face_classifier.detectMultiScale (grå, 1.3, 5) om ansikten är (): returnera img för (x, y, w, h) i ansikten: 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 ögon = eye_classifier.detectMultiScale (roi_gray) för (ex, ey, ew, eh) i ögonen: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) returnera roi_color cap = cv2.VideoCapture (0) medan True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) om cv2.waitKey (1) == 13: # 13 är Enter Key break cap.release () cv2.destroyAllWindows ()
Tuning Cascade Classifiers
Parametrarna som definierats inuti detectMultiScale än ingångsbilden har följande betydelse
vår klassificering. detectMultiScale (ingångsbild, skalfaktor, mina grannar)
- Scale Factor Anger hur mycket vi minskar bildstorleken varje gång vi skalar. Till exempel i ansiktsavkänning använder vi vanligtvis 1.3. Det betyder att vi minskar bilden med 30% varje gång den skalas. Mindre värden, som 1.05, tar längre tid att beräkna, men kommer att öka detekteringsgraden.
- Min grannar Anger antalet grannar som varje potentiellt fönster ska ha för att betrakta det som en positiv upptäckt. Vanligtvis ställs mellan 3-6. Det fungerar som känslighetsinställning, låga värden detekterar ibland flera ansikten över ett enda ansikte. Höga värden kommer att säkerställa mindre falska positiva resultat, men du kan missa några ansikten.
Upptäckt av bil och fotgängare i videor
Nu kommer vi att upptäcka fotgängare och bilar i videor som använder HAAR-kaskaderna, men om ingen video laddas och kodkompilerar utan ett fel måste du följa följande steg:
Om ingen video laddas efter att ha kört kod kan du behöva kopiera vår opencv_ffmpeg.dl från : opencv \ sources \ 3rdparty \ ffmpeg för att klistra in den där din python är installerad, t.ex. C: \ Anaconda2
När den har kopierats måste du byta namn på filen enligt den version av OpenCV du använder. Eg om du använder OpenCV 2.4.13 byt namn på filen till: opencv_ffmpeg2413_64.dll eller opencv_ffmpeg2413.dll (om du är använder en X86-maskin) opencv_ffmpeg310_64.dll eller opencv_ffmpeg310.dll (om du använder en X86-maskin)
För att ta reda på var du python.exe är installerad, kör bara dessa två rader kod, det skulle skriva ut platsen där python är installerat.
importera sys- utskrift (sys.executable)
Nu om du har gjort dessa steg framgångsrikt, låt oss gå till koden för detektering av fotgängare, Du kan få kaskaden för att upptäcka fotgängare och från zip-filen bifogad här.
importera cv2 importera numpy som np # Skapa vår kroppsklassificering body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Initiera videoinspelning för videofil, här använder vi videofilen där fotgängare skulle detekteras cap = cv2.VideoCapture ('walking.avi') # Loop när videon har laddats framgångsrikt medan cap.isOpened (): # Läser varje bildruta i videoretten, frame = cap.read () # här ändrar vi storlek på ramen, till hälften av dess storlek, vi gör för att påskynda klassificeringen # eftersom större bilder har mycket fler fönster att glida över, så totalt sett minskar vi upplösningen # av video med hälften är det som 0,5 indikerar, och vi använder också snabbare interpoleringsmetod som är #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) grå = cv2. cvtColor (ram, cv2.COLOR_BGR2GRAY) # Skicka ram till våra kroppsklassificeringsorgan = body_classifier.detectMultiScale (grå, 1,2, 3) # Extrahera avgränsningsrutor för alla kroppar som identifierats för (x, y, w, h) i kroppar: cv2. rektangel (ram, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Fotgängare', ram) om cv2.waitKey (1) == 13: # 13 är Enter Key break cap.release () cv2.destroyAllWindows ()
Efter att ha lyckats upptäcka fotgängare i video, låt oss gå till koden för bilavkänning. Du kan få kaskaden för att upptäcka fotgängare härifrån.
importera cv2 importtid importera numpy som np # Skapa vår kroppsklassificering car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Starta videoinspelning för videofil cap = cv2.VideoCapture ('cars.avi') # Loop när video har lyckats laddad medan cap.isOpened (): time.sleep (.05) # Läs första bilden ret, frame = cap.read () grå = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Skicka ram till våra bilklassificeringsbilar = car_classifier.detectMultiScale (grå, 1.4, 2) # Extrahera avgränsningsrutor för alla kroppar som identifierats för (x, y, w, h) i bilar: cv2.rectangle (ram, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Bilar', ram) om cv2.waitKey (1) == 13: # 13 är Enter Key break cap.release () cv2.destroyAllWindows ()
Du har märkt att vi har lagt till time.sleep (.05) , det är bara en fördröjning av bildhastigheten så att du kan bekräfta att alla bilar är korrekt identifierade, eller så kan du enkelt ta bort den bara genom att lägga till en kommentaretikett till den.
Denna artikel hänvisas från Master Computer Vision ™ OpenCV4 i Python med Deep Learning-kurs om Udemy, skapad av Rajeev Ratan, prenumerera på den för att lära dig mer om Computer Vision och Python.