Skip to content

Commit

Permalink
Allow using kmeans++ for initialization
Browse files Browse the repository at this point in the history
  • Loading branch information
kugelrund committed Jul 24, 2020
1 parent 746ca19 commit 5194d45
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 11 deletions.
8 changes: 7 additions & 1 deletion src/mesh_segmentation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ class MeshSegmentation(bpy.types.Operator):
"without sacrificing quality. 'Dense' can be tried as "
"fallback. Default",
default = 'sparse')
kmeans_init: bpy.props.EnumProperty(name = "k-means initialization",
items = [('liu_zhang', "Liu & Zhang", "Initialization by Liu & Zhang"),
('kmeans++', "k-means++", "Initialization from k-means++")],
description = "Method to use for initializing centroids for k-means.",
default = 'liu_zhang')

def execute(self, context):
"""Executes the segmentation"""
Expand All @@ -75,7 +80,8 @@ def execute(self, context):
k = self.k,
coefficients = (self.delta, self.eta),
action = getattr(actions, self.action),
ev_method = self.ev_method)
ev_method = self.ev_method,
kmeans_init = self.kmeans_init)
return {'FINISHED'}

def invoke(self, context, event):
Expand Down
23 changes: 13 additions & 10 deletions src/mesh_segmentation/segmentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ def _initial_guess(Q, k):
return chosen


def segment_mesh(mesh, k, coefficients, action, ev_method):
def segment_mesh(mesh, k, coefficients, action, ev_method, kmeans_init):
"""Segments the given mesh into k clusters and performs the given
action for each cluster
"""
Expand All @@ -175,15 +175,18 @@ def segment_mesh(mesh, k, coefficients, action, ev_method):
# normalize each row to unit length
V /= numpy.linalg.norm(V, axis=1)[:,None]

print("mesh_segmentation: Preparing kmeans...")
# compute association matrix
Q = V.dot(V.transpose())
# compute initial guess for clustering
initial_centroids = _initial_guess(Q, k)

print("mesh_segmentation: Applying kmeans...")
# apply kmeans
_, idx = scipy.cluster.vq.kmeans2(V, V[initial_centroids,:], iter=50)
if kmeans_init == 'kmeans++':
print("mesh_segmentation: Applying kmeans...")
_, idx = scipy.cluster.vq.kmeans2(V, k, minit='++', iter=50)
else:
print("mesh_segmentation: Preparing kmeans...")
# compute association matrix
Q = V.dot(V.transpose())
# compute initial guess for clustering
initial_centroids = _initial_guess(Q, k)

print("mesh_segmentation: Applying kmeans...")
_, idx = scipy.cluster.vq.kmeans2(V, V[initial_centroids,:], iter=50)

print("mesh_segmentation: Done clustering!")
# perform action with the clustering result
Expand Down

0 comments on commit 5194d45

Please sign in to comment.