- Objekta noteikšana, izmantojot SIFT
- Objekta noteikšana, izmantojot ORB
- Orientēto gradientu histogramma
- Orientēto gradientu (HOG) histogramma, soli pa solim:
- HAAR kaskādes klasifikatori
- Sejas un acu noteikšana
- Dzīvā sejas un acu noteikšana
- Kaskādes klasifikatoru iestatīšana
- Automašīnu un gājēju noteikšana videoklipos
Mēs sākām ar python OpenCV instalēšanu Windows un līdz šim esam veikuši dažus pamata attēlu apstrādes, attēlu segmentēšanas un objektu noteikšanas veidus, izmantojot Python, kas ir apskatīti zemāk sniegtajās apmācībās:
- Darba sākšana ar Python OpenCV: instalēšana un attēlu pamata apstrāde
- Attēlu manipulācijas Python OpenCV (1. daļa)
- Attēlu manipulācijas OpenCV (2. daļa)
- Attēlu segmentēšana, izmantojot OpenCV - konkrētu attēla apgabalu izvilkšana
Mēs arī uzzinājām par dažādām objektu noteikšanas metodēm un algoritmiem, kur katram objektam tika noteikti daži galvenie punkti, izmantojot dažādus algoritmus. Šajā apmācībā mēs izmantosim šos algoritmus, lai noteiktu reālās dzīves objektus, šeit mēs izmantotu SIFT un ORB noteikšanai.
Objekta noteikšana, izmantojot SIFT
Šeit objektu noteikšana tiks veikta, izmantojot tiešsaistes tīmekļa kameras straumi, tādēļ, ja tā atpazīst objektu, tā pieminētu atrasto objetu. Kodā galveno daļu spēlē funkcija, kuru sauc par SIFT detektoru, lielāko daļu apstrādes veic šī funkcija.
Otrajā koda pusē mēs sākam ar tīmekļa kameras straumes atvēršanu, pēc tam ielādējiet attēla veidni, ti, atsauces attēlu, tas ir, programma faktiski skatās caur tīmekļa kameras straumi.
Tālāk mēs nepārtraukti notveršanā attēlus no webcam plūsmā ar palīdzību bezgalīgas kamēr cilpas, un pēc tam saglabāt atbilstošo augstumu un platumu webcam rāmja, un pēc tam noteikt parametrus reģiona interešu (IA) lodziņā, kurā mūsu objekts var iekļauties, uzņemot atbilstošo tīmekļa kameras rāmja augstumu un platumu. Un pēc tam no ROI parametriem, kurus mēs iepriekš definējām, mēs uzzīmējam taisnstūri. Tad beidzot izgrieziet taisnstūri un ievadiet to SWIFT detektora koda daļā.
Tagad SIFT detektoram pamatā ir divas ieejas, viena ir apgriezts attēls un otra ir attēla veidne, kuru mēs iepriekš definējām, un pēc tam tas mums dod dažas atbilstības, tāpēc sakritības būtībā ir objektu vai atslēgu punktu skaits, kas ir līdzīgi apgrieztajā attēlā un mērķa attēls. Pēc tam mēs nosakām atbilstības sliekšņa vērtību, ja atbilstības vērtība ir lielāka par slieksni, mēs ievietojam mūsu ekrānā redzamo attēlu ar zaļo ROI taisnstūra krāsu.
Tagad atgriezīsimies pie koda galvenās daļas, funkcijas, ko sauc par SIFT detektoru, tā ievada ieeju kā divus attēlus, viens ir attēls, kurā tas meklē objektu, bet otrs ir objekts, kuru mēs cenšamies saskaņot uz (attēla veidne). Tad pelēkā mērogā pirmo attēlu un attēla veidni definējiet kā otro attēlu. Tad mēs izveidojam SIFT detektora objektu un palaižam OpenCV SIFT noteikšanas un aprēķināšanas funkciju, lai noteiktu galvenos punktus un aprēķinātu aprakstus, deskriptori būtībā ir vektori, kas glabā informāciju par galvenajiem punktiem, un tas ir patiešām svarīgi, jo mēs veicam atbilstību starp attēlu aprakstītājiem.
Un pēc tam definējiet FLANN balstītu atbilstību, mēs neiedziļināmies matemātiskajā atbilstības teorijā, bet jūs varat viegli par to googlēt. Pirmkārt, definējiet indeksu kdtree uz nulli, un pēc tam mēs iestatām indeksu un meklēšanas parametrus vārdnīcas formātā, mēs vienkārši definējam algoritmu, kuru izmantosim, kas ir KDTREE, un koku skaitu, ko izmantosim, jo vairāk koku mēs izmantojam jo sarežģītāk un lēnāk. Meklēšanas parametrā definējiet pārbaužu skaitu, kas būtībā ir atbilstošo spēļu skaits.
Un pēc tam izveidojiet mūsu FLANN balstītu atbilstības objektu, ielādējot iepriekš definēto parametru, kas ir indeksa parametri un meklēšanas parametri, un, pamatojoties uz to, izveidojiet mūsu FLANN balstīto saskaņotāju, kas ir KNN sakritība, kur KNN ir K tuvākie kaimiņi, būtībā tas ir veids, kur mēs meklējam tuvākos saskaņotājus un aprakstus, un mēs veicam saskaņošanu ar inicializācijas konstanti k. Tagad šis FLANN balstītais spēlētājs atgriež iegūto spēļu skaitu.
FLANN balstītā atbilstība ir tikai aptuvena informācija, lai palielinātu FLANN balstītas atbilstības precizitāti, mēs veicam Lowe koeficienta testu, un tas, ko tas dara, meklē sakritības no knn flann bāzes matcher un definē dažus matricas parametrus, kas šeit ir attālums, kura attālums ir numpy funkcija, un, tiklīdz tas atbilst kritērijiem, pievienojiet spēles labajām spēlēm un atgriež atrastās labās spēles, tāpēc tiešraides video straume norāda ekrāna stūrī atrasto spēļu skaitu.
Tagad aplūkosim iepriekš aprakstītā apraksta kodu:
importēt cv2 importēt numpy kā np def sift_detector (new_image, image_template): # Funkcija, kas salīdzina ievades attēlu ar veidni # Pēc tam atgriež SIFT savstarpējo atbilstību skaitu image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Izveidot SIFT detektora objekts #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Iegūstiet atslēgu punktus un aprakstus, izmantojot SIFT keypoints_1, deskriptorus_1 = sift.detectAndCompute (image1, None) keypoints_2, deskriptorus2 = sift.det Neviens) # Definējiet mūsu Flann Matcher parametrus FLANN_INDEX_KDTREE = 0 index_params = dict (algoritms = FLANN_INDEX_KDTREE, koki = 3) search_params = dict (pārbaudes = 100) # Izveidot Flann Matcher objektu Flann = cv2.FlannBasedMatcher (index_params, search_params) # Iegūt spēlēm, izmantojot K-tuvāko kaimiņu metode # ka rezultāts "matchs" ir vairāki līdzīgi spēļu atrodami gan attēli spēlēs = flann.knnMatch (deskriptori_1, deskriptori_2, k = 2) # Saglabājiet labas spēles, izmantojot Lova koeficienta testu labas_atbilstības = attiecībā uz m, n mačos: ja m.attālums <0,7 * n.tālums: labas_atbilstības.apvienot (m) atgrieziet len (good_matches) cap = cv2.VideoCapture (0) # Ielādējiet mūsu attēla veidni, tas ir mūsu atsauces attēls image_template = cv2.imread ('phone.jpg', 0), bet True: # Iegūstiet tīmekļa kameras attēlus ret, rāmis = cap.read () # get augstums un platums no webcam rāmja augstums, platums = frame.shape # noteikt AI kastes izmēri top_left_x = int (platums / 3) top_left_y = INT ((augstums / 2) + (augstums / 4)) bottom_right_x = int ((width / 3) * 2) bottom_right_y = int ((height / 2) - (height / 4)) # Zīmējiet taisnstūrveida logu mūsu interesējošajam reģionam cv2. taisnstūris (rāmis, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # Iepriekš definētā novērojuma apgriešanas logs apgriezts = rāmis # Apvērst rāmja orientāciju horizontāli rāmis = cv2.flip (rāmis, 1) # Iegūt SIFT atbilstību skaitu = sift_detector (apgriezts, image_template) # Parādīt statusa virkni, kurā parādīts pašreizējais nr. sērkociņu cv2.putText (rāmis, str (atbilst), (450 450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Mūsu slieksnis, lai norādītu objekta detektēšanu # Mēs izmantojam 10, jo SIFT detektors atgriež maz viltus pozitīvu slieksnis = 10 # Ja atbilstība pārsniedz mūsu slieksni, tad objekts ir atrasts, ja atbilst> slieksnis: cv2. taisnstūris (rāmis, (augšējais kreisais_x, augšējais_lauks_j), (apakšējais_labais_x, apakšējais_labais_j), (0,255,0), 3) cv2.putText (rāmis 'Object Found', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Objekta detektors, izmantojot SIFT', rāmis), ja cv2.waitKey (1) == 13: # 13 ir Enter Key break cap. Release () cv2.destroyAllWindows ()
Objekta noteikšana, izmantojot ORB
Objektu noteikšana, izmantojot SIFT, ir diezgan atdzist un precīza, jo tā rada daudz precīzu atbilstību skaitu, pamatojoties uz galvenajiem punktiem, lai arī tā ir patentēta un kas apgrūtina tā izmantošanu komerciālām lietojumprogrammām, otra izeja tam ir ORB algoritms objektu noteikšanai.
Līdzīgi SIFT objektu noteikšanas metodei, kurā mēs sadalījām programmu divās daļās, šeit tiks ievērots tas pats.
Pirmkārt, mēs definējam funkciju ORB_detector, kas prasa divas ieejas, no kurām viena ir tiešraides attēls no tīmekļa kameras, bet otra ir attēla veidne, uz kuras pamata mēs saskaņosim savu attēlu. Tad mēs pelēktoņu mērogā mūsu tīmekļa kameras attēlu un pēc tam inicializējam mūsu ORB detektoru, un mēs to šeit iestatām 1000 galvenajos punktos un mērogošanas parametros 1,2. jūs varat viegli spēlēt ar šiem parametriem, pēc tam noteikt gan attēlu galvenos punktus (kp), gan deskriptorus (des), un otrais parametrs, kuru mēs definējam funkcijā detektētANDCompute, NAV, tas prasa izmantot attēla masku vai nē mēs to šeit noliedzam.
Pēc tam pārejiet uz detektoru, kurā iepriekš esam izmantojuši FLANN balstītu saskaņotāju, bet šeit mēs izmantosim BFMatcher, un BFMatcher iekšpusē mēs definējam divus parametrus, viens ir NORM_HAMMING, bet otrs ir crossCheck, kura vērtība ir PATIESA.
Pēc tam aprēķiniet atbilstību starp šiem diviem attēliem, izmantojot iepriekš definētos deskriptorus, kas kopumā atgriež atbilstību skaitu, jo šīs atbilstības nav aptuvenas, un tāpēc nav nepieciešams veikt Lowe koeficienta testu, tā vietā mēs sakārtojam spēles, pamatojoties uz attālumu vismazāk attālums, pēc kura spēle ir labāka (šeit attālums nozīmē attālumu starp punktiem), un beigās mēs atgriežam sērkociņu skaitu, izmantojot garuma funkciju.
Un galvenajā funkcijā mēs iestatām slieksni uz daudz lielāku vērtību, jo orbet detektors rada lielu troksni.
Tagad apskatīsim ORB noteikšanas kodu
importēt cv2 import numpy kā np def ORB_detektors (new_image, image_template): # Funkcija, kas salīdzina ievades attēlu ar veidni # Pēc tam atgriež ORB atbilstību skaitu starp tām image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Izveidojiet ORB detektoru ar 1000 atslēgas punktu ar mērogošanas piramīdas koeficientu 1,2 orb = cv2.ORB_create (1000, 1.2) # Sākotnējā attēla atslēgas punktu noteikšana (kp1, des1) = orb.detectAndCompute (image1, None) # Atrodiet pagriezta attēla galvenos punktus (kp2, des2) = orb.detectAndCompute (image_template, None) # Create matcher # Ņemiet vērā, ka mēs vairs neizmantojam Flannbased atbilstību bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Veiciet atbilstošās spēles = bf.match (des1, des2) # Kārtojiet spēles, pamatojoties uz attālumu. Vismazākais attālums # ir labāk atbilst = sakārtots (atbilst, atslēga = lambda val: val.distance) atgriezt len (sakrīt) cap = cv2.VideoCapture (0) # Ielādējiet mūsu attēla veidni, tas ir mūsu atsauces attēls image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0), bet True: # Get webcam images ret, frame = cap.read () # Get webcam frame frame height and width , width = frame.shape # Definēt ROI lodziņa izmērus (ņemiet vērā, ka dažām no šīm lietām jābūt ārpus cilpas) top_left_x = int (width / 3) top_left_y = int ((augstums / 2) + (augstums / 4)) bottom_right_x = int ((platums / 3) * 2) bottom_right_y = int ((augstums / 2) - (augstums / 4)) # Zīmējiet taisnstūra logu mūsu interesējošais reģions cv2.taisnstūris (rāmis, (augšējais_kreisais_x, augšējais_palikums_y), (apakšējais_labais_x, apakšējais_pareizais_y), 255, 3) # Iepriekš definētais novērošanas kultūraugu logs apgriezts = rāmis # Apvērst rāmja orientāciju horizontāli rāmis = cv2.flip (rāmis, 1) # Iegūt ORB atbilstību skaitu = ORB_detector (apgriezts, image_template) # Parādīt statusa virkni, kurā parādīts pašreizējais nr. no match_string = "Matches =" + str (atbilst) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Mūsu slieksnis, lai norādītu objekta detektēšanu # Lai iegūtu jaunus attēlus vai apgaismojuma apstākļus, jums, iespējams, būs nepieciešams nedaudz eksperimentēt # Piezīme: ORB detektors, lai iegūtu 1000 labākos mačus, 350 būtībā ir minimālais 35% atbilstības slieksnis = 250 # Ja spēles pārsniedz mūsu slieksnis, tad objekts ir atrasts, ja tas atbilst> slieksnis: cv2.taisnstūris (rāmis, (augšējais_kreisais_x, augšējais_līmenis_y), (apakšējais_labais_x, apakšējais_labais_j), (0,255,0), 3) cv2.putText (rāmis, 'Atrasts objekts', (50), 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Objekta detektors, izmantojot ORB', rāmis), ja cv2.waitKey (1) == 13: # 13 ir Enter Key break cap.release () cv2.destroyAllWindows ()
Orientēto gradientu histogramma
Tagad parunāsim par citu deskriptoru, kas ir Orientētu gradientu histogramma (HOG's).
HOG ir diezgan daudz atdzist un noderīgi deskriptori, un tos plaši un veiksmīgi izmanto objektu noteikšanai, kā jau iepriekš redzēts attēlu aprakstos, piemēram, SIFT un ORB, kur mums jāaprēķina galvenie punkti un pēc tam jāaprēķina deskriptori no šiem atslēgas punktiem, HOG to dara savādāk. Tas attēlo objektus kā atsevišķu iezīmju vektoru, atšķirībā no iezīmju vektoru kopas, kur katrs attēla segmentu. Tas nozīmē, ka mums ir viena vektora iezīme visam attēlam.
To aprēķina bīdāmā loga detektors virs attēla, kur HOG deskriptors tiek aprēķināts katrai pozīcijai. Un pēc tam katra pozīcija tiek apvienota vienam pazīmes vektoram.
Tāpat kā SIFT, attēla mērogs tiek pielāgots ar piramīdas palīdzību.
Iepriekš mēs izmantojām tādas atbilstības kā FLANN un BFMatcher, taču HOG to dara atšķirīgi, izmantojot SVM (atbalsta vektoru mašīnu) klasifikatorus, kur katrs aprēķinātais HOG deskriptors tiek padots SVM klasifikatoram, lai noteiktu, vai objekts ir atrasts vai nav.
Šeit ir saite uz Dalal & Triggs lielisko grāmatu par HOG izmantošanu cilvēku noteikšanai:
Orientēto gradientu (HOG) histogramma, soli pa solim:
Izpratne par HOG var būt diezgan sarežģīta, taču šeit mēs nodarbojamies tikai ar HOG teoriju, neiedziļinoties ar to saistītajā matemātikā.
Tātad, uzņemsim šo attēlu, kas ir nedaudz pikseļots, un augšējā stūrī šeit ir 8x8 pikseļu lodziņš, tāpēc šajā lodziņā mēs aprēķinām gradienta vektoru vai malu orientācijas katrā pikseļā. Tātad tas nozīmē, ka šajā lodziņā mēs aprēķinām lodziņā esošo pikseļu attēla gradienta vektoru (tie ir sava veida attēla intensitātes virziens vai plūsma), un tas ģenerē 64 (8 x 8) gradienta vektorus, kurus pēc tam attēlo kā histogrammu. Tātad iedomājieties histogrammu, kas attēlo katru gradienta vektoru. Tātad, ja visi punkti vai intensitāte atrodas vienā virzienā, šī virziena histogramma, teiksim, 45 grādi, histogrammas maksimums būs 45 grādi.
Tātad, ko mēs tagad darām, mēs sadalām katru šūnu leņķiskajās tvertnēs, kur katra tvertne atbilst gradienta virzienam (piemēram, x, y). Dalāla un Trigsa papīrā viņi izmantoja 9 atkritumu tvertnes 0-180 ° (20 ° katra tvertne). Tas efektīvi samazina 64 vektorus tikai līdz 9 vērtībām. Tātad tas, ko mēs esam izdarījuši, ir samazinājis lielumu, bet saglabājis visu nepieciešamo informāciju.
Nākamais cūku aprēķināšanas solis ir normalizācija, mēs normalizējam gradientus, lai nodrošinātu nemainību pret apgaismojuma izmaiņām, ti, spilgtumu un kontrastu.
Šajā attēlā intensitātes vērtības tiek parādītas kvadrātā atbilstoši attiecīgajam virzienam, un visām tām ir 50 atšķirības
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Mēs dalām vektorus ar gradienta lielumiem, ko visiem iegūstam 0,707, tā ir normalizācija.
Līdzīgi, ja mainām intensitāti vai mainām kontrastu, iegūstam zemāk norādītās vērtības.
∆ 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
Normalizācija nenotiek šūnu līmenī, tā vietā notiek bloku līmenī, tāpēc šeit bloki būtībā ir 4 šūnu grupa, tajā tiek ņemti vērā kaimiņu bloki, kas normalizējas, vienlaikus ņemot vērā lielākus attēla segmentus.
Tagad apskatīsim kodu
importēt numpy kā np importēt cv2 importēt matplotlib.pyplot kā plt # Ielādēt attēlu, pēc tam pelēktoņu attēlu = cv2.imread ('elephant.jpg') pelēks = cv2.cvtColor (attēls, cv2.COLOR_BGR2GRAY) # Parādīt oriģinālo attēlu cv2.imshow (' Ievades attēls ', attēls) cv2.waitKey (0) #parametru, šūnu lieluma un bloka lieluma noteikšana # hxw pikseļos cell_size = (8, 8) # hxw šūnās block_size = (2, 2) # orientācijas tvertņu skaits nbins = 9 # OpenCV HOG deskriptora izmantošana # winSize ir attēla lielums, kas apgriezts līdz šūnas lieluma hog = cv2 daudzkārtnei. 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) # Izveidojam numpy masīva formu lai izveidotu hog_features n_cells = (gray.shape // cell_size, gray.shape // cell_size) # Mēs vispirms indeksējam blokus pa rindām. # hog_feats tagad satur gradienta amplitūdas katram virzienam, # katrai tās grupas šūnai katrai grupai. Indeksēšana notiek pa rindām, pēc tam kolonnām. hog_feats = hog.compute (pelēks).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Izveidojiet mūsu gradientu masīvu ar nbin izmēriem, lai saglabātu gradienta orientācijas gradientus = np.zeros ((n_cells, n_cells, nbins)) # Izveidojiet dimensiju masīvu cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Bloka normalizēšana diapazonā off_y (block_size): off_x diapazonā (block_size): gradienti - 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 # Vidējo gradientu gradienti / = cell_count # Plānojiet HOG, izmantojot Matplotlib # leņķis ir 360 / nbins * virziens color_bins = 5 pl.pcolor (gradienti) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('vienāds', regulējams = 'lodziņš') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Attēlā parādīts, kā ievades attēls tiek attēlots kā HOG attēlojums.
HAAR kaskādes klasifikatori
Kā iepriekš tika apspriests, mēs varam iegūt attēlā funkcijas un izmantot šīs funkcijas objektu klasificēšanai vai noteikšanai.
Kas ir HAAR kaskādes klasifikatori?
Objekta noteikšanas metode, kas Haar iezīmes ievada klasifikatoru sērijā (kaskāde), lai identificētu objektus attēlā. Viņi ir apmācīti identificēt viena veida objektus, tomēr mēs varam izmantot vairākus no tiem paralēli, piemēram, kopā noteikt acis un sejas.
HAAR klasifikatori paskaidroti:
HAAR klasifikatori tiek apmācīti, izmantojot daudz pozitīvu attēlu (ti, attēlus ar esošo objektu) un
negatīvos attēlus (ti, attēlus bez objekta).
Kad mums ir šie attēli, mēs pēc tam iegūstam funkcijas, izmantojot taisnstūra bloku bīdāmos logus. Šīs pazīmes (HAAR pazīmes) ir vienas vērtības un tiek aprēķinātas, no melnajiem taisnstūriem atņemot pikseļu intensitātes summu zem baltajiem taisnstūriem.
Tomēr tas ir smieklīgs aprēķinu skaits, pat attiecībā uz 24 x 24 pikseļu bāzes logu (izveidoti 180 000 funkciju).
Tātad pētnieki izstrādāja metodi, ko sauc par Integral Images, kas to aprēķināja ar četrām masīvu atsaucēm. Tomēr viņiem joprojām bija 180 000 funkciju, un lielākā daļa no tām neradīja reālu vērtību.
Veicinot tad tika izmantota, lai noteiktu visvairāk informatīvās funkcijas, ar Freund & Schapire s AdaBoost un konstatēja, lielākā daļa informatīvo iezīmes attēla. Palielināšana ir process, kurā mēs izmantojam vājus klasifikatorus, lai izveidotu spēcīgus klasifikatorus, vienkārši nepareizai klasifikācijai piešķirot smagākus svērtos sodus. 180 000 funkciju samazināšana līdz 6000, kas joprojām ir diezgan maz.
Šajās 6000 funkcijās daži būs informatīvāki nekā citi. Tātad, ja mēs izmantojām visinformatīvākās funkcijas, lai vispirms pārbaudītu, vai reģionam var būt seja (nepatiesi pozitīvi rezultāti nebūs nekas liels). Šādi rīkojoties, vairs nav nepieciešams aprēķināt visas 6000 funkcijas vienlaikus. Šo koncepciju sauc par klasifikatoru kaskādi - sejas noteikšanai Viola Jones metode izmantoja 38 posmus.
Sejas un acu noteikšana
Tātad, pēc tam, kad esam ieguvuši teorētiskas zināšanas par HAAR kaskādēm, mēs tos beidzot īstenosim, lai lietas būtu diezgan skaidras, mēs sadalīsim stundas pa daļām, vispirms mēs atklāsim frontālo seju, pēc tam mēs pārvietosimies, lai noteiktu frontālo seju ar acis, un visbeidzot mēs tiešraidē atklātu seju un acis, izmantojot tīmekļa kameru.
Tāpēc šim nolūkam mēs izmantosim iepriekš apmācītus klasifikatorus, kurus OpenCV ir nodrošinājis kā.xml failus, xml nozīmē paplašināmu iezīmēšanas valodu, šī valoda tiek izmantota, lai uzglabātu lielu daudzumu datu, jūs pat varētu uz tā izveidot datu bāzi.
Šīm saitēm varat piekļūt šiem klasifikatoriem .
Sejas noteikšana
Izmēģināsim frontālās sejas noteikšanu. Šeit jūs varat piekļūt frontālā sejas detektora kaskādei. Vienkārši izvelciet zip failu, lai iegūtu xml failu.
import numpy as np import cv2 # Mēs novirzām OpenCV funkciju CascadeClassifier uz vietu, kur tiek glabāts mūsu # klasifikators (XML faila formāts). Neaizmirstiet kodu un klasifikatoru glabāt tajā pašā mapē face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load mūsu attēls pēc tam to pārvērš par pelēktoņu attēlu = cv2.imread ('Trump.jpg') pelēks = cv2.cvtColor (attēls, cv2.COLOR_BGR2GRAY) # Mūsu klasifikators atgriež noteiktās sejas ROI kā kopu # Tas saglabā augšējo kreiso pusi koordinātas un apakšējā labajā pusē esošās koordinātas # atgriež sarakstu sarakstu, kas ir dažādu noteikto seju atrašanās vieta. sejas = face_cascade.detectMultiScale (pelēks, 1.3, 5) # Ja sejas nav noteiktas, atgriežas face_classifier un iztukšo kopu, ja sejas ir (): print ("Nav atrastas sejas") # Mēs atkārtojam sejas masīvu un uzzīmējam taisnstūri # virs katras sejas sejām (x, y, w, h) sejās: cv2. taisnstūris (attēls, (x, y), (x + w, y + h), (127,0, 255), 2) cv2.imshow (“Sejas noteikšana”, attēls) cv2.waitKey (0) cv2.destroyAllWindows ()
Tagad apvienosim sejas un acu noteikšanu kopā, tajā pašā zip failā var piekļūt acu detektora kaskādei.
imports numpy kā NP imports CV2 face_classifier = cv2.CascadeClassifier ("haarcascade_frontalface_default.xml) eye_classifier = cv2.CascadeClassifier (" haarcascade_eye.xml) img = cv2.imread ("Trump.jpg) pelēka = cv2.cvtColor (IMG, cv2.COLOR_BGR2GRAY) sejas = face_classifier.detectMultiScale (pelēks, 1.3, 5) # Ja nav konstatēta neviena seja, face_classifier atgriežas un iztukšo kopu, ja sejas ir (): print ("Nav atrasta seja") (x, y, w, h)) sejās: cv2. taisnstūris (img, (x, y), (x + w, y + h), (127,0, 255), 2) cv2.imshow ('img', img) roi_gray = pelēks roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) acīs (ex, ey, ew, eh) acīs: cv2. taisnstūris (roi_color, (ex, ey), (ex + ew, ey + eh), (255,255,0), 2) cv2.imshow ('img', img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
Tātad šis kods ir tāds pats, cik, ka kods sejas noteikšanas, bet šeit mēs esam pievienoti acu kaskādes un metode, lai noteiktu tos, kā jūs varat redzēt, mēs esam izvēlējušies Gray samazināti versiju sejas kā parametra par detectMultiScale par acis, kas mūs noved pie skaitļošanas samazināšanās, jo acis atklāsim tikai šajā apgabalā.
Dzīvā sejas un acu noteikšana
Tātad līdz šim mēs esam veikuši sejas un acu noteikšanu, tagad īstenosim to pašu ar tiešsaistes video straumi no tīmekļa kameras. Šajā gadījumā mēs darīsim to pašu sejas un acu noteikšanu, bet šoreiz to darīsim tiešraides straumei no tīmekļa kameras. Lielākajā daļā lietojumprogrammu jūsu seja būtu izcelta ar lodziņu ap to, bet šeit mēs esam darījuši kaut ko savādāk, ka jūs atradīsit savu seju apgrieztu un acis identificētu tikai to.
Tātad šeit mēs importējam gan sejas, gan acu klasifikatoru un definējām funkciju, lai veiktu visu apstrādi sejas un acu noteikšanai. Pēc tam sākās tīmekļa kameras straume un izsauca sejas detektora funkciju sejas un acu noteikšanai. Parametrs, ko mēs definējam sejas detektora funkcijas iekšpusē, ir nepārtraukti attēli no tiešraides tīmekļa kameras straumes
importēt cv2 importēt numpy kā np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5 cays vai konvertēt attēlu (img, cv2.COLOR_BGR2GRAY) sejas = face_classifier.detectMultiScale (pelēks, 1.3, 5), ja sejas ir (): atgrieziet img par (x, y, w, h) sejās: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2. taisnstūris (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = pelēks roi_color = img acis = eye_classifier.detectMultiScale (roi_gray) priekš (ex, ey, ew, eh) acīs: cv2. taisnstūris (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) atgriezties roi_color cap = cv2.VideoCapture (0) kamēr True: ret, frame = cap.read () cv2.imshow ('Mūsu sejas nosūcējs', face_detector (rāmis)), ja cv2.waitKey (1) == 13: # 13 ir Enter Key break cap. release () cv2.destroyAllWindows ()
Kaskādes klasifikatoru iestatīšana
Parametriem, kas definēti detektētMultiScale, izņemot ievades attēlu, ir šāda nozīme
mūsuKlasifikators. discoverMultiScale (ievades attēls, mēroga faktors, minimālie kaimiņi)
- Mēroga faktors Norāda, cik daudz mēs samazinām attēla izmēru katru reizi, kad mērogojat. Piemēram, sejas noteikšanā mēs parasti izmantojam 1.3. Tas nozīmē, ka mēs katru reizi samazinām attēlu par 30%. Mazāku vērtību, piemēram, 1.05, aprēķināšana prasīs ilgāku laiku, taču palielinās noteikšanas ātrumu.
- Minimālie kaimiņi Norāda to kaimiņu skaitu, kuriem katram potenciālajam logam jābūt, lai to uzskatītu par pozitīvu atklājumu. Parasti iestatīts starp 3-6. Tas darbojas kā jutīguma iestatījums, zemas vērtības dažreiz nosaka vairākas sejas vairāk nekā vienā sejā. Augstas vērtības nodrošinās mazāk viltus pozitīvu rezultātu, taču jūs varat palaist garām dažas sejas.
Automašīnu un gājēju noteikšana videoklipos
Tagad videoklipos mēs atklāsim gājējus un automašīnas, izmantojot HAAR kaskādes, taču, ja neviens video netiek ielādēts un kods tiek apkopots bez kļūdas, jums ir jāveic šādas darbības:
Ja pēc koda palaišanas netiek ielādēts neviens video, iespējams, jums būs jākopē mūsu opencv_ffmpeg.dl no : opencv \ sources \ 3rdparty \ ffmpeg, lai ielīmētu to vietā, kur ir instalēts jūsu pitons, piemēram, C: \ Anaconda2
Kad tas būs nokopēts, jums būs jāpārdēvē fails atbilstoši izmantotās OpenCV versijai. Eg, ja izmantojat OpenCV 2.4.13, pārdēvējiet failu šādi: opencv_ffmpeg2413_64.dll vai opencv_ffmpeg2413.dll (ja izmantojat izmantojot X86 mašīnu) opencv_ffmpeg310_64.dll vai opencv_ffmpeg310.dll (ja izmantojat X86 mašīnu)
Lai uzzinātu, kur jūs esat instalējis python.exe, vienkārši palaidiet šīs divas koda rindas, tas izdrukātu vietu, kur python ir instalēts.
importēt sys print (sys.executable)
Ja esat veiksmīgi veicis šīs darbības, pārejiet pie gājēju noteikšanas koda , Jums var būt kaskāde gājēju noteikšanai un no šeit pievienotā ZIP faila.
importēt cv2 import numpy kā np # Izveidot ķermeņa klasifikatoru body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Uzsākt video uzņemšanu video failam, šeit mēs izmantojam video failu, kurā gājēji tiktu atklāti cap = cv2.VideoCapture ('walking.avi') # Cikls, kad video ir veiksmīgi ielādēts, kamēr cap.isOpened (): # Katra video kadra lasīšana ret, frame = cap.read () # šeit mēs mainām kadra izmēru uz pusi no tā lieluma, mēs darām, lai paātrinātu klasifikāciju #, jo lielākiem attēliem ir daudz vairāk logu, uz kuriem bīdīties, tāpēc kopumā mēs samazinām izšķirtspēju #of video uz pusi, ko norāda 0,5, un mēs izmantojam arī ātrāku interpolācijas metodi, kas ir #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) pelēks = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Rāmja nodošana mūsu ķermeņa klasifikatora ķermeņiem = body_classifier.detectMultiScale (pelēks, 1.2, 3) # Izņemiet ierobežojošās rūtiņas jebkurai ķermenim, kas identificēts (x, y, w, h) ķermeņos: cv2. taisnstūris (rāmis, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Gājēji', rāmis) if cv2.waitKey (1) == 13: # 13 ir Enter Key break cap. Release () cv2.destroyAllWindows ()
Pēc veiksmīgas gājēja atrašanas video, pārejiet pie automašīnas noteikšanas koda. Šeit varat iegūt gājēju noteikšanas kaskādi.
importēt cv2 importēšanas laiku importēt numpy kā np # Izveidot mūsu ķermeņa klasifikatoru car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Uzsākt video uzņemšanu video faila vāciņam = cv2.VideoCapture ('cars.avi') # Loop, kad video ir veiksmīgi ielādēts, kamēr cap.isOpened (): time.sleep (.05) # Izlasiet pirmo kadru ret, kadrs = vāciņš.read () pelēks = cv2.cvtColor (rāmis, cv2.COLOR_BGR2GRAY) # Iet rāmis mūsu automašīnu klasifikatoram cars = car_classifier.detectMultiScale (pelēks, 1.4, 2) # Izņemiet ierobežojošās rūtiņas visām virsmām , kas automašīnām apzīmētas (x, y, w, h): cv2. taisnstūris (rāmis, (x, y), (x + w, y + h)), (0, 255, 255), 2) cv2.imshow ('Cars', frame) ja cv2.waitKey (1) == 13: # 13 ir Enter Key pārtraukuma vāciņš. release () cv2.destroyAllWindows ()
Jūs esat pamanījis, ka esam pievienojuši time.sleep (.05) , tas ir tikai kadru ātruma aizkavēšanās, lai jūs varētu apstiprināt, ka visas automašīnas ir pareizi identificētas, vai arī to viegli noņemt, vienkārši pievienojot tam komentāru etiķeti.
Šis raksts ir minēts no Rajeev Ratan izveidotā Master Computer Vision ™ OpenCV4 Python ar padziļinātas mācīšanās kursu par Udemy. Abonējiet to, lai uzzinātu vairāk par Computer Vision un Python.