WALT / cwalt /clustering_utils.py
Your Name
update demo
a56642d
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri May 20 15:18:20 2022
@author: dinesh
"""
# 0 - Import related libraries
import urllib
import zipfile
import os
import scipy.io
import math
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.spatial.distance import directed_hausdorff
from sklearn.cluster import DBSCAN
from sklearn.metrics.pairwise import pairwise_distances
import scipy.spatial.distance
from .kmedoid import kMedoids # kMedoids code is adapted from https://github.com/letiantian/kmedoids
# Some visualization stuff, not so important
# sns.set()
plt.rcParams['figure.figsize'] = (12, 12)
# Utility Functions
color_lst = plt.rcParams['axes.prop_cycle'].by_key()['color']
color_lst.extend(['firebrick', 'olive', 'indigo', 'khaki', 'teal', 'saddlebrown',
'skyblue', 'coral', 'darkorange', 'lime', 'darkorchid', 'dimgray'])
def plot_cluster(image, traj_lst, cluster_lst):
'''
Plots given trajectories with a color that is specific for every trajectory's own cluster index.
Outlier trajectories which are specified with -1 in `cluster_lst` are plotted dashed with black color
'''
cluster_count = np.max(cluster_lst) + 1
for traj, cluster in zip(traj_lst, cluster_lst):
# if cluster == -1:
# # Means it it a noisy trajectory, paint it black
# plt.plot(traj[:, 0], traj[:, 1], c='k', linestyle='dashed')
#
# else:
plt.plot(traj[:, 0], traj[:, 1], c=color_lst[cluster % len(color_lst)])
plt.imshow(image)
# plt.show()
plt.axis('off')
plt.savefig('trajectory.png', bbox_inches='tight')
plt.show()
# 3 - Distance matrix
def hausdorff( u, v):
d = max(directed_hausdorff(u, v)[0], directed_hausdorff(v, u)[0])
return d
def build_distance_matrix(traj_lst):
# 2 - Trajectory segmentation
print('Running trajectory segmentation...')
degree_threshold = 5
for traj_index, traj in enumerate(traj_lst):
hold_index_lst = []
previous_azimuth = 1000
for point_index, point in enumerate(traj[:-1]):
next_point = traj[point_index + 1]
diff_vector = next_point - point
azimuth = (math.degrees(math.atan2(*diff_vector)) + 360) % 360
if abs(azimuth - previous_azimuth) > degree_threshold:
hold_index_lst.append(point_index)
previous_azimuth = azimuth
hold_index_lst.append(traj.shape[0] - 1) # Last point of trajectory is always added
traj_lst[traj_index] = traj[hold_index_lst, :]
print('Building distance matrix...')
traj_count = len(traj_lst)
D = np.zeros((traj_count, traj_count))
# This may take a while
for i in range(traj_count):
if i % 20 == 0:
print(i)
for j in range(i + 1, traj_count):
distance = hausdorff(traj_lst[i], traj_lst[j])
D[i, j] = distance
D[j, i] = distance
return D
def run_kmedoids(image, traj_lst, D):
# 4 - Different clustering methods
# 4.1 - kmedoids
traj_count = len(traj_lst)
k = 3 # The number of clusters
medoid_center_lst, cluster2index_lst = kMedoids(D, k)
cluster_lst = np.empty((traj_count,), dtype=int)
for cluster in cluster2index_lst:
cluster_lst[cluster2index_lst[cluster]] = cluster
plot_cluster(image, traj_lst, cluster_lst)
def run_dbscan(image, traj_lst, D):
mdl = DBSCAN(eps=400, min_samples=10)
cluster_lst = mdl.fit_predict(D)
plot_cluster(image, traj_lst, cluster_lst)