【问题标题】:How can I improve a "dumb" vector quantization algorithm for K-means clustering如何改进 K 均值聚类的“哑”矢量量化算法
【发布时间】:2015-06-03 23:45:17
【问题描述】:

我需要将依赖于 scipy.cluster.vq 模块的代码库转换为不使用 scipy,以便我可以在 C++ 中实现它。

首先,我尝试仅使用 numpy 来复制结果。

从尺寸为 MxNx3 的图像开始,我使用带有 opencv 的 kmeans 创建了一个“质心”Kx3 数组。

我需要将原始图像的每个像素映射到centroids数组中最接近原始像素的像素值。

我可以正常工作,但性能很糟糕。我确信必须有更高级的方法来计算它,我怀疑它与最近邻搜索有关(也许?)但不确定。

这是我目前正在做的事情:我认为这可能被称为“蛮力”方法

  1. 遍历图像中的每个像素
  2. 计算该像素与质心列表中每个像素之间的欧式距离
  3. 从第 2 步生成的列表中返回最小值
  4. 将原始图像像素分配给返回最小距离的质心列表的值。

    def vq(self,image,centroids):
        x,y,z = image.shape
        Z=np.reshape(image,(x*y,z))
        counts = np.zeros(len(centroids))
        clusterMap = np.zeros(Z.shape,np.uint8)
        for i in range(Z.shape[0]):
            color = Z[i]
            closestIndex = self.getClosestCenter(color, centroids)
            counts[closestIndex]+=1# tracking how often each color occurs
            clusterMap[i] = centroids[closestIndex]
        return clusterMap,counts
    
    def getClosestCenter(self,color,centers):
            distances = [0 for i in range(len(centers))]
            for i,center in enumerate(centers):
                distances[i] = self.getDistance(color, center)
            return distances.index(min(distances))
    
    def getDistance(self,value1,value2):
           if len(value1) !=len(value2): return None #error
            sum = 0
            for i in range(len(value1)):
                sum+=(value1[i]-value2[i])**2
            return sum**(0.5)
    

【问题讨论】:

    标签: python opencv scipy cluster-analysis k-means


    【解决方案1】:

    首先,分析您的代码,看看它到底是哪里慢了。 enumerate 之类的构造可能非常昂贵,因为它们需要创建许多元组对象并进行垃圾回收。一个好的经验法则是避免在内部循环和函数中分配对象(这包括元组等隐藏对象)

    最后但同样重要的是,kmeans 不使用欧几里得距离。它使用平方和。去掉平方根。

    【讨论】:

    • 感谢您的回复。因此,与其使用enumerate,不如手动增加int?对于最后一点,此方法不是计算 K-means,而是使用 k-means 中的值将原始图像的像素重新映射到从 kmeans 返回的中心。但是,我刚刚意识到 opencv 返回一个 label 映射,其中包含我需要的确切数据,所以我所要做的就是在该矩阵上执行直方图以获得每个质心的相对计数。
    • 重映射也将使用最小二乘法。
    猜你喜欢
    • 2014-09-11
    • 2016-10-09
    • 2017-06-08
    • 2014-04-25
    • 2012-06-15
    • 2014-09-16
    • 1970-01-01
    • 2011-09-06
    相关资源
    最近更新 更多