def get_assignment(gmm_x, gmm_y): """Compute linear assignment with the Hungarian algorithm. """ M = euclidean_distances( gmm_x.means_, gmm_y.means_, squared=True) assignment = linear_assignment(M) return assignment
def cluster_acc(y_true, y_pred): """ Calculate clustering accuracy. Require scikit-learn installed # Arguments y: true labels, numpy.array with shape `(n_samples,)` y_pred: predicted labels, numpy.array with shape `(n_samples,)` # Return accuracy, in [0,1] """ y_true = np.array(y_true).astype(np.int64) assert y_pred.size == y_true.size D = max(y_pred.max(), y_true.max()) + 1 w = np.zeros((D, D), dtype=np.int64) for i in range(y_pred.size): w[y_pred[i], y_true[i]] += 1 ind = linear_assignment(w.max() - w) sum = 0 # print(w,y_pred.size) # for i,j in ind: # sum+=w[i,j] for i in range(y_true.size): if y_pred[i] == y_true[i]: sum += 1 # for i in ind[0]: # for j in ind[1]: # sum += w[i,j] # # print(w) # print("w:",w,"ind:",ind,sum,y_pred.size) return sum * 1.0 / y_pred.size
def reassign_cluster_with_ref(Y_pred, Y): """ Reassign cluster to reference labels Parameters ---------- Y_pred: predict y classes Y: true y classes Returns ------- f1_score: clustering f1 score y_pred: reassignment index predict y classes indices: classes assignment """ def reassign_cluster(y_pred, index): y_ = np.zeros_like(y_pred) for i, j in index: y_[np.where(y_pred == i)] = j return y_ # from sklearn.utils.linear_assignment_ import linear_assignment from scipy.optimize import linear_sum_assignment as linear_assignment # print(Y_pred.size, Y.size) assert Y_pred.size == Y.size D = max(Y_pred.max(), Y.max()) + 1 w = np.zeros((D, D), dtype=np.int64) for i in range(Y_pred.size): w[Y_pred[i], Y[i]] += 1 ind = linear_assignment(w.max() - w) return reassign_cluster(Y_pred, ind), ind
def balance_SA(data, param): (n, m) = data["G"].shape k = param["nbclust"] S = data["S"] A = data["A"] def apply_assignment_S(Sj, permutation): inv_permutation = np.argsort(permutation) for i, val_s in enumerate(Sj): Sj[i] = inv_permutation[val_s] return Sj def apply_assignment_A(Aj, permutation): Aj = Aj[permutation] return Aj for j in range(1,m): weights = np.zeros((k,k)) for (x,y), c in Counter(zip(S[:,j-1], S[:,j])).iteritems(): weights[x, y] = c assignment = linear_assignment(-weights) permutation = assignment[:,1].T Sj = apply_assignment_S(S[:, j], permutation) S[:, j] = Sj Aj = apply_assignment_A(A[:, j], permutation) A[:, j] = Aj return (data, param)
def acc(y_true, y_pred): #numpy from sklearn.metrics import normalized_mutual_info_score, adjusted_rand_score nmi = normalized_mutual_info_score ari = adjusted_rand_score """ https://github.com/XifengGuo/DEC-keras/blob/master/metrics.py Calculate clustering accuracy. Require scikit-learn installed # Arguments y: true labels, numpy.array with shape `(n_samples,)` y_pred: predicted labels, numpy.array with shape `(n_samples,)` # Return accuracy, in [0,1] """ y_true = y_true.astype(np.int64) assert y_pred.size == y_true.size D = max(y_pred.max(), y_true.max()) + 1 w = np.zeros((D, D), dtype=np.int64) for i in range(y_pred.size): w[y_pred[i], y_true[i]] += 1 from scipy.optimize import linear_sum_assignment as linear_assignment ind = np.asarray(linear_assignment(w.max() - w)).T return sum([w[i, j] for i, j in ind]) * 1.0 / y_pred.size
def bestmap(label_pro, lable_true): label_out = [] cost_matrix = construct_W(label_pro, lable_true) matches, changes = linear_assignment(cost_matrix) for i in label_pro: label_out.append(changes[i]) return label_out
def min_cost_matching( distance_metric, max_distance, tracks, detections, track_indices=None, detection_indices=None): if track_indices is None: track_indices = np.arange(len(tracks)) if detection_indices is None: detection_indices = np.arange(len(detections)) if len(detection_indices) == 0 or len(track_indices) == 0: return [], track_indices, detection_indices # Nothing to match. cost_matrix = distance_metric( tracks, detections, track_indices, detection_indices) cost_matrix[cost_matrix > max_distance] = max_distance + 1e-5 row_indices, col_indices = linear_assignment(cost_matrix) matches, unmatched_tracks, unmatched_detections = [], [], [] for col, detection_idx in enumerate(detection_indices): if col not in col_indices: unmatched_detections.append(detection_idx) for row, track_idx in enumerate(track_indices): if row not in row_indices: unmatched_tracks.append(track_idx) for row, col in zip(row_indices, col_indices): track_idx = track_indices[row] detection_idx = detection_indices[col] if cost_matrix[row, col] > max_distance: unmatched_tracks.append(track_idx) unmatched_detections.append(detection_idx) else: matches.append((track_idx, detection_idx)) return matches, unmatched_tracks, unmatched_detections
def _hungarian_match(flat_preds, flat_targets, preds_k, targets_k): assert (isinstance(flat_preds, torch.Tensor) and isinstance(flat_targets, torch.Tensor) and flat_preds.is_cuda and flat_targets.is_cuda) num_samples = flat_targets.shape[0] assert (preds_k == targets_k) # one to one num_k = preds_k num_correct = np.zeros((num_k, num_k)) for c1 in range(num_k): for c2 in range(num_k): # elementwise, so each sample contributes once votes = int(((flat_preds == c1) * (flat_targets == c2)).sum()) num_correct[c1, c2] = votes # num_correct is small match = linear_assignment(num_samples - num_correct) # return as list of tuples, out_c to gt_c res = [] for out_c, gt_c in zip(*match): res.append((out_c, gt_c)) return res
def connect(self, dets, tracks): dets = self.cpm.from_two_corners(dets[:, :-1]) tracks = self.cpm.from_two_corners(tracks[:, :-1]) D = dist.cdist(dets, tracks) matches = np.column_stack(linear_assignment(D)) matches = np.column_stack([matches, D[matches[:, 0], matches[:, 1]]]) return matches[matches[:, -1] < self.max_distance, :]
def cluster_acc(Y_pred, Y): assert Y_pred.size == Y.size D = max(Y_pred.max(), Y.max()) + 1 w = np.zeros((D, D), dtype=self.int_type) for i in range(Y_pred.size): w[Y_pred[i], Y[i]] += 1 ind = np.transpose(np.asarray(linear_assignment(w.max() - w))) return sum([w[i, j] for i, j in ind]) * 1.0 / Y_pred.size, np.array(w)
def advantageCount(self, A: List[int], B: List[int]) -> List[int]: len_A = len(A) optimal_A = [0] * len_A cost_matrix = compute(A, B) order = linear_assignment(cost_matrix)[1] for i, match in enumerate(order): optimal_A[match] = A[i] return optimal_A
def assign_detections_to_trackers(trackers, detections, iou_thrd=0.3): # if there is no trackers (start of the footage) return empty array if (len(trackers) == 0): return np.empty( (0, 2), dtype=int), np.arange(len(detections)), np.empty((0, 5), dtype=int) # initiate empty matrix of len(det), len (trk) iou_matrix = np.zeros((len(detections), len(trackers)), dtype=np.float32) # extract the array of detections and trackers only for d, det in enumerate(detections): for t, trk in enumerate(trackers): # then write each detection and tracker IOU into the matrix (i.e. 0.1. 0.2, 03). # The loop compares each det with each trk iou_matrix[d, t] = iou(det, trk) # extract the indices of optimally matched dets and trks (Hungarian algorithm) # Algorithm selects the highest IOU for each det. Output is in the form [0,1,2], [1,0,2] (Selects the highest from each row) # This means that tracker[1] corresponds to det[0], 0->1, 2->2. Unmatched trackers are not saved to this array try: matched_indices = linear_assignment(-iou_matrix) except: print('matrix contains invalid numeric') # convert tuple to array (size is A x 2) where A is the number of matched pairs matched_indices = np.asarray(matched_indices) # initiate an empty array of unmatched detections unmatched_detections = [] # loop over all detections and extract all unmatched detections (d is just an index) for d, det in enumerate(detections): # [0,:] corresponds to all matched detections indices if d not in matched_indices[0, :]: unmatched_detections.append(d) unmatched_trackers = [] for t, trk in enumerate(trackers): # [1,:] corresponds to all matched trackers indices if t not in matched_indices[1, :]: unmatched_trackers.append(t) # initiate matches array matches = [] # loop over all matched indices for m in np.transpose(matched_indices): # filter out matches with low IOU # Go inside each location (m[0],m[1] corresponds to one IOU value left after Hung algorithm) if (iou_matrix[m[0], m[1]] < iou_thrd): # add unmathced values to already existing ones unmatched_detections.append(m[0]) unmatched_trackers.append(m[1]) else: # append all the matches into separate array matches.append(m.reshape(1, 2)) if len(matches) == 0: matches = np.empty((0, 2), dtype=int) else: matches = np.concatenate(matches, axis=0) # return all of the arrays return matches, np.array(unmatched_detections), np.array( unmatched_trackers)
def ceafe(clusters, gold_clusters): clusters = [c for c in clusters if len(c) != 1] scores = np.zeros((len(gold_clusters), len(clusters))) for i in range(len(gold_clusters)): for j in range(len(clusters)): scores[i, j] = phi4(gold_clusters[i], clusters[j]) matching_row, matching_col = linear_assignment(-scores) similarity = sum(scores[matching_row, matching_col]) return similarity, len(clusters), similarity, len(gold_clusters)
def acc(labels_true, labels_pred): labels_true = labels_true.astype(np.int64) assert labels_pred.size == labels_true.size D = max(labels_pred.max(), labels_true.max()) + 1 w = np.zeros((D, D), dtype=np.int64) for i in range(labels_pred.size): w[labels_pred[i], labels_true[i]] += 1 from scipy.optimize import linear_sum_assignment as linear_assignment ind = dict(zip(*linear_assignment(w.max() - w))) return sum([w[i, j] for i, j in ind.items()]) * 1.0 / labels_pred.size
def cluster_acc(y_true, y_pred): y_true = np.array(y_true).astype(np.int64) assert y_pred.size == y_true.size D = max(y_pred.max(), y_true.max()) + 1 w = np.zeros((D, D), dtype=np.int64) for i in range(y_pred.size): w[y_pred[i], y_true[i]] += 1 ind = linear_assignment(w.max() - w) return sum([w[i, j] for i, j in ind]) * 1.0 / y_pred.size
def min_cost_matching(distance_metric, max_distance, tracks, detections, track_indices=None, detection_indices=None): """ 使用匈牙利算法解决线性分配问题 Parameters ---------- distance_metric 轨迹集检测和他们的下标 max_distance 最大距离阈值,大于此距离的关联无效 tracks detections track_indices detection_indices Returns 匹配上的轨迹和检测 未匹配的轨迹 未匹配的检测 ------- """ if track_indices is None: track_indices = np.arange(len(tracks)) if detection_indices is None: detection_indices = np.arange(len(detections)) if len(detection_indices) == 0 or len(track_indices) == 0: return [], track_indices, detection_indices # Nothing to match. cost_matrix = distance_metric(tracks, detections, track_indices, detection_indices) cost_matrix[cost_matrix > max_distance] = max_distance + 1e-5 row_indices, col_indices = linear_assignment(cost_matrix) matches, unmatched_tracks, unmatched_detections = [], [], [] for col, detection_idx in enumerate(detection_indices): if col not in col_indices: unmatched_detections.append(detection_idx) for row, track_idx in enumerate(track_indices): if row not in row_indices: unmatched_tracks.append(track_idx) for row, col in zip(row_indices, col_indices): track_idx = track_indices[row] detection_idx = detection_indices[col] if cost_matrix[row, col] > max_distance: # 如果组合后的cost大于阈值还是认为不匹配,移到不匹配列表中 unmatched_tracks.append(track_idx) unmatched_detections.append(detection_idx) else: matches.append((track_idx, detection_idx)) return matches, unmatched_tracks, unmatched_detections
def cluster_acc(Y_pred, Y): assert Y_pred.size == Y.size D = max(Y_pred.max(), Y.max()) + 1 w = np.zeros((D, D), dtype=np.int64) for i in range(Y_pred.size): w[Y_pred[i], Y[i]] += 1 ind = linear_assignment(w.max() - w) total = 0 for i in range(len(ind[0])): total += w[ind[0][i], ind[1][i]] return total * 1.0 / Y_pred.size, w
def ceafe(clusters, gold_clusters): clusters = [c for c in clusters if len(c) != 1] scores = np.zeros((len(gold_clusters), len(clusters))) for i in range(len(gold_clusters)): for j in range(len(clusters)): scores[i, j] = phi4(gold_clusters[i], clusters[j]) matching = linear_assignment(-scores) # matching2 = linear_sum_assignment(-scores) # matching2 = np.transpose(np.asarray(matching2)) similarity = sum(scores[matching[:, 0], matching[:, 1]]) return similarity, len(clusters), similarity, len(gold_clusters)
def acc(labels_true, labels_pred): labels_true = labels_true.astype(np.int64) assert labels_pred.size == labels_true.size D = max(labels_pred.max(), labels_true.max()) + 1 w = np.zeros((D, D), dtype=np.int64) for i in range(labels_pred.size): w[labels_pred[i], labels_true[i]] += 1 from scipy.optimize import linear_sum_assignment as linear_assignment row_ind, col_ind = linear_assignment(w.max() - w) return sum([w[row_ind[i], col_ind[i]] for i in range(len(row_ind))]) * 1.0 / labels_pred.size
def unsupervised_clustering_accuracy(y, y_pred): assert len(y_pred) == len(y) u = np.unique(np.concatenate((y, y_pred))) n_clusters = len(u) mapping = dict(zip(u, range(n_clusters))) reward_matrix = np.zeros((n_clusters, n_clusters), dtype=np.int64) for y_pred_, y_ in zip(y_pred, y): if y_ in mapping: reward_matrix[mapping[y_pred_], mapping[y_]] += 1 cost_matrix = reward_matrix.max() - reward_matrix ind = linear_assignment(cost_matrix) return sum([reward_matrix[i, j] for i, j in ind]) * 1.0 / y_pred.size
def associate_detections_to_trackers(detections, trackers, iou_threshold=0.1): # def associate_detections_to_trackers(detections,trackers,iou_threshold=0.01): # ablation study # def associate_detections_to_trackers(detections,trackers,iou_threshold=0.25): """ Assigns detections to tracked object (both represented as bounding boxes) detections: N x 8 x 3 trackers: M x 8 x 3 Returns 3 lists of matches, unmatched_detections and unmatched_trackers """ if (len(trackers) == 0): return np.empty( (0, 2), dtype=int), np.arange(len(detections)), np.empty((0, 8, 3), dtype=int) iou_matrix = np.zeros((len(detections), len(trackers)), dtype=np.float32) for d, det in enumerate(detections): for t, trk in enumerate(trackers): #print(f'On d={d}, t={t}') #iou_matrix[d,t] = iou3d(det,trk)[1] # try 2d iou instead # det: 8 x 3, trk: 8 x 3 iou_matrix[d, t] = compute_iou_2d_bboxes(det, trk) matched_indices = linear_assignment(-iou_matrix) # hungarian algorithm matched_indices = np.column_stack(matched_indices) unmatched_detections = [] for d, det in enumerate(detections): if (d not in matched_indices[:, 0]): unmatched_detections.append(d) unmatched_trackers = [] for t, trk in enumerate(trackers): if (t not in matched_indices[:, 1]): unmatched_trackers.append(t) #print(iou_matrix) #filter out matched with low IOU matches = [] for m in matched_indices: if (iou_matrix[m[0], m[1]] < iou_threshold): unmatched_detections.append(m[0]) unmatched_trackers.append(m[1]) else: matches.append(m.reshape(1, 2)) if (len(matches) == 0): matches = np.empty((0, 2), dtype=int) else: matches = np.concatenate(matches, axis=0) return matches, np.array(unmatched_detections), np.array( unmatched_trackers)
def assign_detections_to_trackers(trackers, detections, iou_thrd = 0.3): ''' From current list of trackers and new detections, output matched detections, unmatchted trackers, unmatched detections. ''' IOU_mat= np.zeros((len(trackers),len(detections)),dtype=np.float32) for t,trk in enumerate(trackers): #trk = convert_to_cv2bbox(trk) for d,det in enumerate(detections): # det = convert_to_cv2bbox(det) IOU_mat[t,d] = box_iou2(trk,det) # Produces matches # Solve the maximizing the sum of IOU assignment problem using the # Hungarian algorithm (also known as Munkres algorithm) matched_idx_tra, matched_idx_det = linear_assignment(-IOU_mat) matched_idx = np.zeros((len(matched_idx_tra),2),dtype=np.int8) for i in range(len(matched_idx_tra)): matched_idx[i]=(matched_idx_tra[i],matched_idx_det[i]) unmatched_trackers, unmatched_detections = [], [] for t,trk in enumerate(trackers): if(t not in matched_idx[:,0]): unmatched_trackers.append(t) for d, det in enumerate(detections): if(d not in matched_idx[:,1]): unmatched_detections.append(d) matches = [] # For creating trackers we consider any detection with an # overlap less than iou_thrd to signifiy the existence of # an untracked object for m in matched_idx: if(IOU_mat[m[0],m[1]]<iou_thrd): unmatched_trackers.append(m[0]) unmatched_detections.append(m[1]) else: matches.append(m.reshape(1,2)) if(len(matches)==0): matches = np.empty((0,2),dtype=int) else: matches = np.concatenate(matches,axis=0) return matches, np.array(unmatched_detections), np.array(unmatched_trackers)
def best_cluster_fit(y_true, y_pred): y_true = y_true.astype(np.int64) D = max(y_pred.max(), y_true.max()) + 1 w = np.zeros((D, D), dtype=np.int64) for i in range(y_pred.size): w[y_pred[i], y_true[i]] += 1 ind = linear_assignment(w.max() - w) best_fit = [] for i in range(y_pred.size): for j in range(len(ind)): if ind[j][0] == y_pred[i]: best_fit.append(ind[j][1]) return best_fit, ind, w
def assign_detections_to_trackers(unit_trackers: List[UnitObject], unit_detections: List[UnitObject], iou_thrd=0.3): """ Matches Trackers and Detections :param unit_trackers: trackers :param unit_detections: detections :param iou_thrd: threshold to qualify as a match :return: matches, unmatched_detections, unmatched_trackers """ IOU_mat = np.zeros((len(unit_trackers), len(unit_detections)), dtype=np.float32) for t, trk in enumerate(unit_trackers): for d, det in enumerate(unit_detections): if trk.class_id == det.class_id: IOU_mat[t, d] = calculate_iou(trk.box, det.box) # Finding Matches using Hungarian Algorithm row_ind, col_ind = linear_assignment(-IOU_mat) # matched_idx = linear_assignment(-IOU_mat) unmatched_trackers, unmatched_detections = [], [] for t, trk in enumerate(unit_trackers): if t not in row_ind: # matched_idx[:, 0]: unmatched_trackers.append(t) for d, det in enumerate(unit_detections): if d not in col_ind: #matched_idx[:, 1]: unmatched_detections.append(d) matches = [] # Checking quality of matched by comparing with threshold for i in range(len(row_ind)): if IOU_mat[row_ind[i], col_ind[i]] < iou_thrd: unmatched_trackers.append(row_ind[i]) unmatched_detections.append(col_ind[i]) else: m = np.array([row_ind[i], col_ind[i]]) matches.append([m.reshape(1, 2)]) if len(matches) == 0: matches = np.empty((0, 2), dtype=int) else: matches = np.concatenate(matches, axis=0) matches = matches.reshape(len(matches), 2) return matches, np.array(unmatched_detections), np.array( unmatched_trackers)
def acuracia(self, lista_corrigida, lista_agrupada): agrupada = lista_agrupada.astype(np.int) corrigida = lista_corrigida.astype(np.int) cm = confusion_matrix(corrigida, agrupada) indexes = np.asarray(linear_assignment(self.make_cost_m( cm))) #encontra a melhor ordem da matrix de confusao cm2 = cm[:, indexes[1]] #altera a ordem na matrix de confusao #ax = sns.heatmap(cm, annot=True, fmt="d", cmap="Blues") #self.util.nova_figura(2) #ay = sns.heatmap(cm2, annot=True, fmt="d", cmap="Blues") #plt.show() # print(np.trace(cm2)) # print(np.sum(cm2)) return (np.trace(cm2) / np.sum(cm2))
def acc(semantic, pred): """ unsupervised clustering accuracy :param semantic: [N] :param pred: [N] :return: """ assert pred.size == semantic.size d = max(pred.max(), semantic.max()) + 1 w = np.zeros((d, d), dtype=np.int64) for i in range(pred.size): w[pred[i], semantic[i]] += 1 ind = linear_assignment(np.max(w) - w) return sum([w[i, j] for i, j in zip(ind[0], ind[1])]) * 1.0 / pred.size, w
def associate(self, det_bboxes, trackers): # Hungarian algorithm for association target_bboxes = tracker2box(trackers) iou = compute_iou(target_bboxes, det_bboxes) T_inds, D_inds = linear_assignment(iou.cpu().numpy(), maximize=True) T_inds, D_inds = torch.from_numpy(T_inds), torch.from_numpy(D_inds) # Filter low IoU matched valid = iou[T_inds, D_inds] > self.IOU_MIN T_inds = T_inds[valid] D_inds = D_inds[valid] trackers = [trackers[i] for i in T_inds] observations = [det_bboxes[i] for i in D_inds] return trackers, observations, T_inds, D_inds, iou
def associate_detections_to_trackers(detections, trackers, iou_threshold=0.3): """ Assigns detections to tracked object (both represented as bounding boxes) Returns 3 lists of matches, unmatched_detections and unmatched_trackers """ if (len(trackers) == 0): return np.empty( (0, 2), dtype=int), np.arange(len(detections)), np.empty((0, 5), dtype=int) iou_matrix = np.zeros((len(detections), len(trackers)), dtype=np.float32) for d, det in enumerate(detections): for t, trk in enumerate(trackers): iou_matrix[d, t] = iou(det, trk) matched_indices = linear_assignment(-iou_matrix) matched_indices = np.vstack(matched_indices).transpose() # import pdb # pdb.set_trace() unmatched_detections = [] for d, det in enumerate(detections): if (d not in matched_indices[:, 0]): unmatched_detections.append(d) unmatched_trackers = [] for t, trk in enumerate(trackers): if (t not in matched_indices[:, 1]): unmatched_trackers.append(t) #filter out matched with low IOU matches = [] for m in matched_indices: if (iou_matrix[m[0], m[1]] < iou_threshold): unmatched_detections.append(m[0]) unmatched_trackers.append(m[1]) else: # import pdb # pdb.set_trace() matches.append(m.reshape(1, 2)) if (len(matches) == 0): matches = np.empty((0, 2), dtype=int) else: matches = np.concatenate(matches, axis=0) return matches, np.array(unmatched_detections), np.array( unmatched_trackers)
def associate_detections_to_trackers(detections, trackers, iou_threshold=0.3): """ Assigns detections to tracked object (both represented as bounding boxes) Returns 3 lists of matches, unmatched_detections and unmatched_trackers """ if (len(trackers) == 0) or (len(detections) == 0): return np.empty( (0, 2), dtype=int), np.arange(len(detections)), np.empty((0, 5), dtype=int) iou_matrix = np.zeros((len(detections), len(trackers)), dtype=np.float32) for d, det in enumerate(detections): for t, trk in enumerate(trackers): iou_matrix[d, t] = iou(det, trk) matched_indices = linear_assignment(-iou_matrix) # scipy returns tuple # standardize output to match sklearn implementation if using scipy if sk == False: row, col = matched_indices matched_indices = np.concatenate( (row.reshape(-1, 1), col.reshape(-1, 1)), axis=1) unmatched_detections = [] for d, det in enumerate(detections): if (d not in matched_indices[:, 0]): unmatched_detections.append(d) unmatched_trackers = [] for t, trk in enumerate(trackers): if (t not in matched_indices[:, 1]): unmatched_trackers.append(t) #filter out matched with low IOU matches = [] for m in matched_indices: if (iou_matrix[m[0], m[1]] < iou_threshold): unmatched_detections.append(m[0]) unmatched_trackers.append(m[1]) else: matches.append(m.reshape(1, 2)) if (len(matches) == 0): matches = np.empty((0, 2), dtype=int) else: matches = np.concatenate(matches, axis=0) return matches, np.array(unmatched_detections), np.array( unmatched_trackers)
def reorder_labels(labels): nClusters = sp.int32(sp.amax(labels.flatten()) + 1) labels0_vec = sp.zeros((labels.shape[0], nClusters), 'bool') labelsi_vec = labels0_vec.copy() for i in range(nClusters): labels0_vec[:, i] = (labels[:, 0] == i) for i in range(labels.shape[1]): for j in range(nClusters): labelsi_vec[:, j] = (labels[:, i] == j) D = pairwise_distances(labelsi_vec.T, labels0_vec.T, metric='dice') D[~sp.isfinite(D)] = 1 ind1 = linear_assignment(D) labels[:, i] = ind1[sp.int16(labels[:, i]), 1] return labels