- Objektų aptikimas naudojant SIFT
- Objektų aptikimas naudojant ORB
- Orientuotų gradientų (HOG) histograma
- Orientuotų gradientų (HOG) histograma, žingsnis po žingsnio:
- HAAR kaskados klasifikatoriai
- Veido ir akių aptikimas
- Tiesioginis veido ir akių aptikimas
- Kaskadinių klasifikatorių derinimas
- Automobilio ir pėsčiųjų aptikimas vaizdo įrašuose
Mes pradėjome diegdami „Python OpenCV“ „Windows“ ir iki šiol atlikome keletą pagrindinių vaizdų apdorojimo, vaizdų segmentavimo ir objektų aptikimo naudojant „Python“, kurie yra aprašyti toliau pateiktose mokymo programose:
- Darbo su „Python OpenCV“ pradžia: diegimas ir pagrindinis vaizdo apdorojimas
- Vaizdo manipuliavimas „Python OpenCV“ (1 dalis)
- Vaizdo manipuliavimas „OpenCV“ (2 dalis)
- Vaizdo segmentavimas naudojant „OpenCV“ - tam tikrų vaizdo sričių išskyrimas
Mes taip pat sužinojome apie įvairius objektų aptikimo metodus ir algoritmus, kai kai kurie pagrindiniai kiekvieno objekto taškai buvo nustatyti naudojant skirtingus algoritmus. Šioje pamokoje tuos algoritmus naudosime aptikti realaus gyvenimo objektus. Čia aptikimui naudosime SIFT ir ORB.
Objektų aptikimas naudojant SIFT
Čia objektas bus aptiktas naudojant tiesioginį internetinės kameros srautą, taigi, jei jis atpažįsta objektą, jis paminėtų rastą objetą. Kode pagrindinę dalį atlieka funkcija, kuri vadinama SIFT detektoriumi, didžiąją dalį apdorojimo atlieka ši funkcija.
Kitoje kodo pusėje mes pradedame atidaryti internetinės kameros srautą, tada įkelkite vaizdo šabloną, ty pamatinį vaizdą, t. Y. Programa iš tikrųjų žiūri per internetinės kameros srautą.
Be to, mes nuolat užfiksuoti iš kameros sraute vaizdus su begalinės pagalba , o kilpa, ir tada užfiksuoti atitinkamą aukštį ir plotį kameros rėmo, ir po to, kai tada apibrėžti interesų (IG) dėžės regione parametrus, kurioje mūsų objektas gali tilpti paimdamas atitinkamą internetinės kameros rėmo aukštį ir plotį. Tada mes nupiešiame stačiakampį iš pirmiau apibrėžtų IG parametrų. Tada pagaliau apkarpykite stačiakampį ir padėkite jį į SWIFT detektoriaus kodo dalį.
Dabar SIFT detektoriuje iš esmės yra du įėjimai, vienas yra apkarpytas vaizdas, o kitas - anksčiau apibrėžtas vaizdo šablonas, tada jis suteikia mums keletą atitikmenų, taigi atitikmenys iš esmės yra objektų arba pagrindinių taškų, kurie yra panašūs apkarpytame vaizde, skaičius ir tikslinį vaizdą. Tada mes nustatome atitikmenų slenkstinę vertę, jei atitikčių vertė yra didesnė už slenkstį, mes įdėjome vaizdą, esantį mūsų ekrane, su žalia ROI stačiakampio spalva.
Dabar grįžkime prie pagrindinės kodo dalies, funkcijos, kuri vadinama SIFT detektoriumi, įvestis yra du vaizdai, vienas yra vaizdas, kuriame jis ieško objekto, o kitas yra objektas, kurį bandome suderinti į (vaizdo šabloną). Tada pilka skalė pirmąjį vaizdą ir apibrėžkite vaizdo šabloną kaip antrąjį vaizdą. Tada sukuriame SIFT detektoriaus objektą ir vykdome „OpenCV SIFT“ aptikimo ir apskaičiavimo funkciją, kad aptiktume pagrindinius taškus ir apskaičiuotume deskriptorius. Apibūdinimo elementai iš esmės yra vektoriai, kuriuose saugoma informacija apie pagrindinius taškus, ir tai tikrai svarbu, nes mes atliekame atitikimą tarp vaizdų deskriptorių.
Tada apibrėžkite FLANN pagrįstą atitikmenį, mes nesigilinsime į matematinę atitikimo teoriją, tačiau jūs galite lengvai apie tai „Google“. Pirma, nustatykite indeksą kdtree į nulį, tada nustatome indekso ir paieškos parametrus žodyno formatu, mes tiesiog apibrėžiame algoritmą, kurį ketiname naudoti, kuris yra KDTREE, ir medžių skaičių, kurį ketiname naudoti, tuo daugiau medžio mes naudojame kuo sudėtingiau ir lėčiau. Paieškos parametre nustatykite patikrinimų skaičių, kuris iš esmės yra baigtinių atitikmenų skaičius.
Tada sukurkite FLANN pagrįstą atitikties objektą, įkeldami anksčiau apibrėžtą parametrą, kurie yra indekso parametrai ir paieškos parametrai, ir, remdamiesi tuo, sukurkite mūsų FLANN pagrįstą atitikmenį, kuris yra KNN atitikmuo, kur KNN yra artimiausi K kaimynai, iš esmės tai yra būdas, kur ieškome artimiausių atitikmenų ir deskriptorių ir deriname su inicializacijos konstanta k. Dabar šis „FLANN“ pagrindu veikiantis atitikmuo pateikia mūsų gautų atitikmenų skaičių.
FLANN pagrindu atliktas atitikimas yra tik apytikslis, todėl norėdami padidinti FLANN pagrindu sukurto atitikiklio tikslumą, mes atliekame Lowe santykio testą ir tai, ką jis daro, yra tai, kad jis ieško atitikmenų iš knn flann pagrįsto atitikiklio ir apibrėžia keletą matricų parametrų, kurie yra atstumas, kurio atstumas yra „numpy“ funkcija, ir kai jis atitiks kriterijus, pridėkite atitikmenis prie gerų atitikmenų ir grąžinkite surastas geras atitiktis, taigi tiesioginiame vaizdo sraute nurodomas rungtynių, rastų ekrano kampe, skaičius.
Dabar pažvelkime į aukščiau aprašyto kodą:
importuoti cv2 import numerį kaip np def sift_detector (new_image, image_template): # Funkcija, kuri palygina įvesties vaizdą su šablonu # Tada grąžina tarp jų esančių SIFT atitikmenų skaičių image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Sukurti SIFT detektoriaus objektas #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Raskite pagrindinius taškus ir aprašus naudodami SIFT keypoints_1, deskriptorius_1 = sift.detectAndCompute (image1, None) keypoints_2, deskriptoriaiAnCompute2 Nėra) # Nurodykite „Flann Matcher“ parametrus FLANN_INDEX_KDTREE = 0 index_params = dict (algoritmas = FLANN_INDEX_KDTREE, medžiai = 3) search_params = dict (check = 100) # Sukurkite „Flann Matcher“ objektą flann = cv2.FlannBasedMatcher (index_params, search_params) # Gaukite atitikčių naudodami K-artimiausio kaimyno metodą # rezultatas „atitikmenys“ yra panašių atitikmenų, rastų abiejose vaizdų atitiktyse, skaičius = flann.knnMatch (deskriptoriai_1, deskriptoriai_2, k = 2) # Gerų atitikmenų saugokite naudodami Lowe santykio testą good_matches = m, n rungtyse : jei m.distance <0,7 * n.tolstis: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Įkelkite savo vaizdo šabloną, tai yra mūsų pamatinis vaizdas image_template = cv2.imread ('phone.jpg', 0), o True: # Gaukite žiniatinklio kameros vaizdus ret, frame = cap.read () # Gauti kameros rėmelio aukščio ir pločio aukštį, plotį = frame.shape # Apibrėžti IG langelio matmenis top_left_x = int (plotis / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((plotis / 3) * 2) bottom_right_y = int ((aukštis / 2) - (aukštis / 4)) # Nubrėžkite stačiakampį langą mūsų dominančiam regionui cv2. Stačiakampis (rėmas, (top_left_x, top_left_y)), (bottom_right_x, bottom_right_y), 255, 3) # Aukščiau apibrėžto stebėjimo langas apkarpytas = rėmelis # Apversti rėmelio orientaciją horizontaliai rėmas = cv2.flip (rėmelis, 1) # Gauti SIFT atitikmenų skaičių = sift_detector (apkarpytas, image_template) # Rodyti būsenos eilutę, rodančią dabartinį Nr. rungtynių cv2.putText (rėmas, str (atitikmenys), (450 450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Mūsų riba nurodyti objekto detekciją # Mes naudojame 10, nes SIFT detektorius pateikia mažai klaidingų teiginių slenkstis = 10 # Jei atitiktys viršija mūsų slenkstį, objektas buvo aptiktas, jei atitiktis> slenkstis: cv2.statočiakampis (rėmelis, (viršuje_kairė_x, viršutinis_kair__)), (apatinis_dešinis_x, apatinis_dešin___), (0,255,0), 3) cv2.putText (rėmelis), 'Object Found', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Objekto detektorius naudojant SIFT', rėmelis), jei cv2.waitKey (1) == 13: # 13 yra „Enter Key break“ dangtelis. Release () cv2.destroyAllWindows ()
Objektų aptikimas naudojant ORB
Objektų aptikimas naudojant SIFT yra gana šaunus ir tikslus, nes jis sukuria daug tikslių atitikmenų skaičių pagal pagrindinius taškus, tačiau yra patentuotas ir dėl to sunku jį naudoti komercinėms programoms, kita išeitis yra ORB algoritmas objekto aptikimui.
Panašiai kaip objektų aptikimo SIFT metodu, kai programą padalijome į dvi dalis, čia bus laikomasi to paties.
Pirmiausia, mes apibrėžiame funkciją ORB_detector, kuriai reikia dviejų įėjimų: vienas yra tiesioginio srauto vaizdas, gaunamas iš interneto kameros, o kitas yra vaizdo šablonas, kurio pagrindu mes suderinsime savo vaizdą. Tada mes supaprastiname internetinės kameros vaizdą, tada inicijuojame ORB detektorių ir nustatome jį čia 1000 pagrindinių taškų ir mastelio parametrų 1,2. galite lengvai žaisti naudodamiesi šiais parametrais, tada aptikti vaizdų pagrindinius taškus (kp) ir deskriptorius (des), o antrasis parametras, kurį mes nustatome funkcijoje detektuotiANDCompute yra NĖRA, jis prašo naudoti vaizdo kaukę arba ne mes tai čia neigiame.
Tada pereikite prie detektoriaus, kuriame anksčiau naudojome „FLANN“ pagrįstą atitikiklį, bet čia mes naudosime „ BFMatcher“, o „BFMatcher“ viduje nustatysime du parametrus, vienas yra NORM_HAMMING, kitas - „crossCheck“, kurio vertė yra TIESA.
Tada apskaičiuokite tų dviejų vaizdų atitikmenis naudodami aukščiau apibrėžtus deskriptorius, kurie iš viso pateikia atitikmenų skaičių, nes šios atitiktys nėra apytikslės, todėl nereikia atlikti Lowe santykio testo, o mes rūšiuojame atitikmenis pagal atstumą mažiausiai atstumas, kuo labiau rungtynės yra geresnės (čia atstumas reiškia atstumą tarp taškų), o pabaigoje mes pateikiame rungtynių skaičių naudodami ilgio funkciją.
Pagrindinėje funkcijoje mes nustatėme daug didesnę ribą, nes orbetektorius generuoja daug triukšmo.
Dabar pažvelkime į ORB nustatymo kodą
importuoti cv2 import numerį kaip np def ORB_detector (new_image, image_template): # Funkcija, kuri palygina įvesties vaizdą su šablonu # Tada grąžina ORB atitikmenų skaičių tarp jų image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Sukurkite ORB detektorių su 1000 raktinių taškų, kai piramidės koeficientas yra 1,2 arb = cv2. ORB_create (1000, 1,2) # Aptikti originalaus vaizdo pagrindinius taškus (kp1, des1) = orb.detectAndCompute (image1, None) # Aptikti pasukto vaizdo pagrindinius taškus (kp2, des2) = orb.detectAndCompute (image_template, None) # Sukurti atitikiklį # Pastaba: mes nebenaudojame „Flannbased“ atitikimo bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Atlikite atitikmenis = bf.match (des1, des2) # Rūšiuokite rungtynes pagal atstumą. Mažiausias atstumas # yra geresnis atitikimas = rūšiuojamas (atitikmenys, raktas = lambda val: val. Atstumas) grąžina len (atitinka) dangtelį = cv2.VideoCapture (0) # Įkelkite savo vaizdo šabloną, tai yra mūsų nuorodos vaizdas image_template = cv2.imread 'phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) o tiesa: # Gaukite internetinės kameros vaizdus , kadras = cap.read () # Gaukite kameros rėmelio aukščio ir pločio vaizdą , plotis = frame.shape # Apibrėžti IG langelio matmenis (atkreipkite dėmesį, kad kai kurie iš šių dalykų turėtų būti už kilpos ribų) top_left_x = int (plotis / 3) top_left_y = int ((height / 2) + (height / 4)) bottom_right_x = int ((plotis / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Nubrėžkite stačiakampį langą dominantis regionas cv2.statočiakampis (rėmas, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Aukščiau apibrėžtas stebėjimo langas apipjaustytas = rėmelis # Apversti rėmo orientaciją horizontaliai rėmelis = cv2.flip (rėmas, 1) # Gauti ORB atitikmenų skaičių = ORB_detector (apkarpytas, image_template) # Rodyti būsenos eilutę, rodančią dabartinį Nr. rungtynių output_string = "Matches =" + str ( match) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Mūsų riba nurodyti objekto detekciją # Norėdami gauti naujų vaizdų ar apšvietimo sąlygų, gali tekti šiek tiek eksperimentuoti # Pastaba: ORB detektorius, kad gautumėte 1000 geriausių atitikmenų, 350 iš esmės yra mažiausiai 35% atitikties slenkstis = 250 # Jei atitikmenys viršija mūsų slenkstis, tada objektas buvo aptiktas, jei atitiko > slenkstis: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (frame, 'Found Object, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow („Object Detector using ORB“, frame) if cv2.waitKey (1) == 13: # 13 yra Enter Key break cap.release () cv2.destroyAllWindows ()
Orientuotų gradientų (HOG) histograma
Dabar pakalbėkime apie kitą deskriptorių, kuris yra orientuotų gradientų histograma.
HOG yra gana šaunūs ir naudingi deskriptoriai, ir jie yra plačiai ir sėkmingai naudojami objektų aptikimui, kaip jau buvo matyti anksčiau, vaizdų aprašai, pvz., SIFT ir ORB, kur mes turime apskaičiuoti pagrindinius taškus, o tada turime apskaičiuoti deskriptorius iš tų pagrindinių taškų, HOG daro tą procesą kitaip. Jis vaizduoja objektus kaip vieną ypatybių vektorių, priešingai nei ypatybių vektorių rinkinį, kur kiekvienas reiškia vaizdo segmentą. Tai reiškia, kad mes turime vieną vektorinę funkciją visam vaizdui.
Tai apskaičiuojama slenkančiu langų detektoriumi virš vaizdo, kur kiekvienai padėčiai apskaičiuojamas HOG aprašas. Tada kiekviena pozicija sujungiama vienam požymio vektoriui.
Kaip ir SIFT, vaizdo mastelis koreguojamas piramidės būdu.
Anksčiau mes naudojome tokius atitikmenis kaip „FLANN“ ir „BFMatcher“, tačiau HOG tai daro kitaip, naudodamiesi SVM (palaikomojo vektoriaus mašina) klasifikatoriais, kur kiekvienas apskaičiuotas HOG deskriptorius tiekiamas į SVM klasifikatorių, kad būtų galima nustatyti, ar objektas buvo rastas, ar ne.
Čia pateikiama nuoroda į puikų Dalal & Triggs straipsnį apie HOG naudojimą žmogaus aptikimui:
Orientuotų gradientų (HOG) histograma, žingsnis po žingsnio:
Suprasti HOG gali būti gana sudėtinga, tačiau čia mes nagrinėsime tik HOG teoriją, nesigilindami į su ja susijusią matematiką.
Taigi paimkime šią nuotrauką šiek tiek pikselių, o viršutiniame kampe yra 8x8 pikselių langelis, taigi šiame laukelyje apskaičiuojame gradiento vektorių arba krašto orientacijas kiekviename pikselyje. Tai reiškia, kad šiame laukelyje mes apskaičiuojame pikselių vaizdo gradiento vektorių dėžutės viduje (jie yra tarsi vaizdo intensyvumo kryptis arba srautas), ir tai sukuria 64 (8 x 8) gradiento vektorius, kurie tada vaizduojami kaip histograma. Taigi įsivaizduokite histogramą, vaizduojančią kiekvieną gradiento vektorių. Taigi, jei visi taškai ar intensyvumas gulėtų viena kryptimi, tos krypties histograma, tarkime, 45 laipsniai, histogramos pikas būtų 45 laipsnių.
Taigi, ką mes darome dabar, mes padalijame kiekvieną ląstelę į kampines dėžes, kur kiekviena šiukšliadėžė atitinka gradiento kryptį (pvz., X, y). Dalal ir Triggs popieriuje jie naudojo 9 šiukšliadėžes 0-180 ° (po 20 ° kiekvienoje šiukšliadėžėje). Tai efektyviai sumažina 64 vektorius tik iki 9 reikšmių. Taigi tai, ką mes padarėme, sumažino dydį, tačiau išsaugojo visą reikalingą informaciją.
Kitas žingsnis apskaičiuojant kiaulę yra normalizavimas, mes normalizuojame nuolydžius, kad būtų užtikrinta invarsija į apšvietimo pokyčius, ty ryškumą ir kontrastą.
Šiame paveikslėlyje intensyvumo vertės yra rodomos kvadrate pagal atitinkamą kryptį, ir visos turi 50 skirtumų
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Mes padalijame vektorius iš gradiento dydžių, kuriuos gauname 0,707 visiems, tai yra normalizavimas.
Panašiai, jei pakeisime intensyvumą ar kontrastą, gausime žemiau pateiktas reikšmes.
∆ 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
Normalizavimas nevyksta ląstelių lygiu, o vyksta blokų lygiu, taigi čia blokai iš esmės yra 4 langelių grupė, atsižvelgiant į kaimyninius blokus, kurie normalizuojami, atsižvelgiant į didesnius vaizdo segmentus.
Dabar pažvelkime į kodą
importuoti numpy kaip np importuoti cv2 importuoti matplotlib.pyplot kaip plt # Įkelti vaizdą, tada pilkumo skalę image = cv2.imread ('elephant.jpg') pilka = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Rodyti originalų vaizdą cv2.imshow (' Įvesties vaizdas ', vaizdas) cv2.waitKey (0) # parametrų, langelio dydžio ir bloko dydžio nustatymas # hxw pikseliais cell_size = (8, 8) # hxw ląstelėse block_size = (2, 2) # orientacinių dėžių skaičius nbins = 9 # „OpenCV“ HOG deskriptoriaus naudojimas # winSize yra vaizdo dydis, nukirptas į daugkartinį langelio dydį hog = cv2. HOGDescriptor (_winSize = (pilka.forma // ląstelių_dydis * ląstelių_dydis, gray.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) # Sukuriame numpy masyvo formą norėdami sukurti „hog_features“ n_cells = (gray.shape // cell_size, gray.shape // cell_size) # Pirmiausia indeksuojame blokus pagal eilutes. Dabar „# hog_feats“ yra kiekvienos krypties gradiento amplitudės, # kiekvienos grupės grupės ląstelės kiekvienai grupei. Indeksavimas atliekamas eilutėmis, tada stulpeliais. hog_feats = hog.compute (pilka).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Sukurkite gradientų masyvą su nbin matmenimis, kad galėtumėte laikyti gradiento orientacijas gradientai = np.zeros ((n_cells, n_cells, nbins)) # Sukurkite matmenų masyvą cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Bloko normalizavimas „off_y“ diapazone („block_size“): „off_x“ diapazone („block_size“): gradientai - 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 # Vidutiniai gradientų gradientai / = cell_count # Nubraižykite HOG, naudodami Matplotlib # kampas yra 360 / nbins * kryptis color_bins = 5 plt.pcolor (gradientai) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('lygus', reguliuojamas = 'dėžutė') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Paveikslėlyje parodyta, kaip įvestas vaizdas vaizduojamas kaip HOG pavaizdavimas.
HAAR kaskados klasifikatoriai
Kaip jau buvo aptarta anksčiau, mes galime išgauti atvaizdo ypatybes ir jas naudoti objektams klasifikuoti ar aptikti.
Kas yra HAAR kaskados klasifikatoriai?
Objektų aptikimo metodas, įvedantis Haaro ypatybes į klasifikatorių (kaskados) seriją, siekiant atpažinti atvaizdo objektus. Jie mokomi atpažinti vieno tipo objektus, tačiau kelis iš jų galime naudoti lygiagrečiai, pvz., Kartu aptikti akis ir veidus.
HAAR klasifikatoriai paaiškinti:
HAAR klasifikatoriai mokomi naudojant daugybę teigiamų vaizdų (ty vaizdų su objektu) ir
neigiamų vaizdų (ty vaizdų be objekto).
Turėdami tuos vaizdus, išskleidžiame funkcijas naudodami stumdomus stačiakampių blokų langus. Šios savybės (HAAR ypatybės) yra vienos vertės ir apskaičiuojamos atimant pikselių intensyvumo sumą po baltais stačiakampiais iš juodų stačiakampių.
Tačiau tai yra juokingai skaičiavimai, net ir baziniam 24 x 24 taškų langui (sukurta 180 000 funkcijų).
Taigi mokslininkai sukūrė metodą, pavadintą „ Integral Images“, kuris apskaičiavo tai su keturiomis masyvo nuorodomis. Tačiau jie vis dar turėjo 180 000 savybių, o dauguma jų nepridėjo jokios realios vertės.
Didėjanti buvo tada naudojamas nustatyti labiausiai informatyvus funkcijų, su Freundo Schapire anketa AdaBoost ir rasti informatyviausius funkcijų paveikslėlyje. „Boosting“ yra procesas, kurio metu mes naudojame silpnus klasifikatorius, kad sukurtume stiprius klasifikatorius, paprasčiausiai paskirdami sunkesnes svertines baudas už neteisingą klasifikaciją. Sumažinti 180 000 funkcijų iki 6000, o tai vis dar yra nemažai funkcijų.
Tose 6000 funkcijose vieni bus informatyvesni nei kiti. Taigi, jei mes naudojome labiausiai informatyvias savybes, kad pirmiausia patikrintume, ar regionas gali turėti veidą (klaidingi teigiami dalykai nebus didelė problema). Tokiu būdu nebereikia apskaičiuoti visų 6000 funkcijų vienu metu. Ši koncepcija vadinama klasifikatorių kaskadu - veidui aptikti Viola Jones metodas panaudojo 38 etapus.
Veido ir akių aptikimas
Taigi įgiję teorinių žinių apie HAAR kaskadas, mes pagaliau jas įgyvendinsime, kad viskas būtų aišku, mes dalinsime pamokas dalimis, pirmiausia aptiksime priekinį veidą, o po to judėsime, kad nustatytume priekinį veidą su akis ir pagaliau mes tiesiogiai aptiktume veidą ir akis per internetinę kamerą.
Taigi tam naudosime iš anksto paruoštus klasifikatorius, kuriuos „OpenCV“ pateikė kaip.xml failus, xml reiškia išplėstinę žymėjimo kalbą, ši kalba naudojama didžiuliam duomenų kiekiui saugoti, netgi galite sukurti joje duomenų bazę.
Šiuos klasifikatorius galite pasiekti šioje nuorodoje .
Veido atpažinimas
Pabandykime nustatyti priekinį veido aptikimą, čia galite pasiekti priekinio veido detektoriaus kaskadą. Tiesiog ištraukite ZIP failą, kad gautumėte xml failą.
import numerį kaip np importuoti cv2 # Nukreipiame „ OpenCV“ funkciją „CascadeClassifier“ ten, kur saugomas mūsų # klasifikatorius (XML failo formatas). Nepamirškite kodą ir klasifikatorių laikyti tame pačiame aplanke face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Įkelti tada mūsų vaizdas konvertuoja jį į pilkos spalvos vaizdą = cv2.imread ('Trump.jpg') pilka = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Mūsų klasifikatorius grąžina aptikto veido IG kaip dvigubą # Jis saugo viršuje kairėje koordinatės ir apatinės dešinės koordinatės # grąžina sąrašų sąrašą, kuriame nurodomi skirtingi aptikti veidai. veidai = face_cascade.detectMultiScale (pilka, 1.3, 5) # Kai veidų neaptikta, grįžta „face_classifier“ ir tuščias kartelis, jei veidai yra (): print („Nerasta veidų“) # Mes kartojamės per veidų masyvą ir brėžiame stačiakampį # ant kiekvieno veido (x, y, w, h) veiduose: cv2. stačiakampis (vaizdas, (x, y), (x + w, y + h), (127,0, 255), 2) cv2.imshow („Veido aptikimas“, vaizdas) cv2.waitKey (0) cv2.destroyAllWindows ()
Dabar sujungsime veido ir akių aptikimą kartu, jūs galite pasiekti akių detektoriaus kaskadą tame pačiame ZIP faile.
import numerį kaip np importuoti cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpgc) ( pilka cv2.COLOR_BGR2GRAY) veidai = face_classifier.detectMultiScale (pilka, 1.3, 5) # Jei veidų neaptikta, face_classifier grįžta ir tuščias kartotinis elementas, jei veidai yra (): print ("Nerasta veido" už (x, y, w, h)) veiduose: cv2. stačiakampis (img, (x, y), (x + w, y + h), (127,0, 255), 2) cv2.imshow ('img', img) roi_gray = pilkas roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) už (ex, ey, ew, eh) akyse: cv2.staciakampis (roi_color, (ex, ey), (ex + ew, ey + eh), (255,255,0), 2) cv2.imshow ('img', img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
Taigi, šis kodas yra toks pat, kaip, kiek, kad už veido aptikimo kodas, bet čia mes pridėti akių kaskadomis ir vartojimo metodas aptikti juos, kaip jūs galite pamatyti, mes pasirinkome Pilka mastelis versiją veido kaip už parametro detectMultiScale už akis, o tai leidžia mums sumažinti skaičiavimą, nes akis aptiksime tik toje srityje.
Tiesioginis veido ir akių aptikimas
Taigi iki šiol mes atlikome veido ir akių aptikimą, dabar įgyvendinkime tą patį su tiesioginiu vaizdo srautu iš internetinės kameros. Tai atliksime tuo pačiu veido ir akių aptikimu, tačiau šį kartą tai padarysime tiesioginei interneto kameros transliacijai. Daugumoje programų jūsų veidas būtų paryškintas langeliu aplink jį, tačiau čia mes padarėme kažką kitaip, kad jūsų veidas būtų iškirptas, o akys atpažintų tik tai.
Taigi čia importuojame veido ir akių klasifikatorių ir apibrėžėme funkciją, skirtą visam veido ir akių aptikimo procesui atlikti. Po to prasidėjo internetinės kameros srautas ir iškvietė veido detektorių, kad veidas ir akys būtų aptikti. Parametras, kurį mes nustatome veido detektoriaus funkcijos viduje, yra nepertraukiami vaizdai iš tiesioginio interneto kameros srauto
importo CV2 importo numpy kaip NP face_classifier = cv2.CascadeClassifier ("haarcascade_frontalface_default.xml) eye_classifier = cv2.CascadeClassifier (" haarcascade_eye.xml) Def face_detector (IMG, dydis = 0,5): # konvertuoti vaizdą pustoniai pilka = cv2.cvtColor [img, cv2.COLOR_BGR2GRAY] veidai = face_classifier.detectMultiScale (pilka, 1.3, 5), jei veidai yra (): grąžinkite img (x, y, w, h) veiduose: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2. stačiakampis (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = pilka roi_color = img akis = „eye_classifier.detectMultiScale“ („roi_gray“) (ex, ey, ew, eh) akyse: cv2.staciakampis (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) grįžti roi_color cap = cv2.VideoCapture (0) o True: ret, frame = cap.read () cv2.imshow ('Mūsų veido ištraukėjas', face_detector (rėmelis)), jei cv2.waitKey (1) == 13: # 13 yra Enter Key pertraukos dangtelis. release () cv2.destroyAllWindows ()
Kaskadinių klasifikatorių derinimas
Parametrai, nustatyti „ detectMultiScale“ viduje, išskyrus įvesties vaizdą, turi tokią reikšmę
mūsųKlasifikatorius. discoverMultiScale (įvesties vaizdas, mastelio koeficientas, minimalūs kaimynai)
- „Scale Factor“ nurodo, kiek sumažiname vaizdo dydį kiekvieną kartą keičiant mastelį. Pvz., Veido atpažinime mes dažniausiai naudojame 1.3. Tai reiškia, kad kiekvieną kartą sumažinus vaizdą 30%. Mažesnių verčių, pvz., 1,05, skaičiavimas užtruks ilgiau, tačiau padidės aptikimo greitis.
- Minimalūs kaimynai Nurodo kaimynų skaičių, kurį turėtų turėti kiekvienas potencialus langas, kad būtų galima teigiamai aptikti. Paprastai nustatoma tarp 3-6. Tai veikia kaip jautrumo nustatymas, kai mažos vertės kartais aptiks kelis veidus per vieną veidą. Didelės vertės užtikrins mažiau klaidingų teigiamų rezultatų, tačiau galite praleisti kai kuriuos veidus.
Automobilio ir pėsčiųjų aptikimas vaizdo įrašuose
Dabar vaizdo įrašuose aptiksime pėsčiuosius ir automobilius naudodamiesi HAAR kaskadomis, tačiau tuo atveju, jei vaizdo įrašas neįkeliamas ir kodas sukompiliuojamas be klaidos, turite atlikti šiuos veiksmus:
Jei paleidus kodą vaizdo įrašas neįkeliamas , gali tekti nukopijuoti mūsų opencv_ffmpeg.dl iš : opencv \ sources \ 3rdparty \ ffmpeg, kad įklijuotumėte jį ten, kur įdiegtas jūsų pitonas, pvz., C: \ Anaconda2
Kai jis nukopijuojamas reikės pervadinti failą pagal OpenCV esate using.eg jei jūs naudojate OpenCV 2.4.13 tada pervardyti failą versija: opencv_ffmpeg2413_64.dll ar opencv_ffmpeg2413.dll (jei esate naudojant „X86“ mašiną) „ opencv_ffmpeg310_64.dll“ arba „opencv_ffmpeg310.dll“ (jei naudojate „X86“ mašiną)
Norėdami sužinoti, kur įdiegta python.exe, tiesiog paleiskite šias dvi kodo eilutes, tai atspausdins vietą, kurioje įdiegtas python.
importuoti sys spausdinimą (sys.executable)
Jei sėkmingai atlikote šiuos veiksmus, pereikime prie pėsčiųjų aptikimo kodo , Čia galite pridėti kaskadą pėstiesiems aptikti ir iš ZIP failo.
importuoti cv2 import numerį kaip np # Sukurkite kūno klasifikatorių body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Inicijuokite vaizdo įrašo rinkimą, čia mes naudojame vaizdo failą, kuriame pėstieji būtų aptikti cap = cv2.VideoCapture („walking.avi“) # Loop, kai vaizdo įrašas bus sėkmingai įkeltas, kol cap.isOpened (): # Skaitydami kiekvieną vaizdo įrašo kadrą ret, frame = cap.read () # čia mes keičiame kadro dydį iki pusės jo dydžio, mes stengiamės pagreitinti klasifikavimą # nes didesni vaizdai turi daug daugiau langų, kuriuos galima perkelti, todėl apskritai mes mažiname skiriamąją gebą #of video per pusę, tai rodo 0,5, taip pat naudojame greitesnį interpoliacijos metodą, kuris yra #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) pilka = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Perduokite rėmą į savo kūno klasifikatoriaus kūnus = body_classifier.detectMultiScale (pilka, 1.2, 3) # Ištraukite ribojančius langelius bet kokiems kūnams, pažymėtiems (x, y, w, h) kūnuose: cv2. stačiakampis (rėmas, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Pėstieji', rėmelis) if cv2.waitKey (1) == 13: # 13 yra Enter Key break cap. Release () cv2.destroyAllWindows ()
Sėkmingai aptikę pėsčiuosius vaizdo įraše, pereikime prie automobilio aptikimo kodo. Čia galite rasti pėsčiųjų aptikimo kaskadą.
importuoti cv2 importo laiką importuoti numpy kaip np # Sukurkite kūno klasifikatorių car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Inicijuoti vaizdo įrašo rinkimą vaizdo failo dangteliui = cv2.VideoCapture ('cars.avi') # Pakartokite, kai vaizdo įrašas bus sėkmingai įkeltas, kol cap.isOpened (): time.sleep (.05) # Skaityti pirmąjį kadrą ret, frame = dangtelis. read () pilkas = cv2.cvtColor (rėmas, cv2.COLOR_BGR2GRAY) # Perduoti rėmą mūsų automobilių klasifikatoriui automobiliai = car_classifier.detectMultiScale (pilka, 1.4, 2) # Ištraukite ribojančius langelius bet kokiems kūnams, pažymėtiems (x, y, w, h) automobiliuose: cv2. stačiakampis (rėmas, (x, y), (x + w, y + h)), (0, 255, 255), 2) cv2.imshow ('Automobiliai', rėmas), jei cv2.waitKey (1) == 13: # 13 yra Enter Key pertraukos dangtelis. release () cv2.destroyAllWindows ()
Pastebėjote, kad pridėjome time.sleep (.05) , tai tik vėlavimo kadrų dažnis, kad galėtumėte patvirtinti, jog visi automobiliai yra teisingai identifikuoti, arba galite lengvai jį pašalinti, tiesiog pridėdami komentaro etiketę.
Šis straipsnis pateiktas iš Rajeev Ratan sukurto „Master Computer Vision ™ OpenCV4“ programoje „Python“ su gilaus mokymosi „Udemy“ kursu. Prenumeruokite jį, kad sužinotumėte daugiau apie „Computer Vision“ ir „Python“.