- Zaznavanje predmetov s pomočjo SIFT
- Zaznavanje predmetov z uporabo ORB
- Histogram usmerjenih prelivov (HOG)
- Histogram usmerjenih prelivov (HOG), korak za korakom:
- HAAR kaskadni klasifikatorji
- Zaznavanje obraza in oči
- Odkrivanje obraza in oči v živo
- Uglaševanje kaskadnih klasifikatorjev
- Zaznavanje avtomobilov in pešcev v video posnetkih
Začeli smo z namestitvijo python OpenCV v okna in doslej opravili nekaj osnovnih obdelav slik, segmentacije slik in zaznavanja predmetov s pomočjo Pythona, ki so opisani v spodnjih vajah:
- Uvod v Python OpenCV: Namestitev in osnovna obdelava slik
- Slikovne manipulacije v Python OpenCV (1. del)
- Slikovne manipulacije v OpenCV (2. del)
- Segmentacija slike z uporabo OpenCV - pridobivanje določenih področij slike
Spoznali smo tudi različne metode in algoritme za zaznavanje predmetov, kjer so bile določene nekatere ključne točke za vsak objekt z uporabo različnih algoritmov. V tej vadnici bomo te algoritme uporabili za zaznavanje predmetov iz resničnega življenja, tukaj bi za zaznavanje uporabili SIFT in ORB.
Zaznavanje predmetov s pomočjo SIFT
Tu bo zaznavanje predmeta izvedeno s pomočjo spletnega toka v živo, tako da če prepozna predmet, bi omenil najdeno objet. V kodi glavno vlogo igra funkcija, ki se imenuje detektor SIFT, večino obdelave opravi ta funkcija.
In v drugi polovici kode začnemo z odpiranjem toka spletne kamere, nato naložimo predlogo slike, tj. Referenčno sliko, to je program, ki dejansko gleda skozi tok spletne kamere.
Nato neprekinjeno zajemamo slike iz toka spletne kamere s pomočjo neskončne zanke while , nato zajemamo ustrezno višino in širino okvira spletne kamere, nato pa definiramo parametre polja zanimanja (ROI), v katerem naš objekt se lahko prilega tako, da vzame ustrezno višino in širino okvira spletne kamere. Nato pravokotnik narišemo iz parametrov ROI, ki smo jih določili zgoraj. Nato pravokotnik končno obrežite in ga vstavite v del kode SWIFT detektorja.
Zdaj ima detektor SIFT v bistvu dva vhoda, eden je obrezana slika, drugi pa je predloga slike, ki smo jo predhodno definirali, nato pa nam da nekaj ujemanj, torej ujemanja so v bistvu število predmetov ali ključnih točk, ki so podobni na obrezani sliki in ciljno sliko. Nato določimo vrednost praga za ujemanja, če je vrednost ujemanja večja od praga, na naš zaslon postavimo sliko z zeleno barvo pravokotnika ROI.
Zdaj pa se vrnimo na glavni del kode, funkcijo, ki se imenuje detektor SIFT, vhod pa ima kot dve sliki ena je slika, kjer išče predmet, druga pa objekt, ki mu skušamo ujemati do (predloga slike). Nato prvo sliko prilagodite sivi in določite predlogo slike kot drugo sliko. Nato ustvarimo objekt detektorja SIFT in zaženemo funkcijo zaznavanja in izračunavanja OpenCV SIFT, tako da so zaznavanje ključnih točk in izračun deskriptorjev v bistvu vektorji, ki shranjujejo informacije o ključnih točkah, in je zelo pomembno, saj izvajamo ujemanje med deskriptorji slik.
Nato definirajte ujemanje na osnovi FLANN-a, ne bomo se spuščali v matematično teorijo ujemanja, vendar lahko o tem enostavno poglabljate. Najprej določimo indeks kdtree na nič in nato nastavimo parametre indeksa in iskanja v obliki slovarja, samo določimo algoritem, ki ga bomo uporabljali, ki je KDTREE, in število dreves, ki jih bomo uporabili, več dreves uporabljamo bolj zapletene in počasnejše. V parametru iskanja določite število pregledov, ki je v bistvu število ujemanj, ki jih bo dokončal.
In nato ustvarite naš predmet ujemanja na osnovi FLANN, tako da naložite parameter, ki smo ga predhodno definirali, to so parametri indeksa in iskalni parametri, in na podlagi tega ustvarite naš ujemanj na osnovi FLANN, ki je ujemanje KNN, kjer je KNN najbližji sosedje, v bistvu gre za način, kjer iščemo najbližja ujemanja in deskriptorje in ujemanje izvajamo s konstanto inicializacije k. Zdaj ta tekma na osnovi FLANN vrne število ujemanj, ki jih dobimo.
Ujemanje na osnovi FLANN-a je le približek, zato da bi povečali natančnost ujemanja na osnovi FLANN-a, izvedemo test razmerja Lowe in kar počne, poiščemo ujemanja iz knn-a na osnovi flanna in določimo nekatere matrične parametre, ki so tukaj razdalja, za katero razdaljo je funkcija numpy in ko izpolni kriterije, dodajte ujemanja dobrim ujemanjem in vrne najdena dobra ujemanja, tako da video tok v živo sporoča število zadetkov, najdenih v kotu zaslona.
Zdaj pa si oglejmo kodo za zgornji opis:
import cv2 import numpy as np def sift_detector (new_image, image_template): # Funkcija, ki primerja vhodno sliko s predlogo # Nato vrne število ujemanj SIFT med njimi image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Create Objekt detektorja SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Pridobite ključne točke in deskriptorje s pomočjo SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, None) keypoints_2, descriptors_2 = sift.detete2A, sift.detete2 Brez) # Določite parametre za naš Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algoritem = FLANN_INDEX_KDTREE, drevesa = 3) search_params = dict (čeki = 100) # Ustvarite FLANN ujemalniku predmet FLANN = cv2.FlannBasedMatcher (index_params, search_params) # Pridobiti tekme uporabo K-najbližjih sosedov Metoda # je rezultat "matchs" je število podobnih zadetkov na voljo v obeh slik tekmah = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Shranite dobra ujemanja z uporabo Lowejevega testa razmerja good_matches = za m, n v ujemanjih: če je m.distance <0,7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Naložite našo predlogo slike, to je naša referenčna slika image_template = cv2.imread ('phone.jpg', 0), medtem ko je True: # Pridobite slike s spletne kamere ret, frame = cap.read () # Pridobite višino in širino višine okvirja spletne kamere , width = frame.shape # Določite dimenzije polja ROI top_left_x = int (width / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((širina / 3) * 2) bottom_right_y = int ((višina / 2) - (višina / 4)) # Nariši pravokotno okno za našo regijo interesa cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Obreži okno opazovanja, ki smo ga definirali zgoraj obrezano = okvir # Obrni okvir usmerjenosti vodoravno frame = cv2.flip (frame, 1) # Pridobite število ujemanj SIFT = sift_detector (obrezano, image_template) # Prikaže niz stanja, ki prikazuje trenutno št. ujemanj cv2.putText (okvir, str (ujemanja), (450.450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Naš prag za zaznavanje predmeta # Uporabljamo 10, saj detektor SIFT vrne malo napačnih pozitv prag = 10 # Če ujemanja presežejo naš prag, je bil predmet zaznan, če je ujemanja> prag: cv2.rectangle (okvir, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Objekt najden', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Detektor predmeta s pomočjo SIFT', okvir), če cv2.waitKey (1) == 13: # 13 je Enter Key break cap.release () cv2.destroyAllWindows ()
Zaznavanje predmetov z uporabo ORB
Zaznavanje predmetov s pomočjo SIFT je precej kul in natančno, saj ustvari precej natančno število ujemanj na podlagi ključnih točk, vendar pa je patentirano in otežuje njegovo uporabo v komercialnih aplikacijah, drugi izhod za to pa je algoritem ORB za zaznavanje predmetov.
Podobno kot metoda zaznavanja predmetov s SIFT, pri kateri smo program razdelili na dva dela, bomo tudi tu sledili istemu.
Najprej določimo funkcijo ORB_detector, ki ima dva vhoda. Eden je slika v živo, ki prihaja iz spletne kamere, druga pa je predloga slike, na podlagi katere se bomo ujemali z našo sliko. Nato sliko naše spletne kamere poslikamo v sivine, nato pa inicializiramo ORB detektor in ga tukaj nastavimo na 1000 ključnih točk in parametre skaliranja 1,2. s temi parametri se lahko enostavno poigrate, nato zaznate ključne točke (kp) in deskriptorje (des) za slike in drugi parameter, ki ga definiramo v funkciji zaznavanja ANDCompute , NI, prosi za uporabo maske slike ali ne in tukaj zanikamo.
Nato se premaknite na detektor, že prej smo uporabljali ujemanje na osnovi FLANN, toda tukaj bomo uporabili BFMatcher, znotraj BFMatcher pa bomo določili dva parametra, eden je NORM_HAMMING, drugi pa crossCheck, katerega vrednost je TRUE.
Nato izračunajte ujemanja ujemanj med tema dvema slikama z uporabo zgoraj definiranih deskriptorjev, kar pri vseh vrne število ujemanj, saj ta ujemanja niso približna in zato ni treba narediti Lowejevega razmernega testa, namesto tega uvrstitve razvrstimo glede na razdaljo, vsaj razdalja bolj kot ujemanje je boljša (tukaj razdalja pomeni razdaljo med točkama), na koncu pa vrnemo število ujemanj s funkcijo dolžine.
In v glavni funkciji smo prag postavili na veliko višjo vrednost, saj detektor orb ustvarja veliko hrupa.
Zdaj pa poglejmo kodo za odkrivanje na osnovi ORB
import cv2 import numpy kot np def ORB_detector (new_image, image_template): # Funkcija, ki primerja vhodno sliko s predlogo # Nato vrne število ORB ujemanj med njimi image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GREY) # Ustvari detektor ORB z 1000 ključnih točk s faktorjem piramide skaliranja 1,2 orb = cv2.ORB_create (1000, 1.2) # Zaznavanje ključnih točk izvirne slike (kp1, des1) = orb.detectAndCompute (image1, None) # Zaznavanje ključnih točk zasukane slike (kp2, des2) = orb.detectAndCompute (image_template, None) # Ustvari ujemanje # Upoštevajte, da ne uporabljamo več ujemanja na podlagi Flannbf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Ali ujemajo ujemanja = bf.match (des1, des2) # Razvrsti ujemanja glede na razdaljo. Najmanjša razdalja # je boljše ujemanje = razvrščeno (ujemanja, ključ = lambda val: val.distance) return len (ujemanja) cap = cv2.VideoCapture (0) # Naložite našo predlogo slike, to je naša referenčna slika image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) while True: # Pridobite slike spletne kamere ret, frame = cap.read () # Pridobite višino in širino višine okvira spletne kamere , width = frame.shape # Določite dimenzije polja ROI (upoštevajte, da bi morale biti nekatere od teh stvari zunaj zanke) top_left_x = int (width / 3) top_left_y = int ((višina / 2) + (višina / 4)) bottom_right_x = int ((širina / 3) * 2) bottom_right_y = int ((višina / 2) - (višina / 4)) # Nariši pravokotno okno za naš območje zanimanja cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Obrezovalno okno opazovanja, ki smo ga določili zgoraj cropped = frame # Flip frame direction horizontally frame = cv2.flip (frame, 1) # Pridobite število ujemanj ORB = ORB_detector (obrezano, image_template) # Prikaži niz stanja, ki prikazuje trenutno št. ujemanj output_string = "Matches =" + str ( match) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Naš prag za zaznavanje predmeta # Za nove slike ali pogoje osvetlitve boste morda morali malo eksperimentirati. # Opomba: ORB detektor, da dobite prvih 1000 zadetkov, 350 je v bistvu prag ujemanja najmanj 35% = 250 # Če ujemanja presegajo prag, potem je bil zaznan objekt, če se ujema> prag: 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 detektor uporabo ORB, okvir) , če cv2.waitKey (1) == 13: # 13 je Enter odmor kapo.release () cv2.destroyAllWindows ()
Histogram usmerjenih prelivov (HOG)
Zdaj pa se pogovorimo o drugem deskriptorju, ki je histogram usmerjenih prelivov (HOG).
HOG-ji so precej kul in uporabni deskriptorji in se pogosto in uspešno uporabljajo za zaznavanje predmetov, kot smo že videli opisniki slik, kot sta SIFT in ORB, kjer moramo izračunati ključne točke, nato pa iz teh ključnih točk izračunati deskriptorje, HOG-i to storijo drugače. To pomeni predmete kot en sam vektorjem lastnosti v primerjavi z nizom vektorji lastnosti, kjer vsak predstavlja segment slike. To pomeni, da imamo enovektorsko funkcijo za celotno sliko.
Izračuna se z detektorjem drsnih oken nad sliko, kjer je HOG deskriptor izračunan za vsak položaj. In nato se vsak položaj kombinira za en vektor funkcije.
Tako kot SIFT se tudi obseg slike prilagodi s piramidiranjem.
Prej smo uporabljali ujemanja, kot sta FLANN in BFMatcher, vendar HOG-ji to počnejo drugače s pomočjo klasifikatorjev SVM (podporni vektorski stroj), kjer se vsak izračunani deskriptor HOG pošlje v klasifikator SVM, da ugotovi, ali je bil predmet najden ali ne.
Tu je povezava do velikega prispevka Dalal & Triggs o uporabi HOG-ov za odkrivanje človeka:
Histogram usmerjenih prelivov (HOG), korak za korakom:
Razumevanje HOG je lahko precej zapleteno, toda tu se bomo ukvarjali le s teorijo HOG, ne da bi se poglobili v matematiko, povezano z njo.
Torej, vzemimo to sliko, ki je nekoliko pikselizirana, v zgornjem kotu pa je polje 8x8 slikovnih pik, zato v tem polju izračunamo vektor gradienta ali orientacije robov pri vsaki slikovni piki. Torej to pomeni, da v tem polju izračunamo vektor gradienta slike slikovnih pik znotraj polja (so neke vrste smer ali pretok same intenzivnosti slike) in to ustvari 64 (8 x 8) vektorjev gradienta, ki so nato predstavljeni kot histogram. Torej, predstavljajte si histogram, ki predstavlja vsak gradientni vektor. Torej, če bi vse točke ali intenzivnosti ležale v eno smer, bi histogram za to smer recimo 45 stopinj, imel histogram vrh pri 45 stopinjah.
To, kar zdaj počnemo, je, da vsako celico razdelimo na kotne koše, kjer vsaka koša ustreza smeri gradienta (npr. X, y). V prispevkih Dalal in Triggs sta uporabila 9 zabojnikov 0-180 ° (po 20 osi). To učinkovito zmanjša 64 vektorjev na samo 9 vrednosti. Tako smo zmanjšali velikost, vendar smo obdržali vse ključne informacije, ki so potrebne.
Naslednji korak pri izračunu prašičev je normalizacija, naklone normaliziramo, da zagotovimo nespremenljivost sprememb osvetlitve, tj. Svetlost in kontrast.
Na tej sliki so vrednosti intenzivnosti prikazane v kvadratu glede na ustrezno smer in imajo med seboj 50-odstotno razliko
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Vektorje delimo z velikostmi gradienta, za vse dobimo 0,707, to je normalizacija.
Če spremenimo intenzivnost ali spremenimo kontrast, dobimo spodnje vrednosti.
∆ 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
Normalizacija ne poteka na ravni celice, temveč poteka na ravni bloka, zato so tu bloki v bistvu skupina 4 celic, kar upošteva sosednje bloke, tako da se normalizira ob upoštevanju večjih segmentov slike.
Zdaj pa poglejmo kodo
uvoz numpy kot np uvoz cv2 uvoz matplotlib.pyplot kot plt # Naloži sliko, nato sivinsko sliko = cv2.imread ('elephant.jpg') siva = cv2.cvtColor (slika, cv2.COLOR_BGR2GRAY) # Pokaži izvirno sliko cv2.imshow (' Vhodna slika ', slika) cv2.waitKey (0) #definiranje parametrov, velikost celice in velikost bloka # hxw v slikovnih pikah cell_size = (8, 8) # hxw v celicah block_size = (2, 2) # število orientacijskih zabojnikov nbins = 9 # Uporaba OpenCV-jevega HOG deskriptorja # winSize je velikost slike, obrezane na večkratnik velikosti celice hog = cv2.HOGDescriptor (_winSize = (gray.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) # Ustvarimo uporabo numpy matrike ustvariti hog_features n_cells = (gray.shape // cell_size, grey.shape // cell_size) # Bloke najprej indeksiramo po vrsticah. # hog_feats zdaj vsebuje amplitude gradienta za vsako smer, # za vsako celico svoje skupine za vsako skupino. Indeksiranje poteka po vrsticah in stolpcih. hog_feats = hog.compute (sivo).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Ustvari naš niz gradientov z dimenzijami nbin za shranjevanje gradientnih usmeritev gradients = np.zeros ((n_cells, n_cells, nbins)) # Ustvari matriko dimenzij cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Block Normalization for off_y in range (block_size): za 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 # Povprečni prelivi prelivov / = count_count # Plot HOGs with Matplotlib # angle is 360 / nbins * direction color_bins = 5 plt.pcolor (gradients) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('enako', nastavljivo = 'polje') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Slika prikazuje, kako je vhodna slika predstavljena kot predstavitev HOG.
HAAR kaskadni klasifikatorji
Kot smo že omenili, lahko iz slike izvlečemo elemente in jih uporabimo za razvrščanje ali zaznavanje predmetov.
Kaj so HAAR kaskadni klasifikatorji?
Metoda zaznavanja predmetov, ki Haarjeve funkcije vnese v vrsto klasifikatorjev (kaskada) za prepoznavanje predmetov na sliki. Usposobljeni so za prepoznavanje ene vrste predmeta, lahko pa jih uporabljamo več vzporedno, npr. Zaznavanje oči in obrazov skupaj.
Pojasnjeni klasifikatorji HAAR:
Klasifikatorji HAAR so usposobljeni z uporabo številnih pozitivnih slik (tj. Slik z navzočim predmetom) in
negativnih slik (tj. Slik brez predmeta).
Ko imamo te slike, nato izvlečemo funkcije z uporabo drsnih oken pravokotnih blokov. Te lastnosti (značilnosti HAAR) so enojne in se izračunajo tako, da se od črnih pravokotnikov odšteje vsota intenzivnosti slikovnih pik pod belimi pravokotniki.
Vendar je to smešno število izračunov, tudi za osnovno okno 24 x 24 slikovnih pik (180.000 ustvarjenih funkcij).
Tako so raziskovalci razvili metodo, imenovano Integral Images, ki je to izračunala s štirimi referencami nizov. Vendar so še vedno imeli 180.000 funkcij in večina jih ni dodala prave vrednosti.
Povečanje je bila nato uporabljena za določitev najbolj informativne funkcije, s Freund & Schapire je AdaBoost in ugotovili najbolj informativne funkcije v sliki. Povečanje je postopek, s katerim uporabljamo šibke klasifikatorje za izdelavo močnih klasifikatorjev, preprosto tako, da damo težje tehtane kazni za nepravilne klasifikacije. Zmanjšanje 180.000 funkcij na 6000, kar je še vedno nekaj funkcij.
V teh 6000 funkcijah bodo nekatere bolj informativne kot druge. Če bi torej uporabili najbolj informativne funkcije, da bi najprej preverili, ali ima regija potencialno obraz (lažni pozitivni učinki ne bodo nič hudega). S tem odpravite potrebo po izračunu vseh 6000 funkcij hkrati. Ta koncept se imenuje kaskada klasifikatorjev - za odkrivanje obrazov je metoda Viola Jones uporabila 38 stopenj.
Zaznavanje obraza in oči
Torej, po pridobitvi teoretičnega znanja o kaskadah HAAR ga bomo končno uvedli, tako da bodo stvari precej jasne, bomo razčlenili lekcije po delih, najprej bomo zaznali čelni obraz, nato bomo premaknili čelni obraz oči in na koncu bi prek spletne kamere naredili zaznavanje obraza in oči v živo.
Za to bomo uporabili vnaprej usposobljene klasifikatorje, ki jih je OpenCV zagotovil kot datoteke.xml, xml pomeni razširljiv označevalni jezik, ta jezik se uporablja za shranjevanje velike količine podatkov, na njem lahko celo zgradite bazo podatkov.
Do teh klasifikatorjev lahko dostopate na tej povezavi .
Zaznavanje obrazov
Poskusimo za zaznavanje čelnega obraza, tukaj lahko imate dostop do kaskade čelnega detektorja obraza. Preprosto izvlecite datoteko zip, da dobite datoteko xml.
import numpy kot np import cv2 # Usmerimo funkcijo CascadeClassifier v OpenCV, kamor je shranjen naš # klasifikator (format datoteke XML), ne pozabite paziti, da bi morali imeti kodo in klasifikator v isti mapi face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load naša slika jo nato pretvori v sivinsko sliko image = cv2.imread ('Trump.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Naš klasifikator vrne ROI zaznanega obraza kot nabor # Shrani zgoraj levo koordinata in spodnja desna koordinata # vrne seznam seznamov, ki so lokacija zaznanih različnih obrazov. obrazov = face_cascade.detectMultiScale (siva, 1.3, 5) # Ko ni zaznanih obrazov, se vrne face_classifier in prazen nabor, če je obrazi (): print ("Nobenih obrazov ni mogoče najti") # Preletimo skozi niz obrazov in narišemo pravokotnik # nad vsakim obrazom v obrazih za (x, y, w, h) v obrazih: cv2.rectangle (slika, (x, y), (x + w, y + h), (127,0.255), 2) cv2.imshow ('Face Detection', image) cv2.waitKey (0) cv2.destroyAllWindows ()
Zdaj pa združimo zaznavanje obraza in oči skupaj, lahko imate dostop do kaskade detektorja oči v isti zip datoteki.
uvozi numpy kot np uvozi cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') s = cv2.cg, im. cv2.COLOR_BGR2GRAY) faces = face_classifier.detectMultiScale (siva, 1.3, 5) # Ko obraz ni zaznan, se face_classifier vrne in prazen nabor, če je face (): print ("No Face Found") za (x, y, w, h) v obrazih: 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) za (ex, ey, ew, eh) v očeh: 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)
Torej, ta številka je enaka kot toliko, kot, da je koda za zaznavanje obrazov, ampak tukaj smo dodali oči kaskade in metode za njihovo odkrivanje, kot lahko vidite, smo se odločili, Sivi pomanjšana različica obraza kot parameter za detectMultiScale za oči, kar nas pripelje do zmanjšanja računanja, saj bomo oči zaznali samo na tem območju.
Odkrivanje obraza in oči v živo
Tako smo do zdaj izvajali zaznavanje obrazov in oči, zdaj pa uporabimo enako s prenosom video posnetkov v živo s spletne kamere. Pri tem bomo naredili enako zaznavanje obraza in oči, tokrat pa bomo to storili za prenos v živo s spletne kamere. V večini aplikacije bi našli svoj obraz označen s poljem okoli njega, toda tukaj smo storili nekaj drugačnega, da bi ugotovili, da je vaš obraz obrezan in bi se oči prepoznale samo v tem.
Tukaj torej uvozimo klasifikator obraza in oči ter smo določili funkcijo za obdelavo obraza in oči. Po tem se je začel tok spletne kamere in poklical funkcijo zaznavanja obrazov za zaznavanje obraza in oči. Parameter, ki ga definiramo v funkciji zaznavanja obrazov, so neprekinjene slike iz spletnega toka v živo
import cv2 import numpy as np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5): # Pretvori sivo sliko v ccv. (img, cv2.COLOR_BGR2GRAY) obrazov = face_classifier.detectMultiScale (siva, 1.3, 5), če je obrazi (): vrni img za (x, y, w, h) v obrazih: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2.pravokotnik (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = siva roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) za (ex, ey, ew, eh) v očeh: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) return roi_color cap = cv2.VideoCapture (0) while True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)), če je cv2.waitKey (1) == 13: # 13 je Enter Key break cap.release () cv2.destroyAllWindows ()
Uglaševanje kaskadnih klasifikatorjev
Parametri, določeni znotraj zaznavanja MultiScale, razen vhodne slike, imajo naslednji pomen
našClasifikator. detectMultiScale (vhodna slika, faktor lestvice, najmanj sosedov)
- Scale Factor Določa, koliko zmanjšamo velikost slike vsakič, ko prilagodimo velikost. Npr. Pri zaznavanju obrazov običajno uporabljamo 1.3. To pomeni, da sliko zmanjšamo za 30% vsakič, ko jo prilagodimo. Manjše vrednosti, na primer 1,05, bodo trajale dlje, vendar bodo povečale stopnjo zaznavanja.
- Min Neighbours določa število sosedov, ki bi jih moralo imeti vsako potencialno okno, da bi ga lahko šteli za pozitivno. Običajno je nastavljen med 3-6. Deluje kot nastavitev občutljivosti, nizke vrednosti včasih zaznajo več obrazov na enem obrazu. Visoke vrednosti bodo zagotovile manj lažnih pozitivnih rezultatov, vendar boste morda pogrešali nekatere obraze.
Zaznavanje avtomobilov in pešcev v video posnetkih
Zdaj bomo v videoposnetkih s kaskadami HAAR zaznali pešce in avtomobile, vendar v primeru, da se noben video ne nalaga in se koda prevede brez napake, sledite naslednjim korakom:
Če se po zagonu kode noben video ne naloži, boste morda morali kopirati naš opencv_ffmpeg.dl iz : opencv \ sources \ 3rdparty \ ffmpeg, da ga prilepite tam, kjer je nameščen vaš python, npr. C: \ Anaconda2
Ko jo kopirate, jo boste morali preimenovati v skladu z različico OpenCV, ki jo uporabljate. Npr. Če uporabljate OpenCV 2.4.13, nato datoteko preimenujte v: opencv_ffmpeg2413_64.dll ali opencv_ffmpeg2413.dll (če ste z uporabo stroja X86) opencv_ffmpeg310_64.dll ali opencv_ffmpeg310.dll (če uporabljate računalnik X86)
Če želite izvedeti, kje je nameščen python.exe, zaženite ti dve vrstici kode, natisnila bi lokacijo namestitve python.
uvoz sys print (sys.executable)
Zdaj, če ste te korake uspešno izvedli, pojdimo na kodo za zaznavanje pešcev, Tu lahko priložite kaskado za zaznavanje pešcev in zip datoteko.
import cv2 import numpy kot np # Ustvarite naš klasifikator telesa body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Začnite snemati video za video datoteko, tu uporabljamo video datoteko, v kateri bi bili zaznani pešci cap = cv2.VideoCapture ('walking.avi') # Zanka, ko se videoposnetek uspešno naloži, medtem ko je cap.isOpened (): # Branje vsakega okvira video ret, frame = cap.read () # tukaj spreminjamo velikost okvirja na polovico njegove velikosti, pospešujemo klasifikacijo #, saj imajo večje slike veliko več oken za zdrs, zato na splošno zmanjšujemo ločljivost # videoposnetka na polovico je tisto, kar označuje 0,5, uporabljamo pa tudi hitrejšo metodo interpolacije, ki je #interlinear frame = cv2.resize (frame, None, fx = 0,5, fy = 0,5, interpolation = cv2.INTER_LINEAR) grey = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Pošljite okvir telesu našega klasifikatorja telesa = body_classifier.detectMultiScale (sivo, 1.2, 3) # Izvlecite mejna polja za vsa telesa, identificirana za (x, y, w, h) v telesih: cv2. pravokotnik (okvir, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Pešci', okvir), če je cv2.waitKey (1) == 13: # 13 je Enter Key break cap.release () cv2.destroyAllWindows ()
Po uspešnem zaznavanju pešca v video posnetku pojdimo na kodo za zaznavanje avtomobila. Od tu lahko dobite kaskado za zaznavanje pešcev.
import cv2 import time import numpy as np # Ustvari naš klasifikator telesa car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Zaženi zajem videoposnetka za video datoteko cap = cv2.VideoCapture ('cars.avi') # Zanka po uspešnem videoposnetku naloženo, medtem ko cap.isOpened (): time.sleep (.05) # Preberite prvi okvir ret, frame = cap.read () grey = cv2.cvtColor (frame, cv2.COLOR_BGR2GREY) # Pošljite okvir v našo avtomobilsko klasifikacijo cars = car_classifier.detectMultiScale (siva, 1.4, 2) # Izvleči omejevalna polja za vsa telesa, identificirana za (x, y, w, h) v avtomobilih: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Avtomobili', okvir), če je cv2.waitKey (1) == 13: # 13 je Enter Key break break cap.release () cv2.destroyAllWindows ()
Opazili ste, da smo dodali time.sleep (.05) , gre le za zamudo pri številu sličic, tako da lahko potrdite, da so vsi avtomobili pravilno identificirani, ali pa ga preprosto odstranite, tako da mu dodate oznako s komentarjem.
Ta članek je naveden v tečaju Master Computer Vision ™ OpenCV4 v Pythonu z globokim učenjem na Udemyju, ki ga je ustvaril Rajeev Ratan, naročite se nanj, če želite izvedeti več o Computer Visionu in Pythonu.