Τι είναι όλη η φασαρία για τα χαρακτηριστικά;
Τα χαρακτηριστικά είναι ενδιαφέρουσες πτυχές ή ιδιότητες ενός πράγματος. Όταν διαβάζουμε μια ιστορία, η αίθουσα ειδήσεων πιστεύει ότι θα είναι η πιο ενδιαφέρουσα, συναρπαστική ιστορία που προσελκύει θεατές. Ομοίως, όταν κοιτάμε μια εικόνα ή μια μικρογραφία στο Youtube, διάφορες πτυχές αυτής της φωτογραφίας ή του βίντεο τείνουν να μας ελκύουν. Με τα χρόνια (χιλιάδες χρόνια), οι άνθρωποι έχουν γίνει αρκετά καλοί στο να συλλέγουν οπτικές ενδείξεις. Οι πρόγονοί μας έπρεπε να μείνουν μακριά από τον κίνδυνο, να προστατεύσουν τις σπηλιές τους από τους εχθρούς, να εντοπίζουν καλές και κακές προθέσεις από τη φαρέτρα του χείλους και να διαβάζουν κάθε είδους γλώσσα του σώματος από χειρονομίες και χορούς.
Σήμερα, δεν είναι πολύ διαφορετικό, εκτός από το ότι διδάσκουμε στους υπολογιστές να εντοπίζουν μερικές από τις ίδιες ενδείξεις. Στην όραση υπολογιστή, τα χαρακτηριστικά είναι χαρακτηριστικά σε μια εικόνα ή ένα βίντεο που θα θέλαμε να απομονώσουμε ως σημαντικά. Ένα χαρακτηριστικό μπορεί να είναι το στόμα, η μύτη, τα αυτιά, τα πόδια ή τα πόδια ενός προσώπου, οι γωνίες ενός πορτρέτου, η οροφή ενός σπιτιού ή το καπάκι ενός μπουκαλιού.
Είναι μια ενδιαφέρουσα περιοχή και ένα εικονοστοιχείο σε κλίμακα του γκρι που αποτελεί μόνο ένα μικροσκοπικό τμήμα μιας ολόκληρης φωτογραφίας δεν θα μας πει πολλά. Αντίθετα, αναζητούμε μια συλλογή από αυτά τα pixel σε μια δεδομένη περιοχή ενδιαφέροντος. Εάν μια εικόνα μπορεί να υποβληθεί σε επεξεργασία, τότε σίγουρα μπορούμε να απομονώσουμε περιοχές αυτής της φωτογραφίας για περαιτέρω επιθεώρηση και να την αντιστοιχίσουμε με παρόμοια ή ακριβή αντικείμενα – και αυτό πρόκειται να εξερευνήσουμε.
Τύποι Ανίχνευσης
Όλοι πρέπει να γνωρίζουμε τη δύναμη που φέρνει στο τραπέζι το OpenCV και δεν υστερεί στις μεθόδους ανίχνευσης χαρακτηριστικών του. Υπάρχει Χάρις ανίχνευση γωνίας, Ανίχνευση γωνίας Shi-Tomasi, Scale-Invariant Feature Transformation (SIFT)και Ισχυρές δυνατότητες επιτάχυνσης (SURF), για να αναφέρουμε μερικά. Ο Harris και ο Shi-Tomasi έχουν και οι δύο διαφορετικούς τρόπους ανίχνευσης γωνιών και η χρήση του ενός έναντι του άλλου εξαρτάται κυρίως από τις προσωπικές προτιμήσεις. Χρησιμοποιήστε τα και βρείτε όσα κουτιά και πορτρέτα θέλετε σε εικόνες και βίντεο, αλλά αναζητούμε τους μεγάλους μεσίτες. Θα χρησιμοποιήσουμε το SIFT σε αυτό το παράδειγμα και το SURF λειτουργεί εξαιρετικά, αλλά όχι σήμερα φίλοι μου.
Τόσο το SURF όσο και το SIFT λειτουργούν ανιχνεύοντας σημεία ενδιαφέροντος και στη συνέχεια σχηματίζοντας έναν περιγραφέα των εν λόγω σημείων. Αν θέλετε την τεχνική εξήγηση του SIFT, ρίξτε μια ματιά στην πηγή. Η εξήγηση πηγαίνει σε βάθος σχετικά με το πώς αυτός ο τύπος ανίχνευσης και αντιστοίχισης χαρακτηριστικών έχει αρκετή στιβαρότητα για να χειριστεί τις μεταβαλλόμενες συνθήκες φωτισμού, προσανατολισμούς, γωνίες κ.λπ. Όμορφο, όμορφο…πολύ καλό υλικό.
Βασικά
Η βασική ροή εργασίας που θα χρησιμοποιήσουμε είναι να τραβήξουμε μια εικόνα, να εντοπίσουμε αυτόματα χαρακτηριστικά που θα κάνουν αυτό το αντικείμενο μοναδικό από παρόμοια αντικείμενα, να προσπαθήσουμε να περιγράψουμε αυτά τα χαρακτηριστικά και, στη συνέχεια, να συγκρίνουμε αυτά τα μοναδικά χαρακτηριστικά (αν βρεθούν) με μια άλλη εικόνα ή βίντεο που περιέχει την αρχική εικόνα/βίντεο, ίσως σε ομάδα για να το κάνει πιο δύσκολο. Φανταστείτε, αν πληκτρολογούσαμε μια συγκεκριμένη μάρκα και μοντέλο αυτοκινήτου, ρυθμίζαμε μια κάμερα και περιμέναμε να δούμε αν και πότε αυτό το αυτοκίνητο εμφανίστηκε ξανά μπροστά στο σπίτι μας. Θα μπορούσατε να δημιουργήσετε ένα δίκτυο καμερών για να αναζητήσετε έναν αγνοούμενο ή να πληκτρολογήσετε μια εικόνα ενός χαμένου ποδηλάτου για κάμερες γύρω από μια πανεπιστημιούπολη κολεγίου. Απλώς βεβαιωθείτε ότι το κάνετε σύμφωνα με τους νόμους της δικαιοδοσίας σας, φυσικά.
Το μεγαλύτερο μέρος της εργασίας για την αντιστοίχιση βασισμένων χαρακτηριστικών διεκπεραιώνεται από μια έκδοση του ταξινομητή ομαδοποίησης χωρίς επίβλεψη, τον αλγόριθμο k-Nearest Neighbor (kNN). Στο παράδειγμά μας, εκπαιδεύουμε ένα μοντέλο kNN για να ανιχνεύει περιγραφείς από την αρχική εικόνα εκπαίδευσης και, στη συνέχεια, χρησιμοποιούμε ένα σύνολο ερωτημάτων για να δούμε αν βρίσκουμε αντιστοιχίες.
Πόροι εξερεύνησης και λήψης κώδικα
Εδώ είναι η αρχική μας εικόνα για αρχή. Αυτή η πεταλούδα είναι γνωστή ως ο Πορφυρός Αυτοκράτορας, και είναι όμορφη, ω ναι. Και τρέφεται επίσης με σάρκα που σαπίζει. Να είστε θαυμαστής όταν χτενίζετε τη βρετανική ύπαιθρο, αλλά όχι πολύ κοντά. Γεμάτος Μπορείτε να κατεβάσετε τον κώδικα και τους πόρους εδώ.
Χρησιμοποιήστε Python 3 αν μπορείτε, εγκατάσταση OpenCV (3+ αν είναι δυνατόν) και το συνηθισμένο Numpy και Matplotlib. Μπορεί να χρειαστεί να εγκαταστήσετε μαζί με το OpenCV, opencv-contrib. Στην περίπτωσή μου χρησιμοποιώντας Python 3+, είχα εγκαταστήσει το OpenCV αν και το Homebrew σε εγκατάσταση Mac/Linux και έπρεπε να βρω έναν εναλλακτικό τρόπο για να επικαλεστώ την εντολή SIFT:
import cv2
import matplotlib.pyplot as plt
import numpy as np
n_kp = 100 #limit the number of possible matches
# Initiate SIFT detector
#sift = cv2.SIFT() #in Python 2.7 or earlier?
sift = cv2.xfeatures2d.SIFT_create(n_kp)
Εάν εξακολουθείτε να αντιμετωπίζετε προβλήματα με τον διερμηνέα σας να αναγνωρίσει το SIFT, δοκιμάστε να χρησιμοποιήσετε τη γραμμή εντολών ή το τερματικό της Python και να καλέσετε αυτήν τη συνάρτηση:
>>help(cv2.xfeatures2d)
Στη συνέχεια, βγείτε και εκτελέστε αυτές τις γραμμές για να δείτε αν όλα είναι ελεγμένα:
>>import cv2
>>>image = cv2.imread("any_test_image.jpg")
>>>sift = cv2.xfeatures2d.SIFT_create()
>>>(kps, descs) = sift.detectAndCompute(gray, None)
>>>print("# kps: {}, descriptors: {}".format(len(kps), des
cs.shape))
Εάν λάβετε απάντηση και όχι μήνυμα σφάλματος, είστε έτοιμοι. Έχω ορίσει τον αριθμό των πιθανών αντιστοιχίσεων χαρακτηριστικών σε 100 με τη μεταβλητή n_kp , έστω και μόνο για να κάνω την τελική μας απόδοση πιο ευχάριστη οπτικά. Δοκιμάστε το χωρίς αυτήν την παράμετρο – είναι άσχημο, αλλά σας δίνει μια αίσθηση όλων των χαρακτηριστικών που ταιριάζουν. μερικά είναι πιο ακριβή από άλλα.
MIN_MATCHES = 10
img1 = cv2.imread('butterfly_orig.png',0) # queryImage
img2 = cv2.imread('butterflies_all.png',0) # trainImage
# find the keypoints and descriptors with SIFT
keyp1, desc1 = sift.detectAndCompute(img1,None)
keyp2, desc2 = sift.detectAndCompute(img2,None)
FLANN_INDEX_KDTREE = 0
src_params = dict(checks = 50)
idx_params = dict(algorithm = FLANN_INDEX_KDTREE, trees =
5)
Με το σύνολο των εικόνων εκπαίδευσης και δοκιμής, αποστέλλουμε SIFT από τις λειτουργίες ανίχνευσης. Ρυθμίσαμε MIN_MATCHES έως 10, που σημαίνει ότι θα χρειαστούμε τουλάχιστον 10 από τις 100 μέγιστες πιθανές αντιστοιχίσεις για να ανιχνευθούν για να τις αποδεχθούμε ως αναγνωρίσιμα χαρακτηριστικά. Χρησιμοποιώντας τον ταξινομητή Fast Library for Approximate Nearest Neighbors (FLANN), θέλουμε τώρα να αναζητήσουμε πραγματικά αναγνωρίσιμα μοτίβα μεταξύ του αρχικού συνόλου εκπαίδευσης και της εικόνας στόχου μας. Αρχικά, δημιουργήσαμε ευρετήριο idx_params και αναζήτηση src_params και θα εκτελέσουμε τη μέθοδο FlannBasedMatcher για να εκτελέσουμε μια γρήγορη αναζήτηση για να προσδιορίσουμε τις αντιστοιχίσεις.
flann = cv2.FlannBasedMatcher(idx_params, src_params)
matches = flann.knnMatch(desc1,desc2,k=2)
# only good matches using Lowe's ratio test
good_matches = []
for m,n in matches:
if m.distance < 0.7*n.distance:
#good_matches = filter(lambda x: x[0].distance<0.7
*x[1].distance,m)
good_matches.append(m)
Έχουμε επίσης αποθηκεύσει σε σπίρτα , μια σειρά από περιγραφείς και από τις δύο εικόνες για να δούμε αν ταιριάζουν. Από flann.knnΤαίριασμα θα καταλήξει σε μια λίστα με κοινά σημεία μεταξύ των δύο συνόλων περιγραφών. Λάβετε υπόψη ότι όσο περισσότερες αντιστοιχίσεις βρεθούν μεταξύ του σετ εκπαίδευσης και ερωτήματος (εικόνα στόχου), τόσο πιο πιθανό είναι το προπονητικό μας μοτίβο να έχει βρεθεί στην εικόνα-στόχο μας. Φυσικά, δεν θα ευθυγραμμιστούν με ακρίβεια όλα τα χαρακτηριστικά. Συνηθίζαμε k=2 για την παράμετρό μας k, και αυτό σημαίνει ότι ο αλγόριθμος αναζητά τους δύο πλησιέστερους περιγραφείς για κάθε αντιστοίχιση.
Πάντα, μία από αυτές τις δύο αντιστοιχίσεις θα είναι πιο μακριά από τη σωστή αντιστοίχιση, επομένως για να φιλτράρουμε τις χειρότερες αντιστοιχίσεις και να φιλτράρουμε τις καλύτερες, έχουμε ρυθμίσει μια λίστα και έναν βρόχο για να συλλάβουμε τα good_match . Χρησιμοποιώντας τη δοκιμή αναλογίας Lowe, μια καλή αντιστοιχία εμφανίζεται όταν ο λόγος των αποστάσεων μεταξύ του πρώτου και του δεύτερου αγώνα είναι μικρότερος από έναν ορισμένο αριθμό – σε αυτήν την περίπτωση 0,7.
Τώρα βρήκαμε τα σημεία-κλειδιά που ταιριάζουν καλύτερα, αν υπάρχουν, και τώρα πρέπει να τα επαναλάβουμε και να κάνουμε διασκεδαστικά πράγματα όπως να σχεδιάζουμε κύκλους και γραμμές μεταξύ των βασικών σημείων, ώστε να μην μπερδευτούμε με αυτό που ψάχνουμε στο.
if len(good_matches)>MIN_MATCHES:
src_pts = np.float32([ keyp1[m.queryIdx].pt for m in g
ood_matches ]).reshape(-1,1,2)
train_pts = np.float32([ keyp2[m.trainIdx].pt for m in
good_matches ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, train_pts, cv2.R
ANSAC,5.0)
matchesMask = mask.ravel().tolist()
h,w = img1.shape
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).
reshape(-1,1,2)
dst = cv2.perspectiveTransform(pts,M)
img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3,
cv2.LINE_AA)
else:
print("Not enough matches have been found - {}/{}".for
mat(len(good_matches),MIN_MATCHES))
matchesMask = None
draw_params = dict(matchColor = (0,0,255), singlePointColo
r = None,matchesMask = matchesMask,flags = 2)
img3 = cv2.drawMatches(img1,keyp1,img2,keyp2,good_matches,
None,**draw_params)
plt.imshow(img3, 'gray'),plt.show()
Αποθηκεύουμε src_pts και τρένο_πόντους , όπου κάθε αντιστοίχιση, m , είναι ένας χώρος αποθήκευσης του ευρετηρίου των λιστών βασικών σημείων. Το m.queryIdx αναφέρεται στο ευρετήριο των βασικών σημείων του ερωτήματος και το m.trainIdx αναφέρεται στο ευρετήριο των βασικών σημείων εκπαίδευσης στο keyp2 λίστα. Έτσι, οι λίστες μας και τα αντίστοιχα βασικά σημεία αποθηκεύονται, αλλά τι είναι αυτό cv2.findHomography ? Αυτή η μέθοδος κάνει την αντιστοίχιση μας πιο ισχυρή, βρίσκοντας τη μήτρα μετασχηματισμού ομογραφίας μεταξύ των σημείων χαρακτηριστικών. Έτσι, εάν η εικόνα-στόχος μας είναι παραμορφωμένη ή έχει διαφορετική προοπτική μεταμόρφωση από την κάμερα ή με άλλο τρόπο, μπορούμε να φέρουμε τα επιθυμητά σημεία χαρακτηριστικών στο σωστό επίπεδο ως την εικόνα προπόνησής μας.
Το RANSAC σημαίνει Τυχαίο δείγμα συναίνεσης, και περιλαμβάνει κάποια βαριά ανύψωση, σύμφωνα με την οποία η εικόνα της προπόνησης χρησιμοποιείται για να προσδιοριστεί πού μπορεί να βρίσκονται αυτά τα ίδια χαρακτηριστικά που ταιριάζουν στη νέα εικόνα που μπορεί να έχουν συστραφεί, κλίση, παραμορφωθεί ή με άλλο τρόπο μεταμορφωθεί. Οι καλύτερες αντιστοιχίσεις μετά από οποιουσδήποτε μετασχηματισμούς είναι γνωστές ως inliers και αυτές που δεν έκαναν το cut ονομάζονται outliers. Και πάλι, αν αφιερώσετε λίγο χρόνο για να το σκεφτείτε αυτό, η δύναμη της ανίχνευσης χαρακτηριστικών μετά από σημαντικούς μετασχηματισμούς είναι αρκετά ενδιαφέρουσα…ίσως λίγο πολύ ενδιαφέρουσα.
Στη συνέχεια σχεδιάζουμε γραμμές για να ταιριάξουμε τα βασικά σημεία της αρχικής εικόνας με τους μετασχηματισμούς ερωτήματος και η έξοδος μπορεί να μοιάζει κάπως έτσι:
Το ονομάζω αυτό το φαινόμενο της πεταλούδας.
Φαγητό σε πακέτο
Δεν είναι σαν να χρειαζόσασταν ένα άλλο παράδειγμα, αλλά το όραμα υπολογιστή του OpenCV είναι ένα ισχυρό εργαλείο. Πήραμε μια εικόνα, ταξινομήσαμε τα μοναδικά χαρακτηριστικά της και, στη συνέχεια, παρεμποδίσαμε εν μέρει αυτήν την εικόνα σε μια πιο απασχολημένη εικόνα ερωτήματος, μόνο για να διαπιστώσουμε ότι η ανίχνευση χαρακτηριστικών μας ήταν τόσο ισχυρή που δεν είχε κανένα πρόβλημα να βρει και να ταιριάξει τα χαρακτηριστικά και τους περιγραφείς από την εικόνα-στόχο μας. Οι εφαρμογές αυτής της τεχνολογίας υλοποιούνται σήμερα, και αν την εξερευνήσετε τώρα, θα είστε σε καλό δρόμο για να δημιουργήσετε κάτι για το αύριο.