- SIFT का उपयोग करके ऑब्जेक्ट का पता लगाना
- ओआरबी का उपयोग करके वस्तु का पता लगाना
- ओरिएंटेड ग्रेजुएट्स (HOG's) का हिस्टोग्राम
- हिस्टोग्राम ऑफ़ ओरिएंटेड ग्रेजुएट्स (HOG's), स्टेप बाय स्टेप:
- HAAR कैस्केड क्लासिफायर
- चेहरा और आँख का पता लगाना
- लाइव फेस एंड आई डिटेक्शन
- ट्यूनिंग कैस्केड क्लासिफायर
- वीडियो में कार और पैदल यात्री का पता लगाना
हमने पायथन ओपनसीवी को खिड़कियों पर स्थापित करने के साथ शुरू किया और अब तक पायथन का उपयोग करके कुछ बुनियादी छवि प्रसंस्करण, छवि विभाजन और ऑब्जेक्ट का पता लगाया है, जो नीचे दिए गए ट्यूटोरियल में शामिल हैं:
- पायथन ओपनसीवी के साथ शुरुआत करना: इंस्टॉलेशन और बेसिक इमेज प्रोसेसिंग
- पायथन ओपनसीवी में छवि जोड़तोड़ (भाग 1)
- OpenCV में छवि जोड़तोड़ (भाग -2)
- OpenCV का उपयोग करके छवि विभाजन - एक छवि के विशिष्ट क्षेत्रों को निकालना
हमने ऑब्जेक्ट डिटेक्शन के लिए विभिन्न तरीकों और एल्गोरिदम के बारे में भी सीखा जहां विभिन्न एल्गोरिदम का उपयोग करके प्रत्येक ऑब्जेक्ट के लिए कुछ महत्वपूर्ण बिंदुओं की पहचान की गई थी। इस ट्यूटोरियल में हम वास्तविक जीवन की वस्तुओं का पता लगाने के लिए उन एल्गोरिदम का उपयोग करने जा रहे हैं, यहाँ हम पता लगाने के लिए SIFT और ORB का उपयोग करेंगे ।
SIFT का उपयोग करके ऑब्जेक्ट का पता लगाना
यहाँ ऑब्जेक्ट डिटेक्शन लाइव वेबकैम स्ट्रीम का उपयोग करके किया जाएगा, इसलिए यदि यह ऑब्जेक्ट को पहचानता है तो यह पाया गया ओज़ेट का उल्लेख करेगा। कोड में मुख्य भाग को फ़ंक्शन द्वारा खेला जाता है जिसे SIFT डिटेक्टर कहा जाता है, अधिकांश प्रसंस्करण इस फ़ंक्शन द्वारा किया जाता है।
और कोड के दूसरे भाग में, हम वेब कैमरा स्ट्रीम खोलने के साथ शुरू कर रहे हैं, फिर इमेज टेम्प्लेट को लोड करते हैं, अर्थात संदर्भ छवि, यह प्रोग्राम वास्तव में वेब कैमरा स्ट्रीम के माध्यम से देख रहा है।
अगला, हम लूप करते समय अनंत की मदद से वेब कैमरा स्ट्रीम से छवियों को लगातार कैप्चर कर रहे हैं, और फिर वेब कैमरा फ्रेम की संबंधित ऊंचाई और चौड़ाई को कैप्चर कर रहे हैं, और उसके बाद रुचि के क्षेत्र (आरओआई) बॉक्स के मापदंडों को परिभाषित करते हैं जिसमें वेब कैमरा फ्रेम की संबंधित ऊँचाई और चौड़ाई लेने से हमारी वस्तु फिट हो सकती है। और फिर हम उन आरओआई मापदंडों से आयत खींचते हैं जिन्हें हमने ऊपर परिभाषित किया था। फिर अंत में आयत को काटें और इसे कोड के SWIFT डिटेक्टर भाग में खिलाएं।
अब SIFT डिटेक्टर में मूल रूप से दो इनपुट होते हैं, एक है फसली छवि और दूसरा वह इमेज टेम्प्लेट है जिसे हमने पहले परिभाषित किया था और फिर यह हमें कुछ मैच देता है, इसलिए मैच मूल रूप से ऑब्जेक्ट्स या कीपॉइंट्स की संख्या है जो क्रॉप्ड इमेज के समान हैं। और लक्ष्य छवि। तब हम मैचों के लिए एक थ्रेशोल्ड मान को परिभाषित करते हैं, यदि मैचों का मूल्य थ्रेशोल्ड से अधिक है, तो हम अपनी स्क्रीन पर पाई गई छवि को आरओआई आयत के हरे रंग के साथ डालते हैं।
अब कोड के मुख्य भाग पर वापस जाते हैं, फ़ंक्शन जिसे SIFT डिटेक्टर कहा जाता है, यह इनपुट को दो छवियों के रूप में लेता है एक वह छवि है जहां यह ऑब्जेक्ट की तलाश में है और अन्य वह ऑब्जेक्ट है जिसे हम मिलान करने का प्रयास कर रहे हैं को (छवि टेम्पलेट) फिर पहली छवि को ग्रे स्केल करें और छवि टेम्पलेट को दूसरी छवि के रूप में परिभाषित करें। फिर हम एक SIFT डिटेक्टर ऑब्जेक्ट बनाते हैं और OpenCV SIFT का पता लगाते हैं और फंक्शन की गणना करते हैं, ताकि की-पॉइंट का पता लगा सकें और डिस्क्रिप्टर की गणना कर सकें, डिस्क्रिप्टर मूल रूप से वैक्टर होते हैं जो की-पॉइंट्स की जानकारी स्टोर करते हैं, और वास्तव में महत्वपूर्ण यह है कि हम मेल खाते हैं। छवियों के वर्णनकर्ताओं के बीच।
और फिर FLANN आधारित मिलानकर्ता को परिभाषित करें, हम इसके पीछे मिलान के गणितीय सिद्धांत में नहीं जा रहे हैं, लेकिन आप इसके बारे में Google को आसानी से बता सकते हैं। सबसे पहले, इंडेक्स kdtree को शून्य में परिभाषित करें और फिर हम इंडेक्स और खोज मापदंडों को डिक्शनरी फॉर्मेट में सेट करते हैं, हम सिर्फ उस एल्गोरिथ्म को परिभाषित करते हैं जिसका हम उपयोग करने जा रहे हैं जो केडीटीआरई है, और जितने पेड़ हम उपयोग करने वाले हैं, उतने ही अधिक पेड़ हम अधिक जटिल का उपयोग करते हैं और यह धीमा हो जाता है। और खोज पैरामीटर में चेक की संख्या को परिभाषित करते हैं, जो मूल रूप से पूर्ण होने वाली मैचों की संख्या है।
और फिर हम पहले से परिभाषित पैरामीटर को लोड करके अपने FLANN आधारित मिलानकर्ता ऑब्जेक्ट को बनाते हैं जो कि इंडेक्स पैरामीटर और खोज पैरामीटर हैं और इसके आधार पर हमारे FLANN आधारित मिलानकर्ता बनाते हैं, जो KNN के निकटतम पड़ोसी, जहां KNN के-मैचर है, मूल रूप से यह एक तरीका है हम निकटतम मैचर्स और डिस्क्रिप्टर की तलाश करते हैं और हम आरम्भिक स्थिरांक के साथ मिलान करते हैं। अब यह FLANN आधारित मिलानकर्ता हमें प्राप्त होने वाले मैचों की संख्या लौटाता है।
FLANN आधारित मिलान सिर्फ एक सन्निकटन है, इसलिए FLANN आधारित मिलानकर्ता की सटीकता को बढ़ाने के लिए हम एक लोव के अनुपात का परीक्षण करते हैं और यह क्या करता है यह knn flann आधारित मिलानकर्ता के मैचों के लिए दिखता है और कुछ मैट्रिक मापदंडों को परिभाषित करता है जो यहां दूरी है, जिसके लिए दूरी एक संख्यात्मक कार्य है, और एक बार जब यह मानदंडों को पूरा करता है तो अच्छे मैचों के लिए मैचों को जोड़ता है और पाए गए अच्छे मैचों को वापस करता है, और इसलिए लाइव वीडियो स्ट्रीम स्क्रीन के कोने पर पाए जाने वाले मैचों की संख्या बताता है।
अब उपरोक्त विवरण के लिए कोड को देखें:
आयात CV2 एनपी के रूप में आयात numpy डीईएफ़ sift_detector (new_image, image_template): उस टेम्पलेट के लिए इनपुट छवि तुलना # समारोह # यह तो रिटर्न झारना की संख्या उन दोनों के बीच मेल खाता Image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) Image2 = image_template # बनाएं SIFT डिटेक्टर ऑब्जेक्ट #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # SIFT keypoint_1, डिस्क्रिप्टर = = sift.detectAndCompute (image1, कोई नहीं) keypoint_2, descriptors_2 = = sift.d = का उपयोग करके कीप और डिस्क्रिप्टर प्राप्त करें। कोई नहीं) # के लिए मानकों को परिभाषित करें हमारे Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (एल्गोरिथ्म = FLANN_INDEX_KDTREE, पेड़ = 3) search_params = dict (चेक = 100) # Flann Matcher वस्तु बनाएं फ्लान = cv2.FlannBasedMatcher (index_params, search_params) # का उपयोग कर कश्मीर निकटतम पड़ोसी विधि मैचों प्राप्त # परिणाम 'matchs के' समान मैचों की संख्या दोनों छवियों में पाया जाता है से मेल खाता है = flann.knnMatch (डिस्क्रिप्टर_1, डिस्क्रिप्टर_2, के = 2) # लोवेस के अनुपात परीक्षण का उपयोग करके अच्छे मेलों को स्टोर करें। मेलों के लिए n, मैचों में m: n, यदि m.distance <0.7 * n.dance: good_matches.append (m) रिटर्न लेन ( ) good_matches) टोपी = cv2.VideoCapture (0) # हमारी छवि टेम्पलेट लोड है, यह हमारी संदर्भ छवि है image_template = cv2.imread ('phone.jpg', 0) : जबकि यह सच है # प्राप्त वेब कैमरा छवियों रिट, फ़्रेम = cap.read () # वेबकैम की ऊँचाई और चौड़ाई प्राप्त करें फ़्रेम फ़्रेम ऊँचाई, चौड़ाई = फ़्रेम। # परिभाषित ROI बॉक्स आयाम top_left_x = int (चौड़ाई / 3) top_left_y = int ((ऊँचाई / 2) + (ऊँचाई / ऊँचाई) 4)) bottom_right_x = int ((चौड़ाई / 3) * 2) bottom_right_y = int ((ऊंचाई / 2) - (ऊँचाई / 4)) # हमारी रुचि के क्षेत्र के लिए आयताकार विंडो बनाएं cv2.rectangle (फ्रेम (top_left_x, top_left_yft)), (bottom_right_x, bottom_right_y), 255, 3) # अवलोकन की फसल खिड़की जिसे हमने क्रॉप्ड = फ्रेम के ऊपर परिभाषित किया है = फ्लिप फ्रेम ओरिएंटेशन क्षैतिज रूप से फ्रेम = cv2.flip (फ्रेम, 1) # सिफ्ट मैचों के मैचों की संख्या प्राप्त करें = sift_detector (क्रॉप्ड) image_template) # वर्तमान स्थिति दिखाने वाली स्ट्रिंग प्रदर्शित करें। मैचों के cv2.putText (फ्रेम, str (माचिस), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # हमारी थ्रेसहोल्ड डिटेकिटोन को इंगित करने के लिए # हम 10 का उपयोग करते हैं क्योंकि SIFT डिटेक्टर से छोटे झूठे पॉज़िटव लौटते हैं। थ्रेशोल्ड = 10 # यदि हमारी थ्रेशोल्ड से अधिक है तो ऑब्जेक्ट का पता लगाया गया है यदि मैच> थ्रेशोल्ड: cv2.rectangle (फ्रेम, (top_left_x, top_left_y), (bottom_right_x, bottom-ok_y), (0,255,0), 3) cv2.putText (फ्रेम ) , 'ऑब्जेक्ट फाउंड', (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('ऑब्जेक्ट डिटेक्टर का उपयोग SIFT', फ्रेम: यदि cv2.waitKey (1) == 13: 13: # 13 Enter कुंजी ब्रेक cap.release () cv2.destroyAllWindows () है
ओआरबी का उपयोग करके वस्तु का पता लगाना
SIFT का उपयोग करते हुए ऑब्जेक्ट का पता लगाना बहुत अधिक शांत और सटीक है, क्योंकि यह की-पॉइंट्स के आधार पर बहुत अधिक सटीक संख्या में मैच बनाता है, हालांकि इसका पेटेंट कराया गया है और यह वाणिज्यिक अनुप्रयोगों के लिए इसका उपयोग करने के लिए कठिन बनाता है, इसके लिए दूसरा तरीका ORB एल्गोरिथ्म है। वस्तु का पता लगाने के लिए।
SIFT द्वारा ऑब्जेक्ट डिटेक्शन के तरीके के समान है जिसमें हमने प्रोग्राम को दो भागों में विभाजित किया है, यहाँ भी इसका अनुसरण किया जाएगा।
सबसे पहले, हम फ़ंक्शन को परिभाषित करते हैं ORB_detector जो दो इनपुट लेता है एक है वेबकैम से आने वाली लाइव स्ट्रीम छवि और दूसरा वह छवि टेम्पलेट है जिसके आधार पर हम अपनी छवि से मिलान करने जा रहे हैं। फिर हम अपनी वेब कैमरा छवि को स्केल करते हैं और फिर अपने ORB डिटेक्टर को इनिशियलाइज़ करते हैं, और हम इसे 1000 प्रमुख बिंदुओं पर सेट कर रहे हैं और 1.2 का स्केलिंग पैरामीटर। आप आसानी से इन मापदंडों के साथ खेल सकते हैं, फिर दोनों छवियों के लिए कीपॉइंट्स (केपी) और डिस्क्रिप्टर ( डीईएस ) का पता लगा सकते हैं और दूसरा पैरामीटर जो हम डिटेन्डकंप्यूट फ़ंक्शन में परिभाषित कर रहे हैं वह कोई भी है, यह इमेज मास्क के उपयोग के लिए पूछ रहा है या नहीं। हम इसे यहां नकार रहे हैं।
इसके बाद डिटेक्टर की ओर रुख करें, पहले हम FLANN आधारित मिलानकर्ता का उपयोग कर रहे हैं, लेकिन यहाँ हम BFMatcher का उपयोग करेंगे और BFMatcher के अंदर हम दो मापदंडों को परिभाषित करेंगे, एक है NORM_HAMMING और दूसरा है क्रॉसचेक जिसका मान TRUE है।
फिर ऊपर परिभाषित किए गए डिस्क्रिप्टर का उपयोग करके उन दो छवियों के बीच के मैचों की गणना करें, जो सभी मैचों की संख्या में वापसी करते हैं क्योंकि ये मैच अनुमानित नहीं हैं और इसलिए लोव के अनुपात परीक्षण करने की आवश्यकता नहीं है, इसके बजाय हम दूरी के आधार पर मैचों को सॉर्ट करते हैं, कम से कम दूरी अधिक मैच बेहतर है (यहां अंकों के बीच दूरी का मतलब है), और अंत में हम लंबाई फ़ंक्शन के साथ मैचों की संख्या वापस करते हैं।
और मुख्य फ़ंक्शन में हमने थ्रेशोल्ड को बहुत अधिक मूल्य पर सेट किया है, क्योंकि ऑर्ब डिटेक्टर बहुत अधिक शोर उत्पन्न करता है।
अब ORB आधारित पहचान के लिए कोड को देखते हैं
आयात cv2 आयात np डीईपी ORB_detector (new_image, image_template) के रूप में सुन्न: # फंक्शन जो इनपुट छवि की तुलना टेम्पलेट से करता है # इसके बाद उन दोनों के बीच ORB मैचों की संख्या छवि 1 = cv2.vtColor (new_image, cv2.COLOR_BGR2GRAY) # फ़ंक्शन डिटेक्टर बनाता है १००० orb = cv2.ORB_create (१०००, १२०) # स्केलिंग पिरामिड मूल छवि (kp1, des1) = orb.detectAndComuteute (image1, कोई नहीं) का पता लगाने के लिए १०० की कीप्स, रोटेटेड इमेज (kp2, des2) के # कुंजी कीनोट्स का पता लगाएं। = orb.detectAndCompute (image_template, कोई नहीं) # माचिस बनाएँ # ध्यान दें कि अब हम Flannbased मिलान bf = cv2.BFMatcher (cv2.NORM_HINGING, crossCheck = True) का उपयोग नहीं कर रहे हैं # मैचिंग मैच करें = bf.match (des1, des2) # दूरी के आधार पर मैचों को क्रमबद्ध करें। कम से कम दूरी # बेहतर मिलान = क्रमबद्ध (मिलान, कुंजी = लंबो द वेल: वैल। डस्टेंस) रिटर्न लेन (मैच) कैप = cv2.VideoCapture (0) # हमारी छवि टेम्पलेट लोड करें, यह हमारी संदर्भ छवि_template = cv2.imread (है) 'phone.jpg', 0) # image_template = cv2.imread ('छवियाँ / kitkat.jpg', 0) जबकि True: # वेब कैमरा छवियां प्राप्त करें , फ़्रेम = cap.read () # वेब कैमरा फ़्रेम ऊँचाई की ऊंचाई और चौड़ाई प्राप्त करें , चौड़ाई = फ्रेम.शैप # आरओआई बॉक्स को परिभाषित करें आयाम (इनमें से कुछ चीजों को लूप के बाहर होना चाहिए) top_left_x = int (चौड़ाई / 3) top_left_y = int ((ऊंचाई / 2) + (ऊंचाई / 4)) bottom_right_x = int ((चौड़ाई / 3) * 2) bottom_right_y = int ((ऊंचाई / 2) - (ऊंचाई / 4) # # हमारे लिए आयताकार खिड़की ड्रा करें रुचि का क्षेत्र cv2.rectangle (फ्रेम, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), 255, 3) # अवलोकन की क्रॉप विंडो जिसे हमने क्रोइस = फ्रेम के ऊपर परिभाषित किया है # Flip फ्रेम ओरिएंटेशन क्षैतिज रूप से फ्रेम = cv2.flip (फ्रेम, 1)) # ORB_detector (ORB_detector (क्रॉप्ड, इमेज_टमप्लेट) ) के # प्राप्त करने की संख्या प्राप्त करें। # वर्तमान स्थिति दिखा रहा है। of output output_string = "माचिस =" + str (माचिस) cv2.putText (फ्रेम, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # ऑब्जेक्ट डिटेकिटोन को इंगित करने के लिए हमारी सीमा # नई छवियों या हल्की स्थितियों के लिए आपको थोड़ा प्रयोग करने की आवश्यकता हो सकती है # नोट: शीर्ष 1000 मैच प्राप्त करने के लिए ओआरबी डिटेक्टर, 350 अनिवार्य रूप से एक मिनट 35% मैच थ्रेशोल्ड = 250 # यदि मैच हमारे से अधिक हो थ्रेशोल्ड तब ऑब्जेक्ट का पता लगाया गया है यदि मैच> थ्रेशोल्ड: cv2.rectangle (फ्रेम, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,25,25,0), 3) cv2.putText (फ्रेम, 'ऑब्जेक्ट फाउंड', (50 पाया), 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('ऑब्जेक्ट डिटेक्टर का उपयोग ORB', फ्रेम) यदि cv2.wawKey (1) == 13: # 13 एंटर कुंजी ब्रेक कैप है।.release () cv2.destroyAllWindows ()
ओरिएंटेड ग्रेजुएट्स (HOG's) का हिस्टोग्राम
अब एक अलग डिस्क्रिप्टर के बारे में बात करते हैं जो हिस्टोग्राम ऑफ़ ओरिएंटेड ग्रैडिएंट्स (HOG's) है।
HOG के बहुत अधिक शांत और उपयोगी डिस्क्रिप्टर हैं और वे व्यापक रूप से और सफलतापूर्वक ऑब्जेक्ट डिटेक्शन के लिए उपयोग किए जाते हैं, जैसा कि पहले देखा गया था कि SIFT और ORB जैसे छवि डिस्क्रिप्टर जहां हमें की-पॉइंट की गणना करनी होती है और फिर उन की-पॉइंट से बाहर के डिस्क्रिप्टर की गणना करनी होती है, HOG की प्रक्रिया अलग तरह से। यह एक एकल फीचर वेक्टर के रूप में वस्तुओं का प्रतिनिधित्व करता है, जो फीचर वैक्टर के एक सेट के विपरीत है जहां प्रत्येक छवि के एक खंड का प्रतिनिधित्व करता है। इसका मतलब है कि हमारे पास पूरी छवि के लिए एकल वेक्टर सुविधा है ।
यह एक छवि पर एक स्लाइडिंग विंडो डिटेक्टर द्वारा गणना की जाती है, जहां एक एचओजी विवरणक प्रत्येक स्थिति के लिए गणना की जाती है। और फिर प्रत्येक स्थिति एकल फीचर वेक्टर के लिए संयुक्त है।
SIFT की तरह छवि का पैमाना पिरामिडिंग द्वारा समायोजित किया गया है।
पहले हमने FLANN और BFMatcher जैसे मैचर्स का इस्तेमाल किया है, लेकिन HOGs इसे SVM (सपोर्ट वेक्टर मशीन) क्लासिफायर की मदद से अलग-अलग तरीके से करते हैं, जहाँ पर गणना की गई प्रत्येक HOG डिस्क्रिप्टर को SVM क्लासिफायर में फीड किया जाता है ताकि यह पता लगाया जा सके कि ऑब्जेक्ट पाया गया था या नहीं।
मानव विवरण के लिए HOG का उपयोग करने पर दलाल और ट्रिग्स द्वारा एक महान पत्र का लिंक यहां दिया गया है:
हिस्टोग्राम ऑफ़ ओरिएंटेड ग्रेजुएट्स (HOG's), स्टेप बाय स्टेप:
HOG को समझना काफी जटिल हो सकता है, लेकिन यहाँ हम केवल HOG के सिद्धांत से निपटने के लिए जा रहे हैं, इससे संबंधित गणित में गहराई तक नहीं जा सकते हैं।
तो चलिए इस तस्वीर को थोड़ा सा पिक्सेलेट किया गया है, और ऊपरी कोने पर यहाँ 8x8 पिक्सेल बॉक्स है, इसलिए इस बॉक्स में हम प्रत्येक पिक्सेल पर ग्रेडिएंट वेक्टर या एज ओरिएंटेशन की गणना करते हैं। तो इसका मतलब है कि इस बॉक्स में हम बॉक्स के अंदर पिक्सल्स के इमेज ग्रेडिएंट वेक्टर की गणना करते हैं (वे स्वयं इमेज की तीव्रता की दिशा या प्रवाह की तरह हैं), और यह 64 (8 x 8) ग्रेडिएंट वैक्टर उत्पन्न करता है, जिन्हें तब हिस्टोग्राम के रूप में दर्शाया जाता है। । तो एक हिस्टोग्राम की कल्पना करें जो प्रत्येक ढाल वेक्टर का प्रतिनिधित्व करता है। इसलिए यदि सभी बिंदु या तीव्रता एक दिशा में झूठ बोलते हैं, तो उस दिशा के लिए हिस्टोग्राम 45 डिग्री कहते हैं, हिस्टोग्राम 45 डिग्री पर चरम पर होगा।
तो अब हम क्या करते हैं, हम प्रत्येक सेल को कोणीय डिब्बे में विभाजित करते हैं, जहां प्रत्येक बिन एक ढाल दिशा (जैसे x, y) से मेल खाती है। दलाल और ट्रिग्स पेपर में, उन्होंने 9 बिन्स -1-180 ° (20 ° प्रत्येक बिन) का उपयोग किया। यह प्रभावी रूप से 64 वैक्टर को सिर्फ 9 मानों तक कम करता है। इसलिए हमने जो किया है उसका आकार घटाया गया है लेकिन सभी महत्वपूर्ण जानकारी रखी गई है जिसकी आवश्यकता है।
हॉग की गणना में अगला कदम सामान्यीकरण है, हम रोशनी में परिवर्तन या चमक और विपरीत के लिए सुनिश्चित करने के लिए ग्रेडिएंट को सामान्य करते हैं।
इस छवि में, तीव्रता के मानों को संबंधित दिशा के अनुसार वर्ग में दिखाया गया है और सभी में एक दूसरे के बीच 50 का अंतर है
∆ एच = 50, = वी = 50; │∆│ = │∆│50 2 +50 = 70.72, 70.72 / 100 = 0.707
हम वैक्टर को क्रमिक परिमाण द्वारा विभाजित करते हैं जो हम सभी के लिए 0.707 प्राप्त करते हैं, यह सामान्यीकरण है।
इसी तरह, यदि हम तीव्रता को बदलते हैं या इसके विपरीत बदलते हैं तो हमें नीचे दिए गए मूल्य मिलते हैं।
∆ एच = 50, = वी = 50; │∆│ = │∆│50 2 +50 = 70.72, 70.72 / 100 = 0.707; ∆ एच = 100, = वी = 100; │∆│ = │∆│100 2 +100 = 141.42, 141.42 / 100 = 1.41
सामान्यीकरण एक सेल स्तर पर नहीं होता है, इसके बजाय यह ब्लॉक स्तर पर होता है, इसलिए यहां ब्लॉक मूल रूप से 4 कोशिकाओं का एक समूह है, यह पड़ोसी ब्लॉकों को ध्यान में रखता है इसलिए छवि के बड़े खंडों को ध्यान में रखते हुए सामान्य हो जाता है।
अब कोड को देखते हैं
आयात सुन्नत के रूप में एनपी आयात cv2 आयात matplotlib.pyplot plt # लोड छवि के रूप में तो ग्रेस्केल छवि = cv2.imread ('हाथी ।jpg') ग्रे = cv2.cvtColor (छवि, cv2.COLOR_BGR2GRAY) # मूल छवि दिखाएँ cv2.imshow इनपुट छवि ', छवि) cv2.waitKey (0) # मापदंडों को पूरा करते हुए, पिक्सेल आकार में सेल आकार और ब्लॉक आकार # hxw को cell_size = (8, 8) # hxw कोशिकाओं में block_size = (2, 2) # अभिविन्यास डिब्बे की संख्या nbins = 9 # OpenCV के HOG डिस्क्रिप्टर का उपयोग करना # winSize छवि का आकार सेल आकार के कई प्रकारों के लिए फसली है = cv2.HOGDescriptor (_winSize = (g.shape) - cell_size * cell_size, 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) # numpy सरणी आकार जो हम प्रयोग बनाएं बनाने के लिए hog_features n_cells = (ग्रे.शैप // सेल_साइज, ग्रे.शैप // सेल_साइज) # हम पंक्तियों द्वारा पहले ब्लॉक करते हैं। # hog_feats में प्रत्येक समूह के प्रत्येक समूह के लिए प्रत्येक दिशा के लिए, # प्रत्येक के लिए ढाल आयाम हैं । अनुक्रमण पंक्तियों द्वारा है फिर स्तंभों द्वारा। hog_feats = hog.compute (ग्रे).reshape (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose (1, 0, 2, 3, 4))। # ग्रेडिएंट ओरिएंटेशन ग्रेडिएंट्स = np.zeros ((n_cells, n_cells, nbins) स्टोर करने के लिए एनबीएन आयामों के साथ हमारे ग्रेडिएंट एरे बनाएं। डाइमेंशन का आयाम सेल_काउंट = np.full (n_cells, n_cells, 1), 0, dtype = int) रेंज में ब्लॉक_ के लिए # ब्लॉक सामान्यीकरण (ब्लॉक_साइज़): रेंज में ब्लॉक_एक्स के लिए (ब्लॉक_साइज़): ग्रेडिएंट - ब्लॉक_साइज़ + ऑफ_य + 1, ऑफ_एक्स: n_cells - block_size + off_x + 1] + = \ hog_feats cell_count - block_size + off_size + off_x: n_cells - block_size + off_x + 1] + = 1 # औसत ग्रेडिएंट ग्रेडिएंट्स / = cell_count # Matplotlib # एंगल का उपयोग करके प्लॉट HOGs 360 / nbins * * color_bins = 5 plt.pcolor (ग्रेडिएंट) है plt.gca ()। invert_yaxis () plt.gca ()। set_aspect ('बराबर', समायोज्य = 'बॉक्स') plt.colorbar () plt.show () cv..destroyAllWindows ()
छवि दिखाती है कि इनपुट छवि को HOG प्रतिनिधित्व के रूप में कैसे दर्शाया गया है।
HAAR कैस्केड क्लासिफायर
जैसा कि पहले चर्चा की गई है, हम एक छवि से सुविधाओं को निकाल सकते हैं और उन सुविधाओं का उपयोग वस्तुओं को वर्गीकृत या पता लगाने के लिए कर सकते हैं।
HAAR कैस्केड क्लासिफायर क्या हैं?
एक वस्तु का पता लगाने की विधि जो कि Haar को इमेज में ऑब्जेक्ट्स की पहचान करने के लिए क्लासिफायर (कैस्केड) की एक श्रृंखला में पेश करती है। उन्हें एक प्रकार की वस्तु की पहचान करने के लिए प्रशिक्षित किया जाता है, हालांकि, हम उनमें से कई का उपयोग कर सकते हैं जैसे कि आंखों और चेहरे का एक साथ पता लगाना।
HAAR क्लासिफायर समझाया:
HAAR क्लासिफायर का उपयोग बहुत सारी सकारात्मक छवियों (अर्थात वर्तमान वस्तु के साथ चित्र) और
नकारात्मक छवियों (अर्थात वर्तमान वस्तु के बिना चित्र) का उपयोग करके किया जाता है।
एक बार जब हमारे पास वे चित्र होते हैं, तो हम आयताकार ब्लॉकों की खिड़कियों को खिसकाकर सुविधाओं को निकालते हैं । ये विशेषताएँ (HAAR सुविधाएँ) एकल मूल्यवान हैं और इनकी गणना काले आयतों से सफेद आयतों के नीचे पिक्सेल तीव्रता के योग को घटाकर की जाती है ।
हालाँकि, यह गणना की एक हास्यास्पद संख्या है, यहां तक कि 24 x 24 पिक्सल (उत्पन्न उत्पन्न 180,000) की आधार विंडो के लिए भी।
इसलिए शोधकर्ताओं ने इंटीग्रल इमेजेज नामक एक विधि तैयार की जिसने चार सरणी संदर्भों के साथ इसकी गणना की। हालांकि, उनके पास अभी भी 180,000 विशेषताएं थीं और उनमें से अधिकांश ने कोई वास्तविक मूल्य नहीं जोड़ा।
बढ़ाने तो Freund और Schapire के साथ सबसे जानकारीपूर्ण सुविधाओं, निर्धारित करने के लिए इस्तेमाल किया गया था AdaBoost और यह छवि में सबसे जानकारीपूर्ण सुविधाओं पाया। बूस्टिंग वह प्रक्रिया है जिसके द्वारा हम कमजोर क्लासिफायर का उपयोग करके मजबूत क्लासिफायरफायर का निर्माण करते हैं, बस गलत मूल्यांकन पर भारी भारित दंड का प्रावधान करते हैं। 180,000 सुविधाओं को 6000 तक कम करना, जो अभी भी काफी विशेषताएं हैं।
उन 6000 सुविधाओं में, कुछ दूसरों की तुलना में अधिक जानकारीपूर्ण होंगी। इसलिए यदि हम सबसे पहले सूचनात्मक सुविधाओं का उपयोग करते हैं कि क्या क्षेत्र संभावित रूप से एक चेहरा हो सकता है (झूठी सकारात्मक कोई बड़ी बात नहीं होगी)। ऐसा करने से एक बार में सभी 6000 सुविधाओं की गणना करने की आवश्यकता समाप्त हो जाती है। इस अवधारणा को क्लासीफायर्स का कैस्केड कहा जाता है - चेहरे का पता लगाने के लिए, वियोला जोन्स विधि ने 38 चरणों का उपयोग किया।
चेहरा और आँख का पता लगाना
इसलिए HAAR कैस्केड के बारे में कुछ सैद्धांतिक ज्ञान प्राप्त करने के बाद हम इसे अंत में लागू करने जा रहे हैं, ताकि चीजों को बहुत स्पष्ट करने के लिए हम भागों में पाठ को तोड़ देंगे, पहले हम ललाट चेहरे का पता लगाएंगे उसके बाद हम ललाट चेहरे का पता लगाने के लिए आगे बढ़ेंगे। आँखें और अंत में हम वेबकैम के माध्यम से चेहरे और आँखों की लाइव पहचान करेंगे।
तो इसके लिए हम पूर्व प्रशिक्षित क्लासीफायर का उपयोग करने जा रहे हैं जो कि ओपनसीवी द्वारा प्रदान की गई हैं। xml फाइलें, एक्सएमएल एक्स्टेंसिबल मार्कअप लैंग्वेज के लिए है, इस भाषा का उपयोग बड़ी मात्रा में डेटा स्टोर करने के लिए किया जाता है, आप इस पर एक डेटाबेस भी बना सकते हैं।
आप इस लिंक पर इन क्लासिफायर का उपयोग कर सकते हैं ।
चेहरा पहचानना
चलो ललाट चेहरे का पता लगाने के लिए प्रयास करें, आप ललाट चेहरे डिटेक्टर के झरना के लिए उपयोग कर सकते हैं। Xml फ़ाइल प्राप्त करने के लिए बस ज़िप फ़ाइल निकालें।
के रूप में एन पी आयात numpy आयात CV2 # हम जहां हमारे लिए OpenCV के CascadeClassifier समारोह इंगित # वर्गीकारक (XML फ़ाइल स्वरूप) संग्रहीत किया जाता है, में एक ही फ़ोल्डर कोड और वर्गीकारक रखने के लिए याद face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # लोड हमारी छवि तब इसे ग्रेस्केल छवि में परिवर्तित करती है = cv2.imread ('Trump.jpg') ग्रे = cv2.cvtColor (छवि, cv2.COLOR_BGR2GRAY) # हमारी कक्षाएँ एक टुपल के रूप में पहचाने गए चेहरे के ROI को लौटाती हैं # यह एक शीर्ष # स्टोर की तरह है। समन्वय और निचला दायां निर्देशांक # यह सूचियों की सूची लौटाता है, जो अलग-अलग चेहरों के स्थान का पता लगाता है। चेहरे = face_cascade.detectMultiScale (ग्रे, 1.3, 5) # जब कोई चेहरे का पता नहीं चलता है, तो face_classifier वापस आ जाता है और अगर चेहरा खाली है (): प्रिंट ("कोई चेहरा नहीं मिला") # हम अपने चेहरे के सरणी के माध्यम से पुनरावृत्ति करते हैं और प्रत्येक चेहरे पर # (x, y, w, के लिए एक आयत खींचते हैं) h) चेहरों में: cv2.rectangle (छवि, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('फेस डिटेक्शन', इमेज) vv2.waitKey (0) cv2.destroyAllWindows ()
अब आइए एक साथ चेहरे और आंख का पता लगाएं, आप एक ही ज़िप फ़ाइल में आई डिटेक्टर के कैस्केड के लिए उपयोग कर सकते हैं।
आयात सुन्न के रूप में np आयात cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = c2_2 .read2.read cv2.COLOR_BGR2GRAY) चेहरे = face_classifier.detectMultiScale (स्लेटी, 1.3, 5) # जब कोई चेहरे का पता नहीं लगा, तो face_classifier रिटर्न और खाली ट्यूपल अगर चेहरे हैं (): प्रिंट ("No Face Found") के लिए (x, y, w, h, w, h)) चेहरों में: cv2.rectangle (img, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow ('img', img, roi_gray = ग्रे roi_color = img आंखों = eye_classifier.detectMultiScale (roi_gray) cv2.waitKey (0) आँखों में (पूर्व, eY, ew, हाँ) के लिए: cv2.rectangle (roi_color, (ex, eye), (ex + ew, eye + eh), (255,255,0), 2) cv2.imshow ('img', img, cv2.waitKey (0) cv2.destroyAllWindows )) cv2.waitKey (0)
तो यह कोड उतना ही है जितना कि चेहरे का पता लगाने के लिए कोड, लेकिन यहां हमने उन्हें खोजने के लिए आंखों के कैस्केड और विधि को जोड़ा है, जैसा कि आप देख सकते हैं कि हमने चेहरे के ग्रे स्केल किए गए संस्करण को पता लगाने के लिए पैरामीटर के रूप में चुना है। आंखें, जो हमें गणना में कमी लाती हैं क्योंकि हम केवल उस क्षेत्र में केवल आंखों का पता लगाने जा रहे हैं।
लाइव फेस एंड आई डिटेक्शन
इसलिए अब तक हमने फेस और आई डिटेक्शन किया है, अब वेब कैमरा से लाइव वीडियो स्ट्रीम के साथ इसे लागू करते हैं । इसमें हम चेहरे और आंखों का समान पता लगाएंगे, लेकिन इस बार हम इसे लाइव स्ट्रीम के लिए वेब कैमरा बना देंगे। अधिकांश एप्लिकेशन में आप अपने चेहरे को उसके चारों ओर एक बॉक्स के साथ हाइलाइट करते हुए पाएंगे, लेकिन यहां हमने कुछ अलग किया है कि आप अपने चेहरे को काटते हुए पाएंगे और आंखों की पहचान केवल उसी में होगी।
इसलिए यहां हम चेहरे और आंख दोनों को वर्गीकृत कर रहे हैं, और चेहरे और आंख की पहचान के लिए सभी प्रसंस्करण करने के लिए एक फ़ंक्शन को परिभाषित किया है। और इसके बाद वेब कैमरा स्ट्रीम शुरू की और चेहरे और आंखों का पता लगाने के लिए फेस डिटेक्टर फंक्शन को बुलाया। फेस डिटेक्टर फंक्शन के अंदर हम जिस पैरामीटर को परिभाषित कर रहे हैं वह लाइव वेब कैम स्ट्रीम से निरंतर छवियां हैं
आयात CV2 एनपी के रूप में आयात numpy face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') डीईएफ़ face_detector (img, आकार = 0.5): # Convert छवि स्केल के लिए ग्रे = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) चेहरे = face_classifier.detectMultiScale (स्लेटी, 1.3, 5) यदि चेहरे हैं (): चेहरों में x (x, y, w, h) के लिए img लौटाएँ : x = x - 50 w = w + 50 + 50 y = y - 50 h = h + 50 cv2.rectangle (img, (x, y), (x + w, y + h), ( 255,0,0 ), 2) roi_gray = ग्रे रो_कोलर / img आँखें = आंखों में ( पूर्व, आंख, ईव, एह) के लिए eye_classifier.detectMultiScale (roi_gray) : cv2.rectangle (roi_color, (ex, eye), (ex + ew, eye + eh), (0,0,255), 2) roi_color = cv2.flip (roi -color, 1) रिटर्न roi_color cap = cv2.VideoCapture (0)। जबकि ट्रू: रिट, फ्रेम = cap.read () cv2.imshow ('अवर फेस एक्स्ट्रेक्टर', face_detector (फ्रेम)) यदि cv2.waitKey (1) == 13: # 13 Enter कुंजी ब्रेक cap.release () है cv2.destroyAllWindows ()
ट्यूनिंग कैस्केड क्लासिफायर
इनपुट छवि के अलावा अन्य DetMultiScale के अंदर परिभाषित मापदंडों का निम्नलिखित महत्व है
हमारे क्लस्टर। DetMultiScale (इनपुट छवि, स्केल फैक्टर, न्यूनतम पड़ोसी)
- स्केल फैक्टर निर्दिष्ट करता है कि हम हर बार स्केल करते समय छवि का आकार कितना कम करते हैं। उदाहरण के लिए चेहरा पहचानने में हम आमतौर पर 1.3 का उपयोग करते हैं। इसका मतलब है कि हम हर बार स्केल होने पर छवि को 30% तक कम करते हैं। छोटे मान, जैसे 1.05 को गणना करने में अधिक समय लगेगा, लेकिन पहचान की दर में वृद्धि होगी।
- न्यूनतम पड़ोसी प्रत्येक सकारात्मक खिड़की पर विचार करने के लिए प्रत्येक संभावित विंडो में पड़ोसियों की संख्या निर्दिष्ट करता है। आमतौर पर 3-6 के बीच सेट करें। यह संवेदनशीलता सेटिंग के रूप में कार्य करता है, कम मूल्य कभी-कभी एकल चेहरे पर कई गुना चेहरे का पता लगाएगा। उच्च मूल्य कम झूठी सकारात्मकता सुनिश्चित करेंगे, लेकिन आपको कुछ चेहरे याद आ सकते हैं।
वीडियो में कार और पैदल यात्री का पता लगाना
अब हम HAAR कैस्केड का उपयोग करते हुए वीडियो में पैदल चलने वालों और कारों का पता लगाएंगे, लेकिन अगर कोई वीडियो लोड नहीं हो रहा है और कोड बिना किसी त्रुटि के संकलन करता है, तो आपको निम्नलिखित चरणों का पालन करने की आवश्यकता है:
यदि कोड चलने के बाद कोई वीडियो लोड नहीं होता है, तो आपको हमारे opencv_ffmpeg.dl को कॉपी करने की आवश्यकता हो सकती है : opencv \ source \ 3rdparty \ ffmpeg को इसे पेस्ट करने के लिए जहां आपका अजगर स्थापित है जैसे C: \ Anacar22
: एक बार जब यह की नकल की है आप OpenCV आप कर रहे हैं using.eg आप OpenCV 2.4.13 उपयोग कर रहे हैं तो के रूप में फ़ाइल का नाम बदलने के संस्करण के अनुसार फ़ाइल का नाम बदलने की आवश्यकता होगी opencv_ffmpeg2413_64.dll या opencv_ffmpeg2413.dll (अगर आप X86 मशीन का उपयोग करके) opencv_ffmpeg310_64.dll या opencv_ffmpeg310.dll (यदि आप X86 मशीन का उपयोग कर रहे हैं)
यह पता लगाने के लिए कि आपने python.exe कहाँ स्थापित किया है, बस कोड की इन दो पंक्तियों को चलाएं, यह उस स्थान को प्रिंट करेगा जहाँ अजगर स्थापित है।
आयात sys प्रिंट (sys.executable)
अब यदि आपने ये चरण सफलतापूर्वक कर लिए हैं, तो चलिए पैदल यात्री का पता लगाने के लिए कोड पर चलते हैं , पैदल यात्री का पता लगाने के लिए और यहां लगी ज़िप फ़ाइल से आप झरना पा सकते हैं।
आयात cv2 आयात np के रूप में numpy # हमारे बॉडी क्लासिफायरफ़ायर body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # वीडियो फ़ाइल के लिए # पहल वीडियो कैप्चर बनाएँ, यहाँ हम उस वीडियो फ़ाइल का उपयोग कर रहे हैं जिसमें पैदल चलने वालों को टोपी = cv2.Videoapture का पता लगाया जाएगा। 'walk.avi') # लूप एक बार वीडियो को सफलतापूर्वक लोड किया जाता है जबकि cap.isOpened (): # वीडियो रिट के प्रत्येक फ्रेम को पढ़ना , फ्रेम = cap.read () # यहां हम फ्रेम का आकार बदल रहे हैं, इसके आधे आकार तक।, हम वर्गीकरण को गति देने के लिए कर रहे हैं # क्योंकि बड़ी छवियों के पास स्लाइड करने के लिए बहुत अधिक खिड़कियां हैं, इसलिए कुल मिलाकर हम संकल्प को कम कर रहे हैं # आधे से वीडियो जो कि 0.5 से संकेत मिलता है, और हम भी तेज प्रक्षेप विधि का उपयोग कर रहे हैं जो कि #interlinear फ्रेम = cv2.resize (फ्रेम, कोई नहीं, fx = 0.5, fy = 0.5, प्रक्षेप = cv2.INTER_LINEAR) ग्रे = cv2 है। cvtColor (फ्रेम, cv2.COLOR_BGR2GRAY) # पास फ्रेम हमारे बॉडी क्लासिफायर बॉडीज = body_classifier.detectMultiScale (स्लेटी, 1.2, 3) # बॉडी में (x, y, w, h) के लिए पहचाने गए किसी भी बॉडी के बॉक्सेस बॉक् स : cv2। आयत (फ्रेम, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('पैदल यात्री', फ्रेम) यदि cv2.waitKey (1) == 13: # 13 Enter कुंजी ब्रेक cap.release () cv2.destroyAllWindows () है
वीडियो में पैदल यात्री का सफलतापूर्वक पता लगाने के बाद, आइए कार का पता लगाने के लिए कोड पर जाएं , यहां से पैदल यात्री का पता लगाने के लिए आप कैस्केड कर सकते हैं।
आयात cv2 आयात समय np # एनपीआई के रूप में सुन्नत आयात करें। हमारे बॉडी क्लासिफायर कार_क्लासीफायर = cv2.CascadeClassifier ('haarcascade_car.xml') बनाएं # वीडियो कैप = cv2.VideoCapture ('Cars.avi') # लूप एक बार वीडियो सफल होने के बाद वीडियो कैप्चर करें। cap.isOpened (): time.sleep (.05) # लोड करते समय पहली फ्रेम रिट, फ्रेम = cap.read () ग्रे = cv2.cvtColor (फ्रेम, cv2.COLOR_BGR2GYY) # हमारी कार क्लासिफायर कारें = car_classifier को पास करें।.detectMultiScale (ग्रे, 1.4, 2) # कारों में (x, y, w, h) के लिए पहचाने गए बॉडी के लिए बाउंडिंग बॉक्स निकालें : cv2.rectangle (फ्रेम, (x, y), (x + w, y + h)), (0, 255, 255), 2) cv2.imshow ('कार', फ़्रेम) यदि cv2.waitKey (1) == 13: # 13 कुंजी ब्रेक है। cap.release () cv2.destroyAllWindows ()
आपने देखा है कि हमने time.sleep (.05) जोड़ दिया है , यह केवल फ्रेम दर में देरी है, इसलिए आप पुष्टि कर सकते हैं कि सभी कारों की सही पहचान की गई है, या आप इसे केवल एक टिप्पणी लेबल जोड़कर आसानी से निकाल सकते हैं।
यह लेख राजीव रतन द्वारा निर्मित उदयन पर डीप लर्निंग कोर्स के साथ पाइथन में मास्टर कंप्यूटर विजन ™ ओपनसीवी 4 से संदर्भित है, इसे कंप्यूटर विजन और पायथन के बारे में अधिक जानने के लिए सदस्यता लें।