Tasche mit visuellen Wörtern

7

Was ich versuche zu tun:

Ich versuche, einige Bilder mithilfe lokaler und globaler Funktionen zu klassifizieren.

Was ich bisher gemacht habe:

Ich habe für jedes Bild Siebdeskriptoren extrahiert und verwende diese als Eingabe für k-means, um mein Vokabular aus allen Merkmalen jedes Bildes zu erstellen. Von hier aus erstelle ich aus meinen Clustern ein Histogramm für jedes Bild, indem ich die Bildsiebmerkmale in k-means an die Vorhersagemethode übergebe und mir die Beschriftungen der Cluster gebe. Von hier aus erstelle ich das Histogramm, indem ich die Anzahl der Etiketten für jeden Behälter zähle. Jetzt habe ich eine nxm-Matrix, wobei n die Anzahl der Bilder und m die Anzahl der Cluster (Merkmale / Wörter) jedes Bildes ist.

Ich werde diese Matrix einem Klassifikator zuführen, um meine Bildklassifikationen zu erhalten.

Schritte auf den Punkt gebracht:

  1. Extrahieren Sie Sift-Feature-Deskriptoren und geben Sie für jedes Bild eine nx128-Matrix an

  2. Stapeln Sie alle Feature-Deskriptoren in einer großen Liste

  3. Passen Sie alle diese Merkmale in die kmeans-Algorithmuseinstellung k = 100 ein

  4. Verwenden Sie für jedes Bild seine Siebfunktionen, um die Beschriftungen der Cluster unter Verwendung des gleichen trainierten kmeans-Modells vorherzusagen

  5. Erstellen Sie ein Histogramm aus den Clustern, indem Sie k als Anzahl der Fächer verwenden und dem Fach für jedes Etikett im Modell 1 hinzufügen. (Wenn ein Bild 10 Merkmale aus dem Sieben hat, erhalten wir 10 Beschriftungen. Diese 10 Beschriftungen liegen im Bereich von k. Für jede Beschriftung fügen wir sie dem entsprechenden Fach für unser Histogramm hinzu.)

  6. Wir haben jetzt eine nxk-Matrix, wobei n die Anzahl der Bilder und k die Anzahl der Cluster ist.

  7. Wir geben nun die Histogramme an einen Klassifikator weiter und bitten ihn, die Testdaten vorherzusagen.

Das Problem:

Führe ich eine Menge visueller Wörter richtig aus?

Hier ist mein Code:

def extract_features(df):
    IF = imageFeatures()
    global_features = []
    sift_features = []
    labels = []
    for i, (index, sample) in enumerate(df.iterrows()):
        image = cv2.imread(sample["location"])
        image = cv2.resize(image, shape)
        hist = IF.fd_histogram(image)
        haralick = IF.fd_haralick(image)
        hu = IF.fd_hu_moments(image)
        lbp = IF.LocalBinaryPatterns(image, 24, 8)
        kp, des = IF.SIFT(image)
        if len(kp) == 0:
            #print (i)
            #print (index)
            #print (sample)
            #return 0
            des = np.zeros(128)
        sift_features.append(des)
        global_feature = np.hstack([hist, haralick, hu, lbp])
        global_features.append(global_feature)
        labels.append(sample["class_id"])
    scaler = MinMaxScaler(feature_range=(0, 1))
    rescaled = scaler.fit_transform(global_features)
    return sift_features, rescaled, labels

def BOVW(feature_descriptors, n_clusters = 100):
    print("Bag of visual words with {} clusters".format(n_clusters))
    #take all features and put it into a giant list
    combined_features = np.vstack(np.array(feature_descriptors))
    #train kmeans on giant list
    print("Starting K-means training")
    kmeans = MiniBatchKMeans(n_clusters=n_clusters, random_state=0).fit(combined_features)
    print("Finished K-means training, moving on to prediction")
    bovw_vector = np.zeros([len(feature_descriptors), n_clusters])#number of images x number of clusters. initiate matrix of histograms
    for index, features in enumerate(feature_descriptors):#sift descriptors in each image
        try:
            for i in kmeans.predict(features):#get label for each centroid
                bovw_vector[index, i] += 1#create individual histogram vector
        except:
            pass
    return bovw_vector#this should be our histogram

