- Pagtuklas ng object gamit ang SIFT
- Pagtuklas ng object gamit ang ORB
- Histogram ng oriented Gradients (HOG's)
- Histogram ng oriented Gradients (HOG's), Hakbang sa Hakbang:
- Mga classifier ng HAC cascade
- Pagtuklas sa Mukha at Mata
- Live na Pagtuklas ng Mukha at Mata
- Mga Classifier ng Cascade ng Pag-tune
- Pagtuklas ng Kotse at Pedestrian sa mga video
Nagsimula kami sa pag-install ng python OpenCV sa mga bintana at sa ngayon ay tapos na ang ilang pangunahing pagproseso ng imahe, paghihiwalay ng imahe at pagtuklas ng bagay gamit ang Python, na sakop sa mga tutorial sa ibaba:
- Pagsisimula sa Python OpenCV: Pag-install at Pangunahing Pagproseso ng Imahe
- Mga Manipulasyon ng Imahe sa Python OpenCV (Bahagi 1)
- Mga Pagmanipula ng Larawan sa OpenCV (Bahagi-2)
- Pagse-segment ng Larawan gamit ang OpenCV - Pagkuha ng mga tukoy na Lugar ng isang imahe
Nalaman din namin ang tungkol sa iba't ibang mga pamamaraan at algorithm para sa Pagtuklas ng Bagay kung saan ang ilang mga pangunahing punto ay nakilala para sa bawat bagay na gumagamit ng iba't ibang mga algorithm. Sa tutorial na ito gagamitin namin ang mga algorithm na iyon upang matukoy ang mga totoong bagay sa buhay, dito gagamitin namin ang SIFT at ORB para sa pagtuklas.
Pagtuklas ng object gamit ang SIFT
Dito magagawa ang pagtuklas ng bagay gamit ang live na stream ng webcam, kaya kung makikilala ang bagay na ito ay banggitin ang nahanap na objet. Sa code ang pangunahing bahagi ay nilalaro ng pagpapaandar na tinatawag na SIFT detector, ang karamihan sa pagpoproseso ay ginagawa ng pagpapaandar na ito.
At sa iba pang kalahati ng code, nagsisimula kami sa pagbubukas ng stream ng webcam, pagkatapos ay i-load ang template ng imahe, ibig sabihin ang imahe ng sanggunian, iyon ang programa na talagang tumitingin sa stream ng webcam.
Susunod, patuloy naming kinukuha ang mga imahe mula sa webcam stream sa tulong ng walang katapusan habang loop, at pagkatapos ay kunan ang kaukulang taas at lapad ng webcam frame, at pagkatapos ay tukuyin ang mga parameter ng kahon ng rehiyon ng interes (ROI) kung saan ang aming object ay maaaring magkasya sa pamamagitan ng pagkuha ng kaukulang taas at lapad ng frame ng webcam. At pagkatapos ay iginuhit namin ang rektanggulo mula sa mga parameter ng ROI na tinukoy namin sa itaas. Pagkatapos sa wakas ay i-crop ang rektanggulo at pakainin ito sa bahagi ng detector ng SWIFT ng code.
Ngayon ang SIFT detector ay karaniwang may dalawang mga input, ang isa ay ang na-crop na imahe at ang isa pa ay ang template ng imahe na dati naming tinukoy at pagkatapos ay binibigyan kami ng ilang mga tugma, kaya't ang mga tugma ay karaniwang bilang ng mga bagay o keypoints na magkatulad sa na-crop na imahe at ang target na imahe. Pagkatapos ay tinutukoy namin ang isang halaga ng threshold para sa mga tugma, kung ang halaga ng mga tugma ay mas malaki kaysa sa threshold, naglalagay kami ng imahe na matatagpuan sa aming screen na may berdeng kulay ng ROI rektanggulo.
Bumalik tayo ngayon sa pangunahing bahagi ng code, ang pagpapaandar na tinatawag na SIFT detector, kukuha ng input bilang dalawang imahe ang isa ay ang imahe kung saan hinahanap nito ang bagay at iba pa ay ang bagay na sinusubukan naming itugma sa (template ng imahe). Pagkatapos ay sukatin ang unang imahe at tukuyin ang template ng imahe bilang pangalawang imahe. Pagkatapos ay lumikha kami ng isang object ng detektor ng SIFT at pinapatakbo ang pag-andar ng OpenCV SIFT at pag-compute ang function, upang matukoy ang mga keypoint at kalkulahin ang mga tagapaglarawan, ang mga tagapaglaraw ay karaniwang mga vector na nag-iimbak ng impormasyon tungkol sa mga keypoints, at talagang mahalaga habang ginagawa namin ang pagtutugma sa pagitan ng mga naglalarawan ng mga imahe.
At pagkatapos ay tukuyin ang FLANN based matcher, hindi kami pupunta sa teorya ng matematika ng pagtutugma sa likuran nito, ngunit madali mo itong ma-Google tungkol dito. Una, tukuyin ang index kdtree sa zero at pagkatapos ay itinakda namin ang index at mga parameter ng paghahanap sa format ng diksyunaryo, tinukoy lamang namin ang algorithm na gagamitin namin na kung saan ay ang KDTREE, at ang bilang ng mga puno na gagamitin namin, mas maraming puno ginagamit namin ang mas kumplikadong nakukuha nito at mas mabagal. At sa parameter ng paghahanap tinukoy ang bilang ng mga tseke, na kung saan ay karaniwang bilang ng mga tugma na makukumpleto nito.
At pagkatapos ay likhain ang aming bagay na batay sa FLANN matcher sa pamamagitan ng paglo-load ng parameter na dati naming tinukoy na mga parameter ng index at mga parameter ng paghahanap at batay dito nilikha ang aming FLANN based matcher, na kung saan ay isang KNN matcher kung saan ang KNN ay K-pinakamalapit na kapitbahay, isa lamang itong paraan kung saan naghahanap kami para sa pinakamalapit na mga matrador at tagapaglarawan at ginagawa namin ang pagtutugma sa pare-pareho ng pagpapasimula k. Ngayon ang FLANN based matcher na ito ay nagbabalik ng bilang ng mga tugma na nakukuha namin.
Ang pagtutugma batay sa FLANN ay isang pagtatantya lamang, upang madagdagan ang kawastuhan ng FLANN based matcher nagsasagawa kami ng isang pagsubok sa ratio ng Lowe at kung ano ang ginagawa nito ay hinahanap nito ang mga tugma mula sa knn flann based matcher at tukuyin ang ilang mga parameter ng matric na kung saan ang distansya dito, para sa kung aling distansya ang isang function na numpy, at kapag natugunan nito ang mga pamantayan idagdag ang mga tugma sa magagandang tugma at ibabalik ang magagandang tugma na natagpuan, at sa gayon ang live na stream ng video ay nagsasabi sa bilang ng mga tugma na matatagpuan sa sulok ng screen.
Ngayon tingnan natin ang code para sa paglalarawan sa itaas:
i-import ang cv2 import numpy bilang np def sift_detector (new_image, image_template): # Function na ihinahambing ang input na imahe sa template # Pagkatapos ay ibabalik ang bilang ng mga tugma na SIFT sa pagitan nila ng image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Lumikha SIFT detector object #sift = cv2.SIFT () sift = cv2.xfeature2d.SIFT_create () # Makuha ang mga keypoint at deskripsyon gamit ang SIFT keypoints_1, descriptors_1 = sift.detectAndCompute (image1, Wala) keypoints_2, descriptors_2 = sift.detectAndCompute Wala) # Tukuyin ang mga parameter para sa aming Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (algorithm = FLANN_INDEX_KDTREE, mga puno = 3) search_params = dict (tseke = 100) # Lumikha ng Flann Matcher object flann = cv2.FlannBasedMatcher (index_params, search_params) # Kumuha ng mga tugma gamit ang K-Pinakamalapit na Pamamaraan ng Kapwa # ang resulta ng 'mga tugma' ay ang bilang ng mga katulad na tugma na matatagpuan sa parehong mga tugma ng imahe = flann.knnMatch (descriptors_1, descriptors_2, k = 2) # Mag-imbak ng magagandang tugma gamit ang mahusay na pagsubok sa ratio ng Lowe = para sa m, n sa mga tugma: kung m.distansya <0.7 * n.distansya: good_matches.append (m) ibalik ang len (good_matches) cap = cv2.VideoCapture (0) # I-load ang aming template ng imahe, ito ang aming sanggunian na imahe na imahe_template = cv2.imread ('phone.jpg', 0) habang Totoo: # Kumuha ng mga imahe ng webcam ret, frame = cap.read () # Kumuha ng taas at lapad ng taas ng frame ng webcam , lapad = frame.shape # Tukuyin ang Mga Dimensyon ng ROI Box top_left_x = int (lapad / 3) top_left_y = int ((taas / 2) + (taas / 4)) ilalim_ kanan_x = int ((lapad / 3) * 2) ilalim_right_y = int ((taas / 2) - (taas / 4)) # Gumuhit ng parihabang window para sa aming rehiyon ng interes cv2.rectangle (frame, (top_left_x, top_left_y), (ilalim_ kanan_x, ilalim_ kanan_y), 255, 3) # I-crop ang window ng pagmamasid na tinukoy namin sa itaas na na- crop = frame # Flip frame orientation na pahalang na frame = cv2.flip (frame, 1) # Kumuha ng bilang ng mga tugma sa SIFT na tugma = sift_detector (na-crop, image_template) # Ipakita ang string ng katayuan na nagpapakita ng kasalukuyang hindi. ng mga tugma cv2.putText (frame, str (mga tugma), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Ang aming threshold upang ipahiwatig ang deteciton ng bagay # Gumagamit kami ng 10 dahil ang SIFT detector ay nagbabalik ng maliit na maling mga positibo threshold = 10 # Kung ang mga tugma ay lumampas sa aming threshold pagkatapos ay napansin ang object kung ang mga tugma> threshold: cv2.rectangle (frame, (top_left_x, top_left_y), (ilalim_ 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 ('Detector ng Bagay na gumagamit ng SIFT', frame) kung cv2.waitKey (1) == 13: Ang # 13 ay ang Enter Key break cap.release () cv2.destroyAllWindows ()
Pagtuklas ng object gamit ang ORB
Ang pagtuklas ng object gamit ang SIFT ay medyo cool at tumpak, dahil bumubuo ito ng isang tumpak na bilang ng mga tugma batay sa mga keypoint, subalit ang patentadong ito at ginagawang mahirap para sa paggamit nito para sa mga komersyal na aplikasyon, ang iba pang paraan para doon ay ang ORB algorithm para sa pagtuklas ng bagay.
Katulad ng pamamaraan ng pagtuklas ng bagay ng SIFT kung saan hinati namin ang programa sa dalawang bahagi, pareho ang susundan dito.
Una, tinukoy namin ang pagpapaandar na ORB_detector na tumatagal ng dalawang mga input ng isa ay ang live na imahe ng stream na nagmumula sa webcam at iba pa ay ang template ng imahe batay sa kung saan kami ay tumugma sa aming imahe. Pagkatapos ay i-grayscale namin ang aming imahe ng webcam at pagkatapos ay isimulan ang aming detektor ng ORB, at itatakda namin ito dito sa 1000 key point at scaling parameter na 1.2. madali mong mapaglaro ang mga parameter na ito, pagkatapos ay tuklasin ang mga keypoint (kp) at mga tagapaglaraw (des) para sa parehong mga imahe at ang pangalawang parameter na tinutukoy namin sa pag- andar ngANDANDUpian ay walang, hinihiling nito ang paggamit ng mask ng imahe o hindi at tinatanggihan namin ito dito.
Pagkatapos lumipat sa detektor dati ay gumagamit kami ng FLANN based matcher, ngunit dito gagamitin namin ang BFMatcher at sa loob ng BFMatcher tinukoy namin ang dalawang mga parameter ng isa ay NORM_HAMMING at iba pa ay ang crossCheck na ang halaga ay TUNAY.
Pagkatapos ay kalkulahin ang mga tugma sa pagitan ng dalawang imaheng iyon gamit ang mga naglalarawan na tinukoy sa itaas, na sa lahat ay ibinabalik ang bilang ng mga tugma dahil ang mga tugma na ito ay hindi approximation at samakatuwid ay hindi na kailangang gawin ang pagsubok sa ratio ni Lowe, sa halip ay inayos namin ang mga tugma batay sa distansya, hindi bababa sa distansya higit na mas mahusay ang tugma (narito ang distansya ay nangangahulugang distansya sa pagitan ng mga puntos), at sa dulo ay ibinabalik namin ang bilang ng mga tugma gamit ang haba ng pag-andar.
At sa pangunahing pag-andar itinatakda namin ang threshold sa isang mas mataas na halaga, dahil ang orb detector ay lumilikha ng maraming ingay.
Ngayon tingnan natin ang code para sa pagtuklas ng batay sa ORB
i-import ang cv2 import numpy bilang np def ORB_detector (new_image, image_template): # Function na ihinahambing ang input na imahe sa template # Pagkatapos ay ibabalik ang bilang ng mga tugma sa ORB sa pagitan nila ng image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Lumikha ng detektor ng ORB 1000 mga keypoint na may scaling pyramid factor na 1.2 orb = cv2.ORB_create (1000, 1.2) # Detect keypoints ng orihinal na imahe (kp1, des1) = orb.detectAndCompute (image1, Wala) # Detect keypoints of rotated image (kp2, des2) = orb.detectAndCompute (image_template, Wala) # Lumikha ng matcher # Tandaan hindi na namin ginagamit ang Flannbased na tumutugma bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Do match match = bf.match (des1, des2) # Pagbukud-bukurin ang mga tugma batay sa distansya. Ang pinakadulo na distansya # ay mas mahusay na mga tugma = pinagsunod-sunod (mga tugma, key = lambda val: val.distansya) bumalik len (mga tugma) cap = cv2.VideoCapture (0) # I-load ang aming template ng imahe, ito ang aming sanggunian na imahe_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('mga imahe / kitkat.jpg', 0) habang Totoo: # Kumuha ng mga imahe ng webcam ret, frame = cap.read () # Kumuha ng taas at lapad ng taas ng frame ng webcam , width = frame.shape # Tukuyin ang Mga Dimensyon ng Box ng ROI (Tandaan na ang ilan sa mga bagay na ito ay dapat nasa labas ng loop) top_left_x = int (lapad / 3) top_left_y = int ((taas / 2) + (taas / 4)) sa ibaba_ kanan_x = int ((lapad / 3) * 2) sa ibaba_ kanan_y = int ((taas / 2) - (taas / 4)) # Gumuhit ng parihabang window para sa aming rehiyon ng interes cv2.rectangle (frame, (top_left_x, top_left_y), (ilalim_ kanan_x, ilalim_ kanan_y), 255, 3) # I-crop ang window ng pagmamasid na tinukoy namin sa itaas na tinadtad = frame # Flip orientation na pahalang na frame = cv2.flip (frame, 1) # Kumuha ng bilang ng mga tugma sa ORB = ORB_detector (na-crop, image_template) # Ipakita ang string ng katayuan na nagpapakita ng kasalukuyang hindi. ng mga tugma output_string = "Mga Tugma =" + str (tugma) cv2.putTxt (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Ang aming threshold upang ipahiwatig ang deteciton ng bagay # Para sa mga bagong imahe o kundisyon ng lightening maaaring kailanganin mong mag-eksperimento nang kaunti # Tandaan: Ang detektor ng ORB upang makuha ang nangungunang 1000 na mga tugma, ang 350 ay mahalagang isang min 35% na threshold ng pagtutugma = 250 # Kung ang mga tugma ay lumampas sa aming threshold pagkatapos object ay napansin kung tugma> threshold: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putTxt (frame, 'Object Found', (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('Detector ng Bagay na gumagamit ng ORB', frame) kung cv2.waitKey (1) == 13: # 13 ay ang Enter Key break cap.release () cv2.destroyAllWindows ()
Histogram ng oriented Gradients (HOG's)
Ngayon pag-usapan natin ang tungkol sa isang iba't ibang tagapaglarawan na Histogram of Oriented Gradients (HOG's).
Ang HOG's ay medyo cool at kapaki-pakinabang na mga tagapaglaraw at malawak at matagumpay itong ginamit para sa pagtuklas ng bagay, tulad ng nakikita dati na mga naglalarawan ng imahe tulad ng SIFT at ORB kung saan kailangan nating kalkulahin ang mga keypoint at pagkatapos ay upang makalkula ang mga tagapaglaraw sa mga keypoint na iyon, ginagawa ng HOG ang proseso na iyon iba iba Ito ay kumakatawan sa mga bagay bilang isang solong tampok vector na taliwas sa isang hanay ng mga tampok vectors kung saan ang bawat kumakatawan sa isang segment ng imahe. Nangangahulugan ito na mayroon kaming solong tampok na vector para sa buong imahe.
Kinakalkula ito ng isang sliding window detector sa isang imahe, kung saan ang isang deskriptor ng HOG ay isang kinalkula para sa bawat posisyon. At pagkatapos ang bawat posisyon ay pinagsama para sa isang solong vector tampok.
Tulad ng SIFT ang sukat ng imahe ay nababagay sa pamamagitan ng pyramiding.
Dati ay gumagamit kami ng mga matcher tulad ng FLANN at BFMatcher, ngunit iba ang ginagawa ng mga HOG sa tulong ng mga klasipikasyon ng SVM (support vector machine), kung saan ang bawat tagapaglarawan ng HOG na na-compute ay pinakain sa isang klasipikasyon ng SVM upang matukoy kung ang bagay ay natagpuan o hindi.
Narito ang link sa isang Mahusay na Papel ni Dalal & Triggs sa paggamit ng HOGs para sa Human Detection:
Histogram ng oriented Gradients (HOG's), Hakbang sa Hakbang:
Ang pag-unawa sa HOG ay maaaring maging kumplikado, ngunit dito lamang tayo makikipag-usap sa teorya ng HOG nang hindi lalalim sa matematika na kaugnay nito.
Kaya't kunin natin ang larawang ito medyo kaunti itong na-pixelate, at sa itaas na sulok ay 8x8 pixel box dito, kaya sa kahon na ito kinukuwenta namin ang gradient vector o mga orientation ng gilid sa bawat pixel. Kaya't nangangahulugan ito sa kahon na ito na kinakalkula namin ang gradient na imahe ng vector ng mga pixel sa loob ng kahon (ang mga ito ay uri ng direksyon o daloy ng lakas ng imahe mismo), at bumubuo ito ng 64 (8 x 8) mga gradient vector na kinakatawan bilang isang histogram. Kaya isipin ang isang histogram na kumakatawan sa bawat gradient vector. Kaya't kung ang lahat ng mga puntos o intensidad ay nagsisinungaling sa isang direksyon, ang histogram para sa direksyong iyon ay sabihin nating 45 degree, ang histogram ay may rurok na 45 degree.
Kaya kung ano ang ginagawa natin ngayon ay pinaghati-hati natin ang bawat cell sa mga anggular bins, kung saan ang bawat basurahan ay tumutugma sa isang gradient na direksyon (hal x, y). Sa papel ng Dalal at Triggs, gumamit sila ng 9 bins0-180 ° (20 ° bawat basurahan). Epektibong binabawasan nito ang 64 na mga vector sa 9 na halaga lamang. Kaya't ang aming nagawa ay binawasan ang laki ngunit itinatago ang lahat ng pangunahing impormasyon na kinakailangan.
Susunod na hakbang sa pagkalkula ng baboy ay ang normalisasyon, ginawang normal namin ang mga gradient upang matiyak na ang invariance sa mga pagbabago sa pag-iilaw ie Brightness at Contrast.
Sa imaheng ito, ipinapakita ang mga halaga ng intensity sa parisukat ayon sa kani-kanilang direksyon at lahat ay may pagkakaiba na 50 sa bawat isa
∆ H = 50, ∆ v = 50; │∆│ = √50 2 +50 = 70.72, 70.72 / 100 = 0.707
Hinahati namin ang mga vector sa gradient magnitude na nakukuha namin sa 0.707 para sa lahat, ito ay normalisasyon.
Katulad nito, kung binago natin ang tindi o binago ang kaibahan nakukuha natin ang mga halagang nasa ibaba.
∆ 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
Ang normalisasyon ay hindi nagaganap sa isang antas ng cell, sa halip ay nagaganap ito sa isang antas ng pag-block, kaya narito ang mga bloke ay karaniwang isang pangkat ng 4 na mga cell, isinasaalang-alang nito ang mga kalapit na bloke upang gawing normal habang isinasaalang-alang ang mas malaking mga segment ng imahe.
Ngayon tingnan natin ang code
import numpy as np import cv2 import matplotlib.pyplot as plt # Load image then grayscale image = cv2.imread ('elephant.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Ipakita ang orihinal na Image cv2.imshow (' Input Image ', imahe) cv2.waitKey (0) #nagtatakda ng mga parameter, laki ng cell at laki ng pag-block # hxw sa mga pixel cell_size = (8, 8) # hxw sa cells block_size = (2, 2) # bilang ng mga orientation bins nbins = 9 # Gamit ang OpenCV's HOG Descriptor # winSize ay ang laki ng imahe na na-crop sa isang maramihang mga laki ng cell hog = cv2.HOGDescriptor (_winSize = (grey.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) # Lumikha ng tumpik na hugis ng array na ginagamit namin upang lumikha ng hog_feature n_cells = (grey.shape // cell_size, grey.shape // cell_size) # Ina- block muna namin ang mga hilera. Naglalaman ang # hog_feats ngayon ng mga gradient amplitude para sa bawat direksyon, # para sa bawat cell ng pangkat nito para sa bawat pangkat. Ang pag-index ay ayon sa mga hilera pagkatapos ng mga haligi. hog_feats = hog.compute (grey).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Lumikha ng aming mga gradient na array na may mga sukat ng nbin upang mag-imbak ng mga gradient orientation gradients = np.zeros ((n_cells, n_cells, nbins)) # Lumikha ng hanay ng mga sukat na cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Pag-normalize ng Block para sa off_y sa saklaw (block_size): para sa off_x sa saklaw (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 # Average gradients gradients / = cell_count # Plot HOGs na gumagamit ng Matplotlib # na anggulo ay 360 / nbins * direksyon color_bins = 5 plt.pcolor (gradients) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('pantay', naaayos = 'kahon') plt.colorbar () plt.show () cv2.destroyAllWindows ()
Ipinapakita ng imahe kung paano kinatawan ang imahe ng pag-input bilang representasyon ng HOG.
Mga classifier ng HAC cascade
Tulad ng naunang tinalakay, maaari kaming kumuha ng mga tampok mula sa isang imahe at gamitin ang mga tampok na iyon upang mauri-uriin o makita ang mga bagay.
Ano ang HAAR Cascade Classifiers?
Isang pamamaraan ng pagtuklas ng bagay na naglalagay ng mga tampok sa Haar sa isang serye ng mga classifier (cascade) upang makilala ang mga bagay sa isang imahe. Sinasanay sila upang makilala ang isang uri ng bagay, gayunpaman, maaari naming magamit ang ilan sa mga ito sa kahanay hal. Pagtuklas ng mga mata at mukha nang magkasama.
Ipinaliwanag ang mga classifier ng HAAR:
Ang HAAR Classifiers ay sinanay gamit ang maraming positibong mga imahe (ie mga imahe na mayroong object na naroroon) at mga
negatibong imahe (ie mga imahe nang wala ang bagay na naroroon).
Kapag mayroon kaming mga imaheng iyon, kumukuha kami ng mga tampok na gumagamit ng mga sliding window ng mga parihabang bloke. Ang mga tampok na ito (mga tampok na HAAR) ay iisa ang pinahahalagahan at kinakalkula sa pamamagitan ng pagbawas sa kabuuan ng mga lakas ng pixel sa ilalim ng mga puting parihaba mula sa mga itim na parihaba.
Gayunpaman, ito ay isang katawa-tawa na bilang ng mga kalkulasyon, kahit na para sa isang batayang window ng 24 x 24 pixel (180,000 mga tampok na nabuo).
Kaya't ang mga mananaliksik ay gumawa ng isang pamamaraan na tinatawag na Integral Images na kinalkula ito ng apat na mga sanggunian sa hanay. Gayunpaman, mayroon pa rin silang 180,000 mga tampok at ang karamihan sa kanila ay nagdagdag ng walang tunay na halaga.
Ginamit ang Boosting upang matukoy ang pinaka-kaalamang mga tampok, kasama ang Freund & Schapire's AdaBoost at natagpuan nito ang pinaka-nagbibigay-kaalamang mga tampok sa imahe. Ang pagpapalakas ay ang proseso kung saan gumagamit kami ng mga mahihinang pag-uuri upang makabuo ng mga malakas na pag-uuri, sa pamamagitan lamang ng pagtatalaga ng mas mabibigat na mga parusa na may timbang sa mga maling pag-uuri. Ang pagbawas ng 180,000 mga tampok sa 6000, na kung saan ay pa rin ng kaunting mga tampok.
Sa 6000 mga tampok na iyon, ang ilan ay magiging mas maraming impormasyon kaysa sa iba. Kaya kung ginamit namin ang pinaka nakakaalam na mga tampok upang suriin muna kung ang rehiyon ay maaaring magkaroon ng mukha (ang mga maling positibo ay hindi magiging malaking pakikitungo). Ang paggawa nito ay tinanggal ang pangangailangan para sa pagkalkula ng lahat ng 6000 mga tampok nang sabay-sabay. Ang konseptong ito ay tinatawag na Cascade of Classifiers - para sa pagtuklas ng mukha, ang pamamaraang Viola Jones ay gumamit ng 38 yugto.
Pagtuklas sa Mukha at Mata
Kaya pagkatapos makakuha ng ilang teoretikal na kaalaman tungkol sa mga casarade ng HAAR ay sa wakas ay ipapatupad natin ito, upang mas malinaw ang mga bagay ay sisirain natin ang mga aralin sa mga bahagi, una naming matutukoy ang harap na mukha pagkatapos na lilipat tayo upang makita ang harapan ng mukha na may mga mata at sa wakas ay gagawin namin ang live na pagtuklas ng mukha at mga mata sa pamamagitan ng webcam.
Kaya't para sa ito ay gagamitin namin ang mga pre-train na classifier na naibigay ng OpenCV bilang mga file na
Maaari kang magkaroon ng pag-access ng mga classifier na ito sa link na ito .
Pagtuklas ng mukha
Subukan natin para sa pagtuklas ng harapan ng mukha, maaari kang magkaroon ng pag-access para sa kaskad ng frontal face detector dito. I-extract lamang ang zip file upang makuha ang xml file.
i-import ang numpy bilang np import cv2 # Itinuturo namin ang pagpapaandar ng CasCadeClassifier ng OpenCV kung saan nakaimbak ang aming # classifier (format ng XML file), tandaan na panatilihin ang code at classifier sa parehong folder na face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load ang aming imahe pagkatapos ay i-convert ito sa grayscale image = cv2.imread ('Trump.jpg') grey = cv2.cvtColor (imahe, cv2.COLOR_BGR2GRAY) # Ibinabalik ng aming classifier ang ROI ng napansin na mukha bilang isang tuple # Iniimbak nito ang kaliwang tuktok coordinate at ang kanang ibaba sa koordinasyon # ibinalik nito ang listahan ng mga listahan, na kung saan ay ang lokasyon ng iba't ibang mga mukha nakita. mukha = face_cascade.detectMultiScale (grey, 1.3, 5) # Kapag walang nakitang mga mukha, nagbabalik ang face_classifier at walang laman na tuple kung ang mga mukha ay (): i- print ("Walang nahanap na mga mukha") # Inuulit namin ang aming mga mukha na nakaayos at gumuhit ng isang rektanggulo # sa bawat mukha sa mga mukha para sa (x, y, w, h) sa mga mukha: cv2.rectangle (imahe, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('Detection ng Mukha', imahe) cv2.waitKey (0) cv2.destroyAllWindows ()
Pagsamahin natin ngayon ang mukha at pagtuklas ng mata nang magkasama, maaari kang magkaroon ng pag-access para sa kaskad ng detektor ng mata sa parehong file ng zip.
i-import ang numpy bilang np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') grey = cv2.cvtColor cv2.COLOR_BGR2GRAY) mga mukha = face_classifier.detectMultiScale (grey, 1.3, 5) # Kapag walang nakitang mga mukha, babalik ang face_classifier at walang laman na tuple kung ang mga mukha ay (): i- print ("Walang Nahanap na Mukha") para sa (x, y, w, h) sa mga mukha: 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) para sa (ex, ey, ew, eh) sa mga mata: 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)
Kaya't ang code na ito ay kapareho ng code para sa pagtuklas ng mukha, ngunit dito nagdagdag kami ng mga cascade ng mata at pamamaraan upang makita ang mga ito, tulad ng nakikita mong pinili namin ang Gray na naka-scale na bersyon ng mukha bilang parameter para sa detectMultiScale para sa ang mga mata, na nagdadala sa amin sa pagbawas ng pagkalkula dahil matutukoy lamang natin ang mga mata sa lugar lamang na iyon.
Live na Pagtuklas ng Mukha at Mata
Kaya hanggang ngayon nagawa na namin ang pagtuklas ng mukha at mata, ngayon ay ipatupad natin ang pareho sa live na stream ng video mula sa webcam. Sa ito ay gagawin namin ang parehong pagtuklas ng mukha at mga mata ngunit sa oras na ito ay gagawin namin ito para sa live stream form na webcam. Sa karamihan ng application ay mahahanap mo ang iyong mukha na naka-highlight sa isang kahon sa paligid nito, ngunit dito nagawa namin ang isang bagay na naiiba na mahahanap mo ang iyong mukha na pinutol at ang mga mata ay makikilala doon lamang.
Kaya't dito ay ina-import namin ang parehong mukha at eye classifier, at tinukoy ang isang function para sa paggawa ng lahat ng pagproseso para sa pagtuklas ng mukha at mata. At pagkatapos nito sinimulan ang stream ng webcam at tinawag ang pagpapaandar ng detektor ng mukha para sa pagkuha ng mukha at mga mata na nakita. Ang parameter na tinutukoy namin sa loob ng pag-andar ng detektor ng mukha ay ang patuloy na mga imahe mula sa live na web cam stream
i-import ang cv2 import numpy bilang np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, size = 0.5): # I-convert ang imahe sa grayscalev = cv. (img, cv2.COLOR_BGR2GRAY) mga mukha = face_classifier.detectMultiScale (grey, 1.3, 5) kung ang mga mukha ay (): bumalik img para sa (x, y, w, h) sa mga mukha: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2.rectangle (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = grey roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) para sa (hal, ey, ew, eh) sa mga mata: cv2.rectangle (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) ibalik ang roi_color cap = cv2.VideoCapture (0) habang Totoo: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) kung cv2.waitKey (1) == 13: # 13 ang Enter Key break cap.release () cv2.destroyAllWindows ()
Mga Classifier ng Cascade ng Pag-tune
Ang mga parameter na tinukoy sa loob ng detectMultiScale maliban sa input na imahe ay may sumusunod na kahalagahan
amingClassifier. detectMultiScale (input imahe, Scale Factor, Min Neighbours)
- Tinutukoy ng Scale Factor kung gaano namin binabawasan ang laki ng imahe sa bawat oras na sukatin. Hal sa pagtuklas ng mukha na karaniwang ginagamit namin 1.3. Nangangahulugan ito na binabawasan namin ang imahe ng 30% sa tuwing mai-scale ito. Ang mas maliit na mga halaga, tulad ng 1.05 ay mas magtatagal upang makalkula, ngunit tataas ang rate ng pagtuklas.
- Tinutukoy ng mga Min Neighbours ang bilang ng mga kapitbahay na dapat mayroon ang bawat potensyal na window upang maisaalang-alang ito bilang isang positibong pagtuklas. Karaniwan na itinakda sa pagitan ng 3-6. Gumaganap ito bilang setting ng pagiging sensitibo, ang mga mababang halaga ay nakakakita kung minsan ng mga maramihang mukha sa isang solong mukha. Ang mga mataas na halaga ay titiyakin ang mas kaunting maling mga positibo, ngunit maaari kang makaligtaan ang ilang mga mukha.
Pagtuklas ng Kotse at Pedestrian sa mga video
Ngayon ay makakakita kami ng pedestrian at mga kotse sa mga video na gumagamit ng mga HAAR cascade, ngunit kung sakali walang video na naglo-load at nag-iipon ng code nang walang error kailangan mong sundin ang mga sumusunod na hakbang:
Kung walang naglo-load na video pagkatapos ng pagpapatakbo ng code, maaaring kailangan mong kopyahin ang aming opencv_ffmpeg.dl mula sa : opencv \ pinagkukunan \ 3rdparty \ ffmpeg upang i-paste ito kung saan naka-install ang iyong sawa eg C: \ Anaconda2
Kapag nakopya ito kailangan mong palitan ang pangalan ng file alinsunod sa bersyon ng OpenCV na iyong ginagamit.eg kung gumagamit ka ng OpenCV 2.4.13 pagkatapos ay palitan ang pangalan ng file bilang: opencv_ffmpeg2413_64.dll o opencv_ffmpeg2413.dll (kung ikaw ay gamit ang isang X86 machine) opencv_ffmpeg310_64.dll o opencv_ffmpeg310.dll (kung gumagamit ka ng X86 machine)
Upang malaman kung saan naka-install ang python.exe, patakbuhin lamang ang dalawang linya ng code, mai-print nito ang lokasyon kung saan naka-install ang python.
i-import ang sys print (sys.executable)
Ngayon kung nagawa mong matagumpay ang mga hakbang na ito, lumipat tayo sa code para sa pagtuklas ng pedestrian, Maaari kang magkaroon ng kaskad para sa pagtuklas ng pedestrian at mula sa zip file na nakakabit dito.
i-import ang cv2 import numpy bilang np # Lumikha ng aming body classifier body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Simulan ang pagkuha ng video para sa file ng video, narito ginagamit namin ang file ng video kung saan ang mga pedestrian ay napansin cap = cv2.VideoCapture ('walking.avi') # Loop sabay video ay matagumpay na na-load habang cap.isOpened (): # Pagbasa ng bawat frame ng video ret, frame = cap.read () # dito namin binabago ang laki ng frame, sa kalahati ng laki nito, ginagawa namin upang mapabilis ang pag-uuri # dahil ang mas malalaking mga imahe ay may mas maraming mga bintana upang dumulas, kaya sa pangkalahatan ay binabawasan natin ang resolusyon # ng video sa kalahati iyon ang ipahiwatig ng 0.5, at gumagamit din kami ng mas mabilis na paraan ng interpolation na #interlinear frame = cv2.resize (frame, Wala, fx = 0.5, fy = 0.5, interpolation = cv2.INTER_LINEAR) grey = cv2. cvtColor (frame, cv2.COLOR_BGR2GRAY) # Pass frame sa aming mga body classifier na katawan = body_classifier.detectMultiScale (grey, 1.2, 3) # I-extract ang mga kahon na may hangganan para sa anumang mga katawang kinilala para sa (x, y, w, h) sa mga katawan: cv2. rektanggulo (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Pedestrian', frame) kung cv2.waitKey (1) == 13: # 13 ang Enter Key break cap.release () cv2.destroyAllWindows ()
Matapos matagumpay na tuklasin ang taong naglalakad sa video, lumipat tayo sa code para sa Pagtuklas ng Kotse, Maaari kang magkaroon ng kaskad para sa pagtuklas ng pedestrian mula dito.
import cv2 import time import numpy as np # Lumikha ng aming body classifier car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Magsimula ng pagkuha ng video para sa cap ng file ng video = cv2.VideoCapture ('cars.avi') # Loop sabay-sabay na matagumpay ang video na-load habang cap.isOpened (): time.s Sleep ( .05) # Basahin ang unang frame ret, frame = cap.read () grey = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Pass frame sa aming mga car classifier na kotse = car_classifier.detectMultiScale (grey, 1.4, 2) # Exact bounding box para sa anumang mga katawan na nakilala para sa (x, y, w, h) sa mga kotse: cv2.rectangle (frame, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Mga Kotse', frame) kung cv2.waitKey (1) == 13: # 13 ang Enter Key break cap.release () cv2.destroyAllWindows ()
Napansin mo na nagdagdag kami ng oras. Tulog (.05) , isang pagkaantala lamang sa rate ng frame upang makumpirma mo na ang lahat ng mga kotse ay nakilala nang wasto, o madali mong matanggal ito sa pamamagitan lamang ng pagdaragdag ng isang label ng komento dito.
Ang artikulong ito ay tinukoy mula sa Master Computer Vision ™ OpenCV4 sa Python na may kurso na Deep Learning sa Udemy, nilikha ni Rajeev Ratan, i-subscribe ito upang malaman ang higit pa tungkol sa Computer Vision at Python.