2016-03-16 57 views
1

我正在製作一個代碼,用於分析圖像並使用KMeans羣集查找三種最主要的顏色。代碼工作正常,但我想要計算三個集羣中的像素數。計算羣集中的像素數(Kmeans顏色檢測)

代碼:

class Cluster(object): 

    def __init__(self): 
     self.pixels = [] 
     self.centroid = None 


    def addPoint(self, pixel): 
     self.pixels.append(pixel) 


    def setNewCentroid(self): 
     R = [colour[0] for colour in self.pixels] 
     G = [colour[1] for colour in self.pixels] 
     B = [colour[2] for colour in self.pixels] 

     R = sum(R)/len(R) 
     G = sum(G)/len(G) 
     B = sum(B)/len(B) 

     self.centroid = (R, G, B) 
     self.pixels = []   
     return self.centroid 


class Kmeans(object): 
    def __init__(self, k=2, max_iterations=5, min_distance=2.0, size=200): 
     self.k = k 
     self.max_iterations = max_iterations 
     self.min_distance = min_distance 
     self.size = (size, size) 


    def run(self, image): 
     self.image = image 
     self.image.thumbnail(self.size) 
     self.pixels = numpy.array(image.getdata(), dtype=numpy.uint8) 

     self.clusters = [None for i in range(self.k)] 
     self.oldClusters = None 

     randomPixels = random.sample(self.pixels, self.k) 

     for idx in range(self.k): 
      self.clusters[idx] = Cluster() 
      self.clusters[idx].centroid = randomPixels[idx] 

     iterations = 0 
     while self.shouldExit(iterations) is False: 

      self.oldClusters = [cluster.centroid for cluster in self.clusters] 
      print iterations 

      for pixel in self.pixels: 
       self.assignClusters(pixel) 

      for cluster in self.clusters: 
       cluster.setNewCentroid() 

      iterations += 1 
     return [cluster.centroid for cluster in self.clusters] 


    def assignClusters(self, pixel): 
     shortest = float('Inf') 
     for cluster in self.clusters: 
      distance = self.calcDistance(cluster.centroid, pixel) 
      if distance < shortest: 
       shortest = distance 
       nearest = cluster 

     nearest.addPoint(pixel) 


    def calcDistance(self, a, b): 
     result = numpy.sqrt(sum((a - b) ** 2)) 
     return result 


    def shouldExit(self, iterations): 
     if self.oldClusters is None: 
      return False 

     for idx in range(self.k): 
      dist = self.calcDistance(
       numpy.array(self.clusters[idx].centroid), 
       numpy.array(self.oldClusters[idx]) 
      ) 
      if dist < self.min_distance: 
       return True 

     if iterations <= self.max_iterations: 
      return False 

     return True 

有沒有一種方法,我可以數分配給每個簇多少像素?我不希望有多少價值相同,只是總數。

+0

難道你不能總結每個集羣中像素的索引值嗎? – kmario23

回答

0

你的意思是,你想要做

for cluster in self.clusters: 
    print len(cluster.pixels) 

每個集羣?

+0

然後它看起來像這樣: >>打印len(像素) >> 3 它是在一個循環遍歷所有的像素,所以我想我需要做一些變量,如x = + 1,每次它循環。但是,所有三個羣集都在同一個循環中,所以我總是以x = 30000(圖像中的所有像素爲200x150)爲結束。 – JoeKing

+0

在羣集上循環,而不是所有像素。當然,還是分別計算羣集 –

+0

您的變量命名是誤導。「像素」是複數,但顯然你只在其中存儲一個像素?它應該被命名爲像素或color_components然後 –