if __name__ == '__main__':
    n_clusters = 100
    #set model
    model = GaussianNB()
    image_list = pd.read_csv("image_list.csv")
    image_list_subset = image_list.groupby('class_id').head(80)#image_list.loc[(image_list["class_id"] == 0) | (image_list["class_id"] == 19)]
    shape = (330,230)
    train, test = train_test_split(image_list_subset, test_size=0.1, random_state=42)

    train_sift_features, train_global_features, y_train = extract_features(train)
    train_histogram = BOVW(train_sift_features, n_clusters)
    import matplotlib.pyplot as plt
    plt.plot(train_histogram[100], 'o')
    plt.ylabel('frequency');
    plt.xlabel('features');

    test_sift_features, test_global_features, y_test = extract_features(test)
    test_histogram = BOVW(test_sift_features, n_clusters)

    '''Naive Bays'''
    y_hat = model.fit(train_histogram, y_train).predict(test_histogram)
    print("Number of correctly labeled points out of a total {} points : {}. An accuracy of {}"
          .format(len(y_hat), sum(np.equal(y_hat,np.array(y_test))), 
                  sum(np.equal(y_hat,np.array(y_test)))/len(y_hat)))
Kevin
quelle
4
Wenn Sie abstimmen, erklären Sie bitte warum.
Kevin
Ich habe nicht abgelehnt, aber es wäre sehr nützlich zu wissen, warum Sie denken, dass etwas mit dem Code nicht stimmt. Bitten Sie um eine generische Codeüberprüfung (die möglicherweise die Grenze außerhalb des Themas erreicht)? Können Sie BOVWzu Testzwecken einige Beispieleingaben für die Funktion bereitstellen ?
E_net4 der Rustacean
@ E_net4 Ich versuche sicherzustellen, dass ich das richtige Konzept habe. Der Grund ist, dass BOVW die Ergebnisse nicht wirklich zu verbessern scheint. Es kann viele Gründe dafür geben, möglicherweise sind die Daten schlecht oder ich habe nicht genügend Cluster oder meine Funktionen sind nicht gut. Ich möchte nur sicherstellen, dass mein Ansatz korrekt ist. Ich kann ein prägnanteres Beispiel liefern, muss aber auch Daten bereitstellen. Gibt es eine Möglichkeit für mich, dies zu tun? Vielleicht kann ich mit numpy Daten generieren?
Kevin
Können Sie uns sagen, womit die Leistung verglichen wird? Und zu welchen Daten verwenden Sie?
Tony Knapp

Antworten:

1

Der beste Weg, um Ihre Frage zu beantworten, ist das Originalpapier, in dem die Methode vorgestellt wurde:

"Visuelle Kategorisierung mit Taschen von Schlüsselpunkten" (2004)

Der Artikel ist nicht lang und leicht verständlich geschrieben. Für Ihre Frage können Sie nur die ersten 6 Seiten lesen.

Entnommen aus dem Artikel "Visuelle Kategorisierung mit Taschen von Schlüsselpunkten":

Die Hauptschritte unserer Methode sind:

• Erkennung und Beschreibung von Bildfeldern

• Zuweisen von Patch-Deskriptoren zu einer Reihe vorbestimmter Cluster (eines Vokabulars) mit einem Vektorquantisierungsalgorithmus

• Erstellen einer Tasche mit Schlüsselpunkten, die die Anzahl der jedem Cluster zugewiesenen Patches zählt

• Anwenden eines Klassifikators mit mehreren Klassen, Behandeln des Beutels mit Schlüsselpunkten als Merkmalsvektor und Bestimmen, welche Kategorie oder Kategorien dem Bild zugewiesen werden sollen.

Mark.F
quelle