- Ανίχνευση αντικειμένων χρησιμοποιώντας SIFT
- Ανίχνευση αντικειμένων χρησιμοποιώντας ORB
- Ιστόγραμμα των προσανατολισμένων ντεγκραντέ (HOG's)
- Ιστόγραμμα των προσανατολισμένων ντεγκραντέ (HOG's), βήμα προς βήμα:
- Ταξινομητές καταρράκτη HAAR
- Ανίχνευση προσώπου και ματιών
- Ζωντανή ανίχνευση προσώπου και ματιών
- Συντονιστές Cascade Classifiers
- Ανίχνευση αυτοκινήτου και πεζών σε βίντεο
Ξεκινήσαμε με την εγκατάσταση του python OpenCV σε παράθυρα και μέχρι στιγμής κάναμε κάποια βασική επεξεργασία εικόνας, τμηματοποίηση εικόνας και ανίχνευση αντικειμένων χρησιμοποιώντας το Python, τα οποία καλύπτονται στα παρακάτω σεμινάρια:
- Ξεκινώντας με το Python OpenCV: Εγκατάσταση και βασική επεξεργασία εικόνων
- Χειρισμοί εικόνας στο Python OpenCV (Μέρος 1)
- Χειρισμοί εικόνας στο OpenCV (Μέρος-2)
- Τμηματοποίηση εικόνας χρησιμοποιώντας OpenCV - Εξαγωγή συγκεκριμένων περιοχών μιας εικόνας
Μάθαμε επίσης για διάφορες μεθόδους και αλγόριθμους για Ανίχνευση Αντικειμένων, όπου εντοπίστηκαν ορισμένα βασικά σημεία για κάθε αντικείμενο χρησιμοποιώντας διαφορετικούς αλγόριθμους. Σε αυτό το σεμινάριο θα χρησιμοποιήσουμε αυτούς τους αλγόριθμους για να εντοπίσουμε αντικείμενα πραγματικής ζωής, εδώ θα χρησιμοποιούσαμε SIFT και ORB για την ανίχνευση.
Ανίχνευση αντικειμένων χρησιμοποιώντας SIFT
Εδώ η ανίχνευση αντικειμένων θα γίνει χρησιμοποιώντας ζωντανή ροή κάμερας web, οπότε αν αναγνωρίσει το αντικείμενο θα αναφέρει το objet που βρέθηκε. Στον κώδικα το κύριο μέρος παίζεται από τη συνάρτηση που ονομάζεται SIFT ανιχνευτής, το μεγαλύτερο μέρος της επεξεργασίας γίνεται από αυτήν τη λειτουργία.
Και στο άλλο μισό του κώδικα, ξεκινάμε με το άνοιγμα της ροής της κάμερας web, και στη συνέχεια φορτώνουμε το πρότυπο εικόνας, δηλαδή την εικόνα αναφοράς, δηλαδή το πρόγραμμα αναζητά στην πραγματικότητα τη ροή της κάμερας.
Στη συνέχεια, είμαστε συνεχώς λήψη των εικόνων από το ρεύμα κάμερα με τη βοήθεια του άπειρου , ενώ βρόχο, και στη συνέχεια, συλλαμβάνοντας το αντίστοιχο ύψος και το πλάτος του πλαισίου κάμερα, και μετά στη συνέχεια, ορίζουν τις παραμέτρους της περιοχής ενδιαφέροντος (ROI) στην οποία το αντικείμενο μας μπορεί να χωρέσει λαμβάνοντας το αντίστοιχο ύψος και πλάτος του πλαισίου της κάμερας web. Και μετά αντλούμε το ορθογώνιο από τις παραμέτρους ROI που είχαμε ορίσει παραπάνω. Στη συνέχεια, κόψτε το ορθογώνιο και τροφοδοτήστε το στο τμήμα ανιχνευτή SWIFT του κώδικα.
Τώρα ο ανιχνευτής SIFT έχει βασικά δύο εισόδους, η μία είναι η περικομμένη εικόνα και η άλλη είναι το πρότυπο εικόνας που ορίσαμε προηγουμένως και στη συνέχεια μας δίνει κάποιες αντιστοιχίες, οπότε οι αγώνες είναι βασικά ο αριθμός των αντικειμένων ή των σημείων πληκτρολογίου που είναι παρόμοια στην περικομμένη εικόνα και την εικόνα-στόχο. Στη συνέχεια, ορίζουμε μια τιμή κατωφλίου για τους αγώνες, εάν η τιμή των αγώνων είναι μεγαλύτερη από το όριο, βάζουμε την εικόνα που βρέθηκε στην οθόνη μας με πράσινο χρώμα του ορθογωνίου ROI.
Τώρα ας επιστρέψουμε στο κύριο μέρος του κώδικα, τη λειτουργία που ονομάζεται ανιχνευτής SIFT, παίρνει την είσοδο καθώς δύο εικόνες είναι η εικόνα όπου ψάχνει το αντικείμενο και άλλη είναι το αντικείμενο που προσπαθούμε να ταιριάξουμε σε (πρότυπο εικόνας). Στη συνέχεια, γκρι κλίμακα την πρώτη εικόνα και ορίστε το πρότυπο εικόνας ως δεύτερη εικόνα. Στη συνέχεια, δημιουργούμε ένα αντικείμενο ανιχνευτή SIFT και εκτελούμε τη λειτουργία εντοπισμού και υπολογισμού OpenCV SIFT, έτσι ώστε να εντοπίσουμε τα σημεία πληκτρολογίου και να υπολογίσουμε τους περιγραφείς, οι περιγραφείς είναι βασικά τα διανύσματα που αποθηκεύουν τις πληροφορίες σχετικά με τα πληκτρολόγια και είναι πολύ σημαντικό καθώς κάνουμε την αντιστοίχιση μεταξύ των περιγραφών των εικόνων.
Και, στη συνέχεια, ορίστε το πρόγραμμα αντιστοίχισης με βάση το FLANN, δεν μπαίνουμε στη μαθηματική θεωρία της αντιστοίχισης πίσω από αυτό, αλλά μπορείτε εύκολα να το Google σχετικά με αυτό. Πρώτον, ορίστε το ευρετήριο kdtree στο μηδέν και μετά ορίζουμε τις παραμέτρους ευρετηρίου και αναζήτησης στη μορφή λεξικού, απλώς ορίζουμε τον αλγόριθμο που πρόκειται να χρησιμοποιήσουμε, ο οποίος είναι KDTREE και τον αριθμό των δέντρων που πρόκειται να χρησιμοποιήσουμε, τόσο περισσότερο δέντρο χρησιμοποιούμε το πιο περίπλοκο γίνεται και πιο αργά. Και στην παράμετρο αναζήτησης ορίστε τον αριθμό των επιταγών, που είναι βασικά ο αριθμός των αντιστοιχιών που πρόκειται να ολοκληρωθούν.
Και, στη συνέχεια, δημιουργήστε το αντικείμενο αντιστοίχισης με βάση το FLANN φορτώνοντας την παράμετρο που ορίσαμε προηγουμένως, οι οποίες είναι παράμετροι ευρετηρίου και παράμετροι αναζήτησης και με βάση αυτό δημιουργήστε τον αντιστοιχιστή με βάση το FLANN, ο οποίος είναι αντιστοιχιστής KNN όπου το KNN είναι οι πλησιέστεροι γείτονες, ψάχνουμε για κοντινότερους αντιστοιχιστές και περιγραφείς και κάνουμε την αντιστοίχιση με σταθερά αρχικοποίησης Τώρα αυτός ο συνδυασμός FLANN επιστρέφει τον αριθμό των αγώνων που λαμβάνουμε.
Η αντιστοίχιση με βάση το FLANN είναι απλώς μια προσέγγιση, έτσι ώστε να αυξήσουμε την ακρίβεια του αντιστοιχιστή με βάση το FLANN, πραγματοποιούμε δοκιμή αναλογίας Lowe και αυτό που κάνει είναι να αναζητά τους αγώνες από τον αντιστοιχιστή με βάση το knn flann και να καθορίσει μερικές παραμέτρους του πίνακα που είναι απόσταση εδώ, για ποια απόσταση είναι μια συνάρτηση numpy, και όταν πληροί τα κριτήρια, προσαρτήστε τους αγώνες στους καλούς αγώνες και επιστρέφει τους καλούς αγώνες που βρέθηκαν, και έτσι η ζωντανή ροή βίντεο αναφέρει τον αριθμό των αγώνων που βρέθηκαν στη γωνία της οθόνης.
Τώρα ας δούμε τον κωδικό για την παραπάνω περιγραφή:
cv2 εισαγωγή εισαγωγής NumPy ως NP def sift_detector (new_image, image_template): # Λειτουργία που συγκρίνει την εικόνα εισόδου στο πρότυπο # Στη συνέχεια, επιστρέφει ο αριθμός των SIFT αγώνες μεταξύ τους image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) image2 = image_template # Δημιουργία Ανιχνευτής αντικειμένου SIFT #sift = cv2.SIFT () sift = cv2.xfeatures2d.SIFT_create () # Λάβετε τα σημεία και τους περιγραφείς χρησιμοποιώντας SIFT keypoints_1, deskors_1 = sift.detectAndCompute (image1, None) keypoints_2, deskors_2 = sift.detectAnd Καμία) # Ορίστε παραμέτρους για το Flann Matcher FLANN_INDEX_KDTREE = 0 index_params = dict (αλγόριθμος = FLANN_INDEX_KDTREE, tree = 3) search_params = dict (checks = 100) # Δημιουργήστε το αντικείμενο Flann Matcher flann = cv2.FlannBasedMatcher (index_params, search_params) # Λάβετε αντιστοιχίσεις χρησιμοποιώντας τη μέθοδο K-Nearest Neighbor # το αποτέλεσμα "matchs" είναι ο αριθμός παρόμοιων αντιστοιχιών που βρέθηκαν και στους δύο αγώνες = flann.knnMatch (περιγραφή1, περιγραφείς_2, k = 2) # Αποθηκεύστε καλές αντιστοιχίες χρησιμοποιώντας δοκιμή αναλογίας Lowe good_matches = για m, n σε αγώνες: εάν m.distance <0,7 * n.distance: good_matches.append (m) return len (good_matches) cap = cv2.VideoCapture (0) # Φορτώστε το πρότυπο εικόνας μας, αυτή είναι η εικόνα αναφοράς μας image_template = cv2.imread ('phone.jpg', 0) ενώ True: # Λήψη εικόνων κάμερας web ret, frame = cap.read () # Λήψη ύψους και πλάτους της κάμερας web ύψος, πλάτος = frame.shape # Ορισμός ROI Box Διαστάσεις top_left_x = int (πλάτος / 3) top_left_y = int ((ύψος / 2) + (ύψος / 4)) bottom_right_x = int ((πλάτος / 3) * 2) bottom_right_y = int ((ύψος / 2) - (ύψος / 4)) # Σχεδιάστε ορθογώνιο παράθυρο για την περιοχή ενδιαφέροντός μας cv2. ορθογώνιο (πλαίσιο, (top_left_x, top_left_y)), (bottom_right_x, bottom_right_y), 255, 3) # Παράθυρο περικοπής της παρατήρησης που ορίσαμε παραπάνω περικομμένο = πλαίσιο # Αναστροφή πλαισίου οριζόντια καρέ = cv2.flip (πλαίσιο, 1) # Λήψη αριθμού αντιστοιχιών SIFT ταιριάζει = sift_detector (περικομμένο, image_template) # Εμφάνιση συμβολοσειράς κατάστασης που δείχνει το τρέχον αριθ. των αγώνων cv2.putText (πλαίσιο, str (αγώνες), (450,450), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 1) # Το κατώφλι μας για την ένδειξη αντικειμένου deteciton # Χρησιμοποιούμε 10 αφού ο ανιχνευτής SIFT επιστρέφει λίγο ψευδείς θέσεις threshold = 10 # Εάν οι αντιστοιχίσεις υπερβαίνουν το όριό μας, τότε το αντικείμενο έχει ανιχνευτεί εάν ταιριάζει> threshold: cv2.rectangle (frame, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (πλαίσιο, "Object Found", (50,50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ("Object Detector using SIFT", frame) if cv2.waitKey (1) == 13: # 13 είναι το Enter Key break cap.release () cv2.destroyAllWindows ()
Ανίχνευση αντικειμένων χρησιμοποιώντας ORB
Η ανίχνευση αντικειμένων που χρησιμοποιεί SIFT είναι πολύ δροσερή και ακριβής, καθώς δημιουργεί έναν πολύ ακριβή αριθμό αντιστοιχιών με βάση τα πληκτρολόγια, ωστόσο είναι κατοχυρωμένο με δίπλωμα ευρεσιτεχνίας και αυτό καθιστά δύσκολη τη χρήση του για εμπορικές εφαρμογές, η άλλη διέξοδος είναι αυτός ο αλγόριθμος ORB για ανίχνευση αντικειμένων.
Παρόμοια με τη μέθοδο ανίχνευσης αντικειμένων από το SIFT στην οποία χωρίσαμε το πρόγραμμα σε δύο μέρη, το ίδιο θα ακολουθηθεί εδώ.
Πρώτον, ορίζουμε τη συνάρτηση ORB_detector που παίρνει δύο εισόδους, μία είναι η εικόνα ζωντανής ροής που προέρχεται από κάμερα web και άλλη είναι το πρότυπο εικόνας βάσει του οποίου πρόκειται να ταιριάξει την εικόνα μας. Στη συνέχεια, κάνουμε κλίμακα του γκρι της εικόνας της κάμερας και στη συνέχεια αρχικοποιούμε τον ανιχνευτή ORB και το θέτουμε εδώ σε 1000 βασικά σημεία και παραμέτρους κλιμάκωσης 1,2. μπορείτε εύκολα να παίξετε με αυτές τις παραμέτρους και, στη συνέχεια, να εντοπίσετε τα πληκτρολόγια (kp) και τους περιγραφείς (des) και για τις δύο εικόνες και η δεύτερη παράμετρος που ορίζουμε στη λειτουργία ανίχνευσηςANDCompute είναι ΚΑΝΕΝΑ, ζητά τη χρήση μάσκας εικόνας ή όχι και το αρνούμαστε εδώ.
Στη συνέχεια, μεταβείτε στον ανιχνευτή προηγουμένως χρησιμοποιούμε το πρόγραμμα αντιστοίχισης με βάση το FLANN, αλλά εδώ θα χρησιμοποιούμε το BFMatcher και μέσα στο BFMatcher ορίζουμε δύο παραμέτρους, μία είναι NORM_HAMMING και άλλη είναι το crossCheck του οποίου η τιμή είναι ΑΛΗΘΗ
Στη συνέχεια, υπολογίστε τους αγώνες των αγώνων μεταξύ αυτών των δύο εικόνων χρησιμοποιώντας τους περιγραφείς που ορίζονται παραπάνω, οι οποίοι σε όλες επιστρέφουν τον αριθμό των αγώνων, καθώς αυτοί οι αγώνες δεν είναι προσέγγιση και ως εκ τούτου δεν χρειάζεται να κάνετε τη δοκιμή αναλογίας Lowe, αντί να ταξινομούμε τους αγώνες με βάση την απόσταση, τουλάχιστον η απόσταση όσο μεγαλύτερη είναι η αντιστοιχία (εδώ η απόσταση σημαίνει απόσταση μεταξύ των πόντων) και στο τέλος επιστρέφουμε τον αριθμό των αγώνων χρησιμοποιώντας τη συνάρτηση μήκους.
Και στην κύρια συνάρτηση ορίζουμε το όριο σε πολύ υψηλότερη τιμή, καθώς ο ανιχνευτής σφαιρών παράγει πολύ θόρυβο.
Τώρα ας δούμε τον κώδικα για ανίχνευση με βάση το ORB
import cv2 import numpy as np def ORB_detector (new_image, image_template): # Λειτουργία που συγκρίνει την εικόνα εισόδου με το πρότυπο # Στη συνέχεια επιστρέφει τον αριθμό των αντιστοιχιών ORB μεταξύ τους image1 = cv2.cvtColor (new_image, cv2.COLOR_BGR2GRAY) # Δημιουργία ανιχνευτή ORB με 1000 σημεία πληκτρολογίου με συντελεστή πυραμίδας κλιμάκωσης 1,2 orb = cv2.ORB_create (1000, 1.2) # Εντοπισμός σημείων πληκτρολογίου αρχικής εικόνας (kp1, des1) = orb.detectAndCompute (image1, None) # Εντοπισμός σημείων πληκτρολογίου περιστρεφόμενης εικόνας (kp2, des2) = orb.detectAndCompute (image_template, None) # Δημιουργία αντιστοίχισης # Σημειώστε ότι δεν χρησιμοποιούμε πια Flannbasing bf = cv2.BFMatcher (cv2.NORM_HAMMING, crossCheck = True) # Να ταιριάζει με αγώνες = bf.match (des1, des2) # Ταξινόμηση των αγώνων με βάση την απόσταση. Η ελάχιστη απόσταση # είναι καλύτερη αντιστοιχία = ταξινόμηση (αντιστοιχίσεις, κλειδί = λάμδα val: val.distance) επιστροφή len (αγώνες) καπάκι = cv2.VideoCapture (0) # Φορτώστε το πρότυπο εικόνας μας, αυτή είναι η εικόνα αναφοράς μας image_template = cv2.imread ('phone.jpg', 0) # image_template = cv2.imread ('images / kitkat.jpg', 0) ενώ True: # Λήψη εικόνων κάμερας ret, frame = cap.read () # Λήψη ύψους και πλάτους ύψους καρέ κάμερας web , width = frame.shape # Define ROI Box Dimensions (Σημειώστε ότι μερικά από αυτά πρέπει να βρίσκονται εκτός βρόχου) top_left_x = int (width / 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) το παράθυρο # Crop παρατήρησης ορίσαμε παραπάνω περικοπεί = πλαισίου # Flip προσανατολισμό πλαίσιο οριζόντια καρέ = cv2.flip (καρέ, 1) # Λήψη αριθμού αντιστοιχιών ORB αντιστοιχιών = ORB_detector (περικομμένο, image_template) # Εμφάνιση συμβολοσειράς κατάστασης που δείχνει τον τρέχοντα αριθ. των αγώνων output_string = "Matches =" + str ( match) cv2.putText (frame, output_string, (50,450), cv2.FONT_HERSHEY_COMPLEX, 2, (250,0,150), 2) # Το όριό μας για την ένδειξη αντικειμένου deteciton # Για νέες εικόνες ή συνθήκες φωτισμού ίσως χρειαστεί να πειραματιστείτε λίγο # Σημείωση: Ο ανιχνευτής ORB για να πάρει τους κορυφαίους 1000 αγώνες, το 350 είναι ουσιαστικά ένα ελάχιστο όριο αντιστοίχισης 35% = 250 # Εάν οι αγώνες υπερβούν κατώφλι, τότε το αντικείμενο έχει ανιχνευθεί εάν ταιριάζει> κατώφλι: cv2 . ορθογώνιο (καρέ, (top_left_x, top_left_y), (bottom_right_x, bottom_right_y), (0,255,0), 3) cv2.putText (πλαίσιο, "Object Found", (50, 50), cv2.FONT_HERSHEY_COMPLEX, 2, (0,255,0), 2) cv2.imshow ('ανιχνευτής αντικειμένου χρησιμοποιώντας ORB', πλαίσιο) εάν cv2.waitKey (1) == 13: # 13 είναι το πλήκτρο Enter διάλειμμα καπάκι.release () cv2.destroyAllWindows ()
Ιστόγραμμα των προσανατολισμένων ντεγκραντέ (HOG's)
Τώρα ας μιλήσουμε για έναν διαφορετικό περιγραφέα που είναι το Ιστόγραμμα των προσανατολισμένων διαβαθμίσεων (HOG's).
Οι HOG είναι πολύ δροσεροί και χρήσιμοι περιγραφείς και χρησιμοποιούνται ευρέως και επιτυχώς για την ανίχνευση αντικειμένων, όπως είδαμε προηγουμένως οι περιγραφείς εικόνων όπως SIFT και ORB όπου πρέπει να υπολογίσουμε τα πληκτρολόγια και έπειτα να υπολογίσουμε τους περιγραφείς από αυτά τα πληκτρολόγια, οι HOG κάνουν αυτή τη διαδικασία διαφορετικά. Είναι αντιπροσωπεύει αντικείμενα ως ένα ενιαίο διάνυσμα χαρακτηριστικών γνωρισμάτων σε αντίθεση με ένα σύνολο διανυσμάτων χαρακτηριστικών όπου το κάθε ένα παριστά ένα τμήμα της εικόνας. Σημαίνει ότι έχουμε μια μοναδική διανυσματική δυνατότητα για ολόκληρη την εικόνα.
Υπολογίζεται από έναν ανιχνευτή συρόμενων παραθύρων πάνω από μια εικόνα, όπου ένας περιγραφέας HOG υπολογίζεται για κάθε θέση. Και στη συνέχεια κάθε θέση συνδυάζεται για ένα διάνυσμα χαρακτηριστικών.
Όπως το SIFT, η κλίμακα της εικόνας ρυθμίζεται από την πυραμίδα.
Προηγουμένως είχαμε χρησιμοποιήσει αντιστοιχιστές όπως το FLANN και το BFMatcher, αλλά τα HOG το κάνουν διαφορετικά με τη βοήθεια των ταξινομητών SVM (μηχανή φορέα υποστήριξης), όπου κάθε περιγραφέας HOG που υπολογίζεται τροφοδοτείται σε έναν ταξινομητή SVM για να προσδιορίσει εάν το αντικείμενο βρέθηκε ή όχι.
Ακολουθεί ο σύνδεσμος για ένα υπέροχο έγγραφο από τον Dalal & Triggs σχετικά με τη χρήση HOGs για Ανίχνευση Ανθρώπου:
Ιστόγραμμα των προσανατολισμένων ντεγκραντέ (HOG's), βήμα προς βήμα:
Η κατανόηση των HOG μπορεί να είναι αρκετά περίπλοκη, αλλά εδώ θα ασχοληθούμε μόνο με τη θεωρία των HOG χωρίς να προχωρήσουμε βαθύτερα στα μαθηματικά που σχετίζονται με αυτό.
Ας πάρουμε λοιπόν αυτήν την εικόνα, είναι λίγο pixelated και στην επάνω γωνία είναι 8x8 pixel box εδώ, οπότε σε αυτό το πλαίσιο υπολογίζουμε τον κλίση του διανύσματος ή των προσανατολισμών άκρων σε κάθε pixel. Αυτό σημαίνει ότι σε αυτό το πλαίσιο υπολογίζουμε το διάνυσμα διαβάθμισης της εικόνας των εικονοστοιχείων μέσα στο κουτί (είναι είδος κατεύθυνσης ή ροής της ίδιας της έντασης της εικόνας) και αυτό δημιουργεί διανύσματα διαβάθμισης 64 (8 x 8) τα οποία στη συνέχεια αντιπροσωπεύονται ως ιστόγραμμα. Φανταστείτε λοιπόν ένα ιστόγραμμα που αναπαριστά κάθε φορέα κλίσης. Αν λοιπόν όλα τα σημεία ή οι εντάσεις βρίσκονται σε μία κατεύθυνση, το ιστόγραμμα για αυτήν την κατεύθυνση ας πούμε 45 μοίρες, το ιστόγραμμα θα κορυφώθηκε στους 45 μοίρες.
Αυτό που κάνουμε τώρα είναι να χωρίσουμε κάθε κελί σε γωνιακούς κάδους, όπου κάθε κάδος αντιστοιχεί σε κατεύθυνση διαβάθμισης (π.χ. x, y). Στο χαρτί Dalal και Triggs, χρησιμοποίησαν 9 κάδους 0-180 ° (20 ° κάθε κάδο). Αυτό μειώνει αποτελεσματικά 64 διανύσματα σε μόλις 9 τιμές. Έτσι, αυτό που κάναμε είναι να μειώσουμε το μέγεθος αλλά να διατηρήσουμε όλες τις βασικές πληροφορίες που χρειάζονται.
Το επόμενο βήμα στον υπολογισμό του γουρούνι είναι η ομαλοποίηση, ομαλοποιούμε τις κλίσεις για να διασφαλίσουμε την αμετάβλητη στις αλλαγές φωτισμού, δηλαδή Φωτεινότητα και Αντίθεση.
Σε αυτήν την εικόνα, οι τιμές έντασης εμφανίζονται στο τετράγωνο σύμφωνα με την αντίστοιχη κατεύθυνση και όλες έχουν διαφορά 50 μεταξύ τους
Δ H = 50, Δ v = 50; │Δ│ = √50 2 +50 = 70,72, 70,72 / 100 = 0,707
Διαιρούμε τα διανύσματα με τα μεγέθη κλίσης που έχουμε 0,707 για όλους, αυτό είναι κανονικοποίηση.
Παρομοίως, αν αλλάξουμε την ένταση ή αλλάξουμε την αντίθεση παίρνουμε τις παρακάτω τιμές.
Δ 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
Η κανονικοποίηση δεν πραγματοποιείται σε επίπεδο κελιού, αλλά πραγματοποιείται σε επίπεδο μπλοκ, οπότε εδώ τα μπλοκ είναι βασικά μια ομάδα 4 κελιών, αυτό λαμβάνει υπόψη γειτονικά μπλοκ, έτσι ομαλοποιείται λαμβάνοντας υπόψη μεγαλύτερα τμήματα της εικόνας.
Τώρα ας δούμε τον κώδικα
import numpy as np import cv2 import matplotlib.pyplot as plt # Load image and then grayscale image = cv2.imread ('elephant.jpg') grey = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # Εμφάνιση αρχικής εικόνας cv2.imshow (' Input Image ', image) cv2.waitKey (0) # καθορισμός παραμέτρων, μέγεθος κελιού και μέγεθος μπλοκ # hxw σε pixel cell_size = (8, 8) # hxw σε κελιά block_size = (2, 2) # αριθμός κάδων προσανατολισμού nbins = 9 # Χρησιμοποιώντας το OpenCV HOG Descriptor # winSize είναι το μέγεθος της εικόνας που περικόπτεται σε πολλαπλάσιο του μεγέθους κελιού hog = cv2.HOGDescriptor (_winSize = (grey.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 array για να δημιουργήσετε hog_features n_cells = (grey.shape // cell_size, grey.shape // cell_size) # Έχουμε δείξει πρώτα μπλοκ κατά σειρές. Το # hog_feats περιέχει τώρα τα πλάτη κλίσης για κάθε κατεύθυνση, # για κάθε κελί της ομάδας του για κάθε ομάδα. Η ευρετηρίαση γίνεται κατά σειρές και μετά στήλες. hog_feats = hog.compute (γκρι). σχήμα (n_cells - block_size + 1, n_cells - block_size + 1, block_size, block_size, nbins).transpose ((1, 0, 2, 3, 4)) # Δημιουργήστε τον πίνακα διαβαθμίσεων με διαστάσεις nbin για να αποθηκεύσετε κλίσεις προσανατολισμού ντεγκραντέ = np.zeros ((n_cells, n_cells, nbins)) # Δημιουργία σειρά διαστάσεων cell_count = np.full ((n_cells, n_cells, 1), 0, dtype = int) # Κανονικοποίηση μπλοκ για off_y στο εύρος (block_size): για off_x στο εύρος (block_size): κλίσεις - 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 # Μέσος όρος ντεγκραντέ / / cell_count # Plot HOGs χρησιμοποιώντας το Matplotlib # η γωνία είναι 360 / nbins * color_bins διεύθυνση = 5 plt.pcolor (ντεγκραντέ) plt.gca (). invert_yaxis () plt.gca (). set_aspect ('ίση', 'κουτί' ρυθμιζόμενο =) plt.colorbar () plt.show () cv2.destroyAllWindows ()
Η εικόνα δείχνει πώς η εικόνα εισόδου αντιπροσωπεύεται ως αναπαράσταση HOG.
Ταξινομητές καταρράκτη HAAR
Όπως συζητήθηκε προηγουμένως, μπορούμε να εξαγάγουμε χαρακτηριστικά από μια εικόνα και να χρησιμοποιήσουμε αυτές τις δυνατότητες για την ταξινόμηση ή τον εντοπισμό αντικειμένων.
Τι είναι οι ταξινομητές HAAR Cascade;
Μια μέθοδος ανίχνευσης αντικειμένων που εισάγει χαρακτηριστικά του Haar σε μια σειρά κατηγοριοποιητών (cascade) για την αναγνώριση αντικειμένων σε μια εικόνα. Εκπαιδεύονται για να αναγνωρίσουν έναν τύπο αντικειμένου, ωστόσο, μπορούμε να χρησιμοποιήσουμε πολλά από αυτά παράλληλα, π.χ. ανίχνευση ματιών και προσώπων μαζί.
Οι ταξινομητές HAAR εξήγησαν:
Οι ταξινομητές HAAR εκπαιδεύονται χρησιμοποιώντας πολλές θετικές εικόνες (π.χ. εικόνες με το αντικείμενο που υπάρχει) και
αρνητικές εικόνες (δηλαδή εικόνες χωρίς το αντικείμενο που υπάρχει).
Μόλις έχουμε αυτές τις εικόνες, στη συνέχεια εξάγουμε χαρακτηριστικά χρησιμοποιώντας συρόμενα παράθυρα ορθογώνιων μπλοκ. Αυτά τα χαρακτηριστικά (χαρακτηριστικά HAAR) είναι μοναδικής αξίας και υπολογίζονται αφαιρώντας το άθροισμα των εντάσεων pixel κάτω από τα λευκά ορθογώνια από τα μαύρα ορθογώνια.
Ωστόσο, πρόκειται για έναν γελοίο αριθμό υπολογισμών, ακόμη και για ένα βασικό παράθυρο 24 x 24 pixel (δημιουργήθηκαν 180.000 χαρακτηριστικά).
Έτσι, οι ερευνητές επινόησαν μια μέθοδο που ονομάζεται Integral Images που την υπολόγισε με τέσσερις αναφορές πίνακα. Ωστόσο, είχαν ακόμα 180.000 χαρακτηριστικά και η πλειοψηφία τους δεν είχε καμία πραγματική αξία.
Ενίσχυση στη συνέχεια χρησιμοποιήθηκε για τον προσδιορισμό των πιο κατατοπιστική χαρακτηριστικά, με Freund & Schapire του AdaBoost και βρήκε πιο κατατοπιστική χαρακτηριστικά στην εικόνα. Η ενίσχυση είναι η διαδικασία με την οποία χρησιμοποιούμε αδύναμους ταξινομητές για να δημιουργήσουμε ισχυρούς ταξινομητές, απλώς αναθέτοντας βαρύτερες ποινές σε εσφαλμένες ταξινομήσεις. Μειώνοντας τις 180.000 δυνατότητες σε 6000, κάτι που εξακολουθεί να είναι αρκετά χαρακτηριστικά.
Σε αυτά τα 6000 χαρακτηριστικά, μερικά θα είναι πιο ενημερωτικά από άλλα. Έτσι, εάν χρησιμοποιήσαμε τις πιο ενημερωτικές δυνατότητες για να ελέγξουμε πρώτα εάν η περιοχή μπορεί ενδεχομένως να έχει πρόσωπο (τα ψευδώς θετικά δεν θα είναι μεγάλη υπόθεση) Με αυτόν τον τρόπο εξαλείφεται η ανάγκη υπολογισμού και των 6000 δυνατοτήτων ταυτόχρονα. Αυτή η ιδέα ονομάζεται Cascade of Classifiers - για την ανίχνευση προσώπου, η μέθοδος Viola Jones χρησιμοποίησε 38 στάδια.
Ανίχνευση προσώπου και ματιών
Έτσι, αφού αποκτήσουμε κάποια θεωρητική γνώση για τους καταρράκτες HAAR, θα το εφαρμόσουμε επιτέλους, έτσι ώστε να κάνουμε τα πράγματα αρκετά ξεκάθαρα ότι θα σπάσουμε τα μαθήματα σε τμήματα, πρώτα θα ανιχνεύσουμε μετωπικό πρόσωπο μετά από αυτό θα κινηθούμε για να ανιχνεύσουμε μετωπικό πρόσωπο με μάτια και τέλος θα κάνουμε ζωντανή ανίχνευση προσώπου και ματιών μέσω της κάμερας web.
Έτσι, για αυτό θα χρησιμοποιήσουμε προ-εκπαιδευμένους ταξινομητές που έχουν παρασχεθεί από το OpenCV ως αρχεία.xml, το xml σημαίνει επεκτάσιμη γλώσσα σήμανσης, αυτή η γλώσσα χρησιμοποιείται για την αποθήκευση τεράστιου όγκου δεδομένων, θα μπορούσατε ακόμη και να δημιουργήσετε μια βάση δεδομένων σε αυτήν.
Μπορείτε να έχετε πρόσβαση σε αυτούς τους ταξινομητές σε αυτόν τον σύνδεσμο .
Ανίχνευση προσώπου
Ας προσπαθήσουμε για την ανίχνευση μετωπικού προσώπου, μπορείτε να έχετε πρόσβαση για τον καταρράκτη του ανιχνευτή μετωπικού προσώπου εδώ. Απλώς εξαγάγετε το αρχείο zip για να λάβετε το αρχείο xml.
import numpy as np import cv2 # Δείχνουμε τη συνάρτηση CascadeClassifier του OpenCV στο σημείο όπου είναι αποθηκευμένο το # classifier (μορφή αρχείου XML), θυμηθείτε να διατηρήσετε τον κωδικό και τον ταξινομητή στον ίδιο φάκελο face_cascade = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') # Load η εικόνα μας, στη συνέχεια, μετατρέψτε την σε κλίμακα του γκρι εικόνα = cv2.imread ('Trump.jpg') γκρι = cv2.cvtColor (εικόνα, cv2.COLOR_BGR2GRAY) # Ο ταξινομητής μας επιστρέφει την απόδοση επένδυσης που εντοπίστηκε ως πλειάδα # Αποθηκεύει την επάνω αριστερή γωνία συντεταγμένες και κάτω δεξιά συντεταγμένες # επιστρέφει τη λίστα των λιστών, οι οποίες είναι η θέση των διαφορετικών προσώπων που εντοπίστηκαν. face = face_cascade.detectMultiScale (γκρι, 1,3, 5) # Όταν δεν εντοπίζονται πρόσωπα, το face_classifier επιστρέφει και αδειάζει η πλειάδα αν είναι τα πρόσωπα (): εκτύπωση ("Δεν βρέθηκαν πρόσωπα") # Κάνουμε επανάληψη μέσω της σειράς προσώπων και σχεδιάζουμε ένα ορθογώνιο # πάνω από κάθε πρόσωπο σε πρόσωπα για h) σε πρόσωπα: cv2 . ορθογώνιο (εικόνα, (x, y), (x + w, y + h), (127,0,255), 2) cv2.imshow («Face Detection», εικόνα) cv2.waitKey (0) cv2.destroyAllWindows ()
Τώρα ας συνδυάσουμε την ανίχνευση προσώπου και ματιών μαζί, μπορείτε να έχετε πρόσβαση για τον καταρράκτη του ανιχνευτή ματιών στο ίδιο αρχείο zip.
import numpy as np import cv2 face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') img = cv2.imread ('Trump.jpg') γκρι = cg cv2.COLOR_BGR2GRAY) face = face_classifier.detectMultiScale (grey, 1.3, 5) # Όταν δεν εντοπίζονται πρόσωπα, το face_classifier επιστρέφει και άδειο πλειάδα αν τα πρόσωπα είναι (): print ("No Face Found") για (x, y, w, h) σε πρόσωπα: cv2 . ορθογώνιο (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) για (π.χ., ey, ew, eh) στα μάτια: cv2. ορθογώνιο (roi_color, (ex, ey), (ex + ew, ey + eh), (255,255,0), 2) cv2.imshow ('img', img) cv2.waitKey (0) cv2.destroyAllWindows () cv2.waitKey (0)
Επομένως, αυτός ο κώδικας είναι ίδιος με εκείνος του κωδικού για την ανίχνευση προσώπου, αλλά εδώ έχουμε προσθέσει καταρράκτες ματιών και μέθοδο για τον εντοπισμό τους, όπως μπορείτε να δείτε ότι επιλέξαμε την γκρι κλιμακωτή έκδοση του προσώπου ως την παράμετρο για την ανίχνευσηMultiScale για τα μάτια, που μας φέρνουν στη μείωση του υπολογισμού, καθώς θα εντοπίσουμε μόνο τα μάτια μόνο σε αυτήν την περιοχή.
Ζωντανή ανίχνευση προσώπου και ματιών
Έτσι, μέχρι τώρα έχουμε κάνει ανίχνευση προσώπου και ματιών, τώρα ας εφαρμόσουμε το ίδιο με τη ζωντανή ροή βίντεο από την κάμερα web. Σε αυτό θα κάνουμε την ίδια ανίχνευση προσώπου και ματιών, αλλά αυτή τη φορά θα το κάνουμε για τη ζωντανή ροή από την κάμερα. Στις περισσότερες από τις εφαρμογές θα βρείτε το πρόσωπό σας επισημασμένο με ένα κουτί γύρω του, αλλά εδώ έχουμε κάνει κάτι διαφορετικό που θα βρείτε το πρόσωπό σας περικομμένο και τα μάτια θα ταυτίζονταν μόνο σε αυτό.
Έτσι εδώ εισάγουμε τόσο τον ταξινομητή προσώπου όσο και τον οφθαλμό, και ορίσαμε μια λειτουργία για να κάνουμε όλη την επεξεργασία για την ανίχνευση προσώπου και ματιών. Και μετά από αυτό ξεκίνησε η ροή της κάμερας web και κάλεσε τη λειτουργία ανιχνευτή προσώπου για να εντοπίσει το πρόσωπο και τα μάτια. Η παράμετρος που ορίζουμε μέσα στη λειτουργία ανιχνευτή προσώπου είναι οι συνεχείς εικόνες από τη ζωντανή ροή κάμερας web
cv2 εισαγωγής εισαγωγής NumPy ως np face_classifier = cv2.CascadeClassifier ('haarcascade_frontalface_default.xml') eye_classifier = cv2.CascadeClassifier ('haarcascade_eye.xml') def face_detector (img, μέγεθος = 0,5): # Μετατροπή εικόνας σε κλίμακα του γκρι γκρι = cv2.cvtColor (img, cv2.COLOR_BGR2GRAY) πρόσωπα = face_classifier.detectMultiScale (γκρι, 1.3, 5) εάν τα πρόσωπα είναι (): επιστροφή img για (x, y, w, h) σε πρόσωπα: x = x - 50 w = w + 50 y = y - 50 h = h + 50 cv2. ορθογώνιο (img, (x, y), (x + w, y + h), (255,0,0), 2) roi_gray = γκρι roi_color = img eyes = eye_classifier.detectMultiScale (roi_gray) για (π.χ., ey, ew, eh) στα μάτια: cv2. ορθογώνιο (roi_color, (ex, ey), (ex + ew, ey + eh), (0,0,255), 2) roi_color = cv2.flip (roi_color, 1) return roi_color cap = cv2.VideoCapture (0) ενώ True: ret, frame = cap.read () cv2.imshow ('Our Face Extractor', face_detector (frame)) if cv2.waitKey (1) == 13: # 13 είναι το Enter Key break cap.release () cv2.destroyAllWindows ()
Συντονιστές Cascade Classifiers
Οι παράμετροι που καθορίζονται στο ανίχνευσηultiScale εκτός από την εικόνα εισόδου έχουν την ακόλουθη σημασία
μαςClassifier. DetectMultiScale (εικόνα εισόδου, Παράγοντας κλίμακας, Ελάχιστοι γείτονες)
- Scale Factor Καθορίζει πόσο μειώνουμε το μέγεθος της εικόνας κάθε φορά που κάνουμε κλίμακα. Π.χ. στην ανίχνευση προσώπου συνήθως χρησιμοποιούμε 1.3. Αυτό σημαίνει ότι μειώνουμε την εικόνα κατά 30% κάθε φορά που κλιμακώνεται. Οι μικρότερες τιμές, όπως το 1.05, θα χρειαστούν περισσότερο χρόνο για τον υπολογισμό, αλλά θα αυξήσουν το ρυθμό ανίχνευσης.
- Min Neighbours Καθορίζει τον αριθμό των γειτόνων που πρέπει να έχει κάθε πιθανό παράθυρο για να το θεωρήσει θετικό. Συνήθως ορίζεται μεταξύ 3-6. Λειτουργεί ως ρύθμιση ευαισθησίας, οι χαμηλές τιμές μερικές φορές εντοπίζουν πολλαπλά πρόσωπα σε ένα μόνο πρόσωπο. Οι υψηλές τιμές θα εξασφαλίσουν λιγότερο ψευδώς θετικά, αλλά μπορεί να χάσετε κάποια πρόσωπα.
Ανίχνευση αυτοκινήτου και πεζών σε βίντεο
Τώρα θα εντοπίσουμε πεζούς και αυτοκίνητα σε βίντεο χρησιμοποιώντας τους καταρράκτες HAAR, αλλά στην περίπτωση που δεν φορτώνεται βίντεο και μεταγλωττίζεται κώδικας χωρίς σφάλμα πρέπει να ακολουθήσετε τα ακόλουθα βήματα:
Εάν δεν φορτωθεί βίντεο μετά την εκτέλεση κώδικα, ίσως χρειαστεί να αντιγράψετε το opencv_ffmpeg.dl από : opencv \ source \ 3rdparty \ ffmpeg για να το επικολλήσετε όπου είναι εγκατεστημένο το python σας π.χ. C: \ Anaconda2
Μόλις αυτό αντιγράφεται θα πρέπει να μετονομάσετε το αρχείο, σύμφωνα με την έκδοση του 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, απλώς εκτελέστε αυτές τις δύο γραμμές κώδικα, θα εκτυπώσει τη θέση όπου είναι εγκατεστημένο το python.
εισαγωγή sys print (sys.executable)
Τώρα αν έχετε κάνει αυτά τα βήματα με επιτυχία, ας προχωρήσουμε στον κώδικα για την ανίχνευση πεζών, Μπορείτε να έχετε τον καταρράκτη για ανίχνευση πεζών και από το αρχείο zip που επισυνάπτεται εδώ.
import cv2 import numpy as np # Create our body classifier body_classifier = cv2.CascadeClassifier ('haarcascade_fullbody.xml') # Ξεκινήστε τη λήψη βίντεο για αρχείο βίντεο, εδώ χρησιμοποιούμε το αρχείο βίντεο στο οποίο θα ανιχνεύονταν οι πεζοί cap = cv2.VideoCapture ('walking.avi') # Loop μόλις φορτωθεί επιτυχώς το βίντεο ενώ το cap.isOpened (): # Διαβάζοντας κάθε καρέ του βίντεο ret, frame = cap.read () # εδώ αλλάζουμε το μέγεθος του καρέ, στο μισό του μεγέθους του, κάνουμε να επιταχύνουμε την ταξινόμηση # καθώς οι μεγαλύτερες εικόνες έχουν πολύ περισσότερα παράθυρα για να γλιστρήσουν, οπότε γενικά μειώνουμε την ανάλυση # από το βίντεο κατά το ήμισυ αυτό δείχνει το 0,5 και χρησιμοποιούμε επίσης τη μέθοδο ταχύτερης παρεμβολής που είναι #interlinear frame = cv2.resize (frame, None, fx = 0.5, fy = 0.5, interpolation = 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 Key break cap.release () cv2.destroyAllWindows ()
Μετά την επιτυχή ανίχνευση πεζών σε βίντεο, ας προχωρήσουμε στον κώδικα για την ανίχνευση αυτοκινήτου, Μπορείτε να έχετε τον καταρράκτη για ανίχνευση πεζών από εδώ.
import cv2 import time import numpy as np # Create our body classifier car_classifier = cv2.CascadeClassifier ('haarcascade_car.xml') # Ξεκινήστε τη λήψη βίντεο για καπάκι αρχείου βίντεο = cv2.VideoCapture ('cars.avi') # Loop μόλις το βίντεο είναι επιτυχές φορτωμένο ενώ cap.isOpened (): time.sleep (.05) # Read first frame ret, frame = cap.read () grey = cv2.cvtColor (frame, cv2.COLOR_BGR2GRAY) # Περάστε το πλαίσιο στους ταξινομητές αυτοκινήτων μας αυτοκίνητα = car_classifier.detectMultiScale (γκρι, 1.4, 2) # Εξαγάγετε οριοθετημένα κουτιά για τυχόν αμαξώματα που προσδιορίζονται για (x, y, w, h) σε αυτοκίνητα: cv2 . ορθογώνιο (πλαίσιο, (x, y), (x + w, y + h), (0, 255, 255), 2) cv2.imshow ('Cars', frame) if cv2.waitKey (1) == 13: # 13 είναι το Enter Key break cap.release () cv2.destroyAllWindows ()
Έχετε παρατηρήσει ότι έχουμε προσθέσει το time.sleep (.05) , είναι απλώς μια καθυστέρηση στο ρυθμό καρέ, ώστε να μπορείτε να επιβεβαιώσετε ότι όλα τα αυτοκίνητα αναγνωρίζονται σωστά ή μπορείτε εύκολα να το αφαιρέσετε απλά προσθέτοντας μια ετικέτα σχολίου σε αυτό.
Αυτό το άρθρο αναφέρεται από το Master Computer Vision ™ OpenCV4 στο Python with Deep Learning course on Udemy, δημιουργήθηκε από τον Rajeev Ratan, εγγραφείτε για να μάθετε περισσότερα για το Computer Vision και το Python.