我正在寻找一种与OpenCV进行单链路聚类的方法。我的情景:
E
- 如果两个向量之间的l1范数小于E
,则向量应位于同一群集中。E
之内。这可能导致长链“而不是簇”,但我对此很好。我尝试使用K-means,但因为我不知道群集的数量,所以这里并不适用。我可以做迭代的K-means并寻找最好的K,但听起来效率低下。我可以在这里使用OpenCV中实现更合适的聚类算法吗?
理想情况下,我需要类似于SLINK algorithm的内容,因为这是我目前正在尝试实施的文章中引用的内容。我的选择是直接实现SLINK(一些任务,因为调试和测试)或寻找一个类似的现有算法。
有什么建议吗?
答案 0 :(得分:2)
我建议按相似度阈值构建图表并找到connected components。构建图形后,查找连接的组件将非常简单有效。如果您希望NetworkX已有连接的组件function。
答案 1 :(得分:0)
我最终自己做了一个实现:
import cv
def main():
import sys
x = cv.Load(sys.argv[1])
epsilon = float(sys.argv[2])
y = cv.CloneImage(x)
labels = range(x.height)
tmp = cv.CreateImage((x.width, 1), x.depth, x.nChannels)
for i in range(x.height):
cv.SetImageROI(x, (0, i, x.width, 1))
for j in range(i+1, x.height):
cv.SetImageROI(y, (0, j, x.width, 1))
cv.AbsDiff(x, y, tmp)
dist, _, _, _ = cv.Avg(tmp)
if dist < epsilon:
for k, lbl in enumerate(labels):
if lbl == j:
labels[k] = i
for i, lbl in enumerate(labels):
print i, lbl
if __name__ == '__main__':
main()
x
是包含N x M
个向量的N
矩阵。向量的维数为M
。它基本上使用L1范数比较每对向量,并且如果它们的差异小于epsilon
则认为一对是相同的。这个算法很慢--- O(N^3)
,但现在对我来说已经足够了。