Spaces:
Runtime error
Runtime error
#!/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) | |