2016-03-16 55 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然后 –