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) | |