Saco de Palavras Visuais

7

O que estou tentando fazer:

Estou tentando classificar algumas imagens usando recursos locais e globais.

O que eu fiz até agora:

Eu extraí descritores de peneiração para cada imagem e estou usando isso como minha entrada para k-means para criar meu vocabulário a partir de todos os recursos de cada imagem. A partir daqui, crio um histograma a partir de meus clusters para cada imagem, passando os recursos de seleção de imagens para o método de previsão em k-means, fornecendo os rótulos dos clusters. A partir daqui, crio o histograma contando o número de etiquetas para cada bandeja. Agora eu tenho uma matriz nxm onde n é o número de imagens e estou sendo o número de clusters (recursos / palavras) de cada imagem.

Vou alimentar essa matriz com um classificador para obter minhas classificações de imagem.

Etapas em poucas palavras:

  1. Extraia descritores de recursos de peneiração, fornecendo uma matriz nx128 para cada imagem

  2. Empilhe todos os descritores de recursos em uma lista grande

  3. Ajuste todos esses recursos à configuração do algoritmo kmeans k = 100

  4. Para cada imagem, use seus recursos de peneiração para prever os rótulos dos clusters usando o mesmo modelo kmeans treinado

  5. Crie um histograma a partir dos clusters usando k como o número de posições, adicionando 1 à bandeja para cada etiqueta no modelo. (se uma imagem tiver 10 recursos do sift, ela fornecerá 10 rótulos, esses 10 rótulos estarão no intervalo de k; portanto, para cada rótulo, a adicionaremos à lixeira correspondente do histograma).

  6. Agora temos uma matriz nxk, em que n é o número de imagens ek é o número de clusters.

  7. Agora, alimentamos os histogramas para um classificador e pedimos que ele preveja os dados do teste.

O problema:

Estou executando corretamente um conjunto de palavras visuais?

Aqui está o meu código:

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
fonte
4
Se você votou negativamente, explique o motivo.
Kevin
Não reduzi o voto, mas seria muito útil saber por que você acha que há algo errado com o código. Você está solicitando uma revisão de código genérica (que pode atingir a fronteira fora do tópico)? Você pode fornecer algumas entradas de amostra para a BOVWfunção, para fins de teste?
E_net4 the Rustacean
@ E_net4 Estou tentando ter certeza de que tenho o conceito correto. A razão é que o BOVW parece realmente não melhorar muito os resultados. Pode haver muitas razões para isso, talvez os dados estejam ruins ou eu não tenha clusters suficientes ou talvez meus recursos não sejam bons. Eu só quero garantir que minha abordagem esteja correta. Eu posso fornecer um exemplo mais sucinto, mas também tenho que fornecer dados. Existe uma maneira de eu fazer isso? Talvez eu possa gerar alguns dados usando numpy?
21318 Kevin
Você poderia nos dizer com o que está comparando o desempenho? E para quais dados você está usando?
Tony Knapp

Respostas:

1

A melhor maneira de responder sua pergunta é ir ao artigo original que introduziu o método:

"Categorização visual com malas de pontos-chave" (2004)

O artigo não é longo e escrito de uma maneira fácil de entender. Para sua pergunta, você pode ler apenas as 6 primeiras páginas.

Retirado do artigo "Categorização visual com bolsas de pontos-chave":

As principais etapas do nosso método são:

• Detecção e descrição de amostras de imagens

• Designando descritores de patch a um conjunto de clusters predeterminados (um vocabulário) com um algoritmo de quantização vetorial

• Construir um conjunto de pontos-chave, que conta o número de patches atribuídos a cada cluster

• Aplicar um classificador de várias classes, tratar o conjunto de pontos-chave como o vetor de recurso e, assim, determinar qual categoria ou categorias atribuir à imagem.

Mark.F
fonte