2017-01-30 4 views
0

Ich versuche, die 3 dominierenden Farben mehrerer Bilder mit K-Means Clustering zu finden. Das Problem, mit dem ich konfrontiert bin, ist, dass K-means auch den Hintergrund des Bildes gruppiert. Ich verwende Python 2.7 und OpenCV 3K-bedeutet Farb-Clustering - Hintergrund Pixel mit maskierten numpy Arrays weglassen

Alle Bilder haben den gleichen grauen Hintergrund der folgenden RGB-Farbe: 150,150,150. Um zu vermeiden, dass K-means auch die Hintergrundfarbe gruppiert, habe ich ein maskiertes Array erstellt, das alle '150' Pixelwerte aus dem ursprünglichen Bildfeld maskiert und theoretisch nur die Nicht-Hintergrundpixel im Array belässt, mit denen K-Means arbeiten kann. Wenn ich jedoch mein Skript ausführe, wird immer noch das Grau als eine der dominierenden Farben zurückgegeben.

Meine Frage: ist ein maskiertes Array der Weg zu gehen (und habe ich etwas falsch gemacht) oder gibt es bessere Alternativen, um Pixel aus K-Means-Clustering irgendwie auszuschließen?

finden Sie meinen Code unten:

from sklearn.cluster import KMeans 
from sklearn import metrics 
import cv2 
import numpy as np 

def centroid_histogram(clt): 
    numLabels = np.arange(0, len(np.unique(clt.labels_)) + 1) 
    (hist, _) = np.histogram(clt.labels_, bins=numLabels) 
    hist = hist.astype("float") 
    hist /= hist.sum() 
    return hist 

image = cv2.imread("test1.jpg") 
image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) 

h, w, _ = image.shape 
w_new = int(100 * w/max(w, h)) 
h_new = int(100 * h/max(w, h)) 
image = cv2.resize(image, (w_new, h_new)) 

image_array = image.reshape((image.shape[0] * image.shape[1], 3)) 
image_array = np.ma.masked_values(image_array,150) 

clt = KMeans(n_clusters=3) 
clt.fit(image_array) 

hist = centroid_histogram(clt) 
zipped = zip(hist, clt.cluster_centers_) 
zipped.sort(reverse=True, key=lambda x: x[0]) 

hist, clt.cluster_centers = zip(*zipped) 
print(clt.cluster_centers_) 

Antwort

1

Wenn Sie die Werte von Pixeln, die nicht Ihren Hintergrund extrahieren möchten, können Sie numpy Indexierung verwenden:

img2=image_array[image_array!=[150,150,150]] 
img2=img2.reshape((len(img2)/3,3)) 

Dies ergeben die Liste der Pixel, die nicht [150,150,150] sind.
Allerdings behält es nicht die Struktur des Bildes, gibt Ihnen nur die Liste der Pixel Werte. Ich kann mich nicht wirklich erinnern, aber vielleicht für K-bedeutet, dass Sie das ganze Bild geben müssen, d. H. Sie müssen ihm auch die Position der Pixel zuführen? Aber in diesem Fall wird keine Maskierung jemals helfen, weil die Maskierung nur die Werte bestimmter Pixel durch eine andere ersetzt und die Pixel nicht alle zusammen loswerden.

+0

dies funktioniert gut als Eingabe für KBeans für Farb-Clustering. es wird keine räumliche Information (Pixelpositionen) verwendet, eine durch Indexierung erzeugte Liste von Pixeln ist in Ordnung. – welch

+0

Danke @welch, ich war mir nicht sicher – Soltius