def hausdorff_distance(estimate, truth, linestring_lookup): l_coords = curve_to_coords(estimate, linestring_lookup) r_coords = curve_to_coords(truth, linestring_lookup) return max(directed_hausdorff(l_coords, r_coords), directed_hausdorff(r_coords, l_coords), key=lambda x: x[0])[0]
def hausdorff_dist(seg_calc, seg_real, img_calc, img_real): positions_real_fin = [] positions_calc_fin = [] space_calc = img_calc.GetSpacing() space_real = img_real.GetSpacing() #Calculate coordinates for predicated/calculated image calc_slice = find_boundaries(seg_calc) positions_calc = zip(*np.where(calc_slice > 0)) positions_calc = list(positions_calc) positions_calc = np.array(positions_calc) positions_calc = (positions_calc * [space_calc[0], space_calc[1], space_calc[2]]) positions_calc = (positions_calc).tolist() positions_calc_fin.append(positions_calc) #Calculate coordinates for real image real_slice = find_boundaries(seg_real) positions_real = zip(*np.where(real_slice > 0)) positions_real = list(positions_real) positions_real = np.array(positions_real) positions_real = (positions_real * [space_real[0], space_real[1], space_real[2]]) positions_real = positions_real.tolist() positions_real_fin.append(positions_real) #Find Hausdorff distance in both directions dh_pc_pr = (directed_hausdorff(positions_calc, positions_real)[0]) dh_pr_pc = (directed_hausdorff(positions_real, positions_calc)[0]) dh = max(dh_pc_pr, dh_pr_pc) return dh
def distance_between(A: traja.TrajaDataFrame, B: traja.TrajaDataFrame, method="dtw"): """Returns distance between two trajectories. Args: A (:class:`~traja.frame.TrajaDataFrame`) : Trajectory 1 B (:class:`~traja.frame.TrajaDataFrame`) : Trajectory 2 method (str): ``dtw`` for dynamic time warping, ``hausdorff`` for Hausdorff Returns: distance (float): Distance """ if method == "hausdorff": dist0 = directed_hausdorff(A, B)[0] dist1 = directed_hausdorff(B, A)[0] symmetric_dist = max(dist0, dist1) return symmetric_dist elif method == "dtw": try: from fastdtw import fastdtw except ImportError: raise ImportError(""" Missing optional dependency 'fastdtw'. Install fastdtw for dynamic time warping distance with pip install fastdtw. """) distance, path = fastdtw(A, B, dist=euclidean) return distance
def test_symmetry(self): # Ensure that the directed (asymmetric) Hausdorff distance is # actually asymmetric forward = directed_hausdorff(self.path_1, self.path_2)[0] reverse = directed_hausdorff(self.path_2, self.path_1)[0] assert_(forward != reverse)
def hausdorff_distance(input, target): _, result = input.max(1) result = torch.squeeze(result) target = torch.squeeze(target) result_np = result.data.cpu().numpy() label_np = target.data.cpu().numpy() output_indexes = np.where(result_np == 1.0) sitk_output = sitk.GetImageFromArray(result_np) label_indexes = np.where(label_np == 1.0) sitk_label = sitk.GetImageFromArray(label_np) if (result_np.sum()==0) or (label_np.sum()==0): h_dist = 0 else: # Note the reversed order of access between SimpleITK and numpy (z,y,x) if len(output_indexes) == 3: physical_points_output = [sitk_output.TransformIndexToPhysicalPoint([int(x), int(y), int(z)]) \ for z,y,x in zip(output_indexes[0], output_indexes[1], output_indexes[2])] physical_points_label = [sitk_label.TransformIndexToPhysicalPoint([int(x), int(y), int(z)]) \ for z,y,x in zip(label_indexes[0], label_indexes[1], label_indexes[2])] if len(output_indexes) == 2: physical_points_output = [sitk_output.TransformIndexToPhysicalPoint([int(x), int(y)]) \ for y,x in zip(output_indexes[0], output_indexes[1])] physical_points_label = [sitk_label.TransformIndexToPhysicalPoint([int(x), int(y)]) \ for y,x in zip(label_indexes[0], label_indexes[1])] h_dist_lo, u_ind, v_ind = directed_hausdorff(u = physical_points_label, v = physical_points_output) h_dist_ol, u_ind, v_ind = directed_hausdorff(u = physical_points_output, v = physical_points_label) h_dist = max(h_dist_lo, h_dist_ol) return h_dist
def set_convolution_matrix(self, gac_img, doctor_result): from math import sqrt from numpy import ravel, corrcoef from scipy.spatial.distance import directed_hausdorff import numpy as np # Sum and subtract two images img_sum = np.add(gac_img, doctor_result) img_sub = np.subtract(gac_img, doctor_result) # True (positive and negative) and False (positive and negative) tp = np.float(np.sum((img_sum == 2).nonzero(), dtype=np.int32)) tn = np.float(np.sum((img_sum == 0).nonzero(), dtype=np.int32)) fp = np.float(np.sum((img_sub < 0).nonzero(), dtype=np.int32)) fn = np.float(np.sum((img_sub > 0).nonzero(), dtype=np.int32)) # Hausdorff equation conf_temp = corrcoef(ravel(gac_img), ravel(doctor_result)) u = directed_hausdorff(doctor_result, gac_img)[0] v = directed_hausdorff(gac_img, doctor_result)[0] # Other metrics equations self.precision = tp / (tp + fp) self.recall = tp / (tp + fn) self.dice = (2 * tp) / ((2 * tp) + (fp + fn)) self.sens = tp / (tp + fn) self.spec = tn / (tn + fp) self.jacc = tp / (fp + fn + tp) self.accu = (tp + tn) / (tp + tn + fp + fn) self.f1sc = 2 * ((self.precision * self.recall) / (self.precision + self.recall)) self.matt = ((tp * tn) - (fp * fn)) / sqrt( (tp + fp) * (tp + fn) * (tn + fp) * (tn + fn)) self.conf = conf_temp[0, 1] self.haus = max(u, v)
def click_event(event, x, y, flags, params): # checking for left mouse clicks if event == cv2.EVENT_LBUTTONDOWN: reference_image_path = "shapes_pat.png" landscape_image_path = "shapes.jpg" ref_image = cv2.imread(reference_image_path,0) landscape_image = cv2.imread(landscape_image_path,0) print(f"check for x = {x} , y = {y}") landcape_sample = copy.deepcopy(ref_image) n, m = ref_image.shape[:2] RGB = False for i in range(0, n): for j in range(0, m): I = int(y + i - n / 2) J = int(x + j - m / 2) try: if RGB: landcape_sample[i, j, :] = landscape_image[I, J, :] else: landcape_sample[i, j] = landscape_image[I, J] except IndexError: sys.exit(7) result = 0 if RGB: for k in range(0, 3): result += max(directed_hausdorff(landcape_sample[:, :, k], ref_image[:, :, k])[0], directed_hausdorff(ref_image[:, :, k], landcape_sample[:, :, k])[0]) else: result = max(directed_hausdorff(landcape_sample, ref_image)[0], directed_hausdorff(ref_image, landcape_sample)[0]) print(f"RESULT = {result}")
def Hausdorff(A, B): """ Calculates the Hausdorff distance between a pair of bags (videos), and returns the distance. """ h1 = directed_hausdorff(A, B)[0] h2 = directed_hausdorff(B, A)[0] return max((h1, h2))
def hausdorff_distance(x, y): """ Hausdorff distance between two segmentations :param x: array :param y: array :return: the hausdorff distance """ # binarize x = x > 0.5 y = y > 0.5 hd_0 = 0 hd_1 = 0 hd = 0 for i in range(x.shape[0]): hd_0 += directed_hausdorff(x[i, ...], y[i, ...])[0] hd_1 += directed_hausdorff(y[i, ...], x[i, ...])[0] hd += max(hd_0, hd_1) hd_0 /= x.shape[0] hd_1 /= x.shape[0] hd /= x.shape[0] return hd, hd_0, hd_1
def HausdorffDist(A, B): # D_mat = np.sqrt(inner1d(A,A)[np.newaxis].T + inner1d(B,B)-2*(np.dot(A,B.T))) # dH = np.max(np.array([np.max(np.min(D_mat,axis=0)),np.max(np.min(D_mat,axis=1))])) # return(dH) d_forward = directed_hausdorff(A, B)[0] d_backward = directed_hausdorff(B, A)[0] return max(d_forward, d_backward)
def HausforffDistance(x1, x2): # https://docs.scipy.org/doc/scipy/reference/generated/scipy.spatial.distance.directed_hausdorff.html from scipy.spatial.distance import directed_hausdorff if type(x1) == Variable: distance = directed_hausdorff(x1.cpu().data.numpy(), x2.cpu().data.numpy()) elif type(x1) == torch.cuda.FloatTensor: distance = directed_hausdorff(x1.cpu().numpy(), x2.cpu().numpy())
def numpy_haussdorf(pred: np.ndarray, target: np.ndarray) -> float: assert len(pred.shape) == 2 assert pred.shape == target.shape return max( directed_hausdorff(pred, target)[0], directed_hausdorff(target, pred)[0])
def re_ranking(input_feature_source, input_feature, k=20, lambda_value=0.1, MemorySave=False, Minibatch=2000): ##rerank_plain all_num_source = input_feature_source.shape[0] all_num = input_feature.shape[0] feat = input_feature.astype(np.float16) print('computing source distance...') sour_tar_dist = cdist(input_feature,input_feature_source) source_dist_vec = np.min(sour_tar_dist, axis = 1) source_dist_vec = source_dist_vec / np.max(source_dist_vec) source_dist = np.zeros([all_num, all_num]) for i in range(all_num): source_dist[i,:] = source_dist_vec + source_dist_vec[i] del sour_tar_dist del source_dist_vec print('computing original distance...') if MemorySave: original_dist = np.zeros(shape=[all_num, all_num], dtype=np.float16) i = 0 while True: it = i + Minibatch if it < np.shape(feat)[0]: original_dist[i:it, ] = np.power( cdist(feat[i:it, ], feat), 2).astype(np.float16) else: original_dist[i:, :] = np.power( cdist(feat[i:, ], feat), 2).astype(np.float16) break i = it else: original_dist = cdist(feat, feat).astype(np.float16) original_dist = np.power(original_dist, 2).astype(np.float16) del feat euclidean_dist = original_dist/np.max(original_dist) ## compute k-nn of each instance knn_bool = np.zeros([all_num,all_num],dtype=bool) for i in range(all_num): tem_vec = original_dist[i,:] kThreshold = np.partition(tem_vec,k-1,)[k-1] knn_bool[i,:] = (tem_vec <= kThreshold) knn_bool[i,i] = False del tem_vec # new added for compute hausdorff distance matrix hausdorff_dist = np.zeros([all_num,all_num], dtype=np.float64) for i in range(all_num): u_set = input_feature[knn_bool[i]] for j in range(i+1, all_num): v_set = input_feature[knn_bool[j]] hausdorff_dist[i,j] = max(directed_hausdorff(u_set, v_set)[0], directed_hausdorff(v_set, u_set)[0]) hausdorff_dist[j,i] = hausdorff_dist[i,j] hausdorff_dist = hausdorff_dist/np.max(hausdorff_dist) final_dist = hausdorff_dist*(1-lambda_value) + source_dist*lambda_value del original_dist del hausdorff_dist return euclidean_dist, final_dist
def hausdorff_distance(curve1, curve2, n_sampling): s1 = np.floor(np.linspace(0, len(curve1) - 1, n_sampling)).astype(int) s2 = np.floor(np.linspace(0, len(curve2) - 1, n_sampling)).astype(int) u = curve1[s1] v = curve2[s2] curve_dist = max(directed_hausdorff(u, v)[0], directed_hausdorff(v, u)[0]) return curve_dist
def hausdorffDistance(ptsA, ptsB): hdAB = directed_hausdorff(ptsA, ptsB)[0] hdBA = directed_hausdorff(ptsB, ptsA)[0] hd = np.max([hdAB, hdBA]) return hd
def test_invalid_dimensions(self): # Ensure that a ValueError is raised when the number of columns # is not the same np.random.seed(1234) A = np.random.rand(3, 2) B = np.random.rand(4, 5) with pytest.raises(ValueError): directed_hausdorff(A, B)
def compute_hausdorff_dist(self, traj1, traj2): """ double side hausdorff distance """ # import ipdb;ipdb.set_trace() dist1 = directed_hausdorff(traj1, traj2)[0] dist2 = directed_hausdorff(traj2, traj1)[0] return max(dist1, dist2)
def get_hausdorff(y_true, y_prediction): ''' Here is the directed Hausdorff distance, but it computes both directions and output the larger value ''' Hausdorff = max( directed_hausdorff(y_true, y_prediction)[0], directed_hausdorff(y_prediction, y_true)[0]) return Hausdorff
def post(self, request, format=None): json_request = json.loads(request.body.decode(encoding='UTF-8')) features = [feature['name'] for feature in json_request['features']] target = json_request['target']['name'] sensitive_attr = json_request['sensitiveAttr']['name'] raw_df = open_dataset('./data/themis_ml_raw_sample.csv') whole_dataset_df = open_dataset(sample_file_path) X = whole_dataset_df[features] X_wo_s_attr = whole_dataset_df[features] y = whole_dataset_df[target] s = whole_dataset_df[sensitive_attr] # male:0, female: 1 for feature in features: X[feature] = X[feature].astype(float) is_categorical_feature_list = [] for feature in features: if feature in numerical_features: is_categorical_feature_list.append(False) else: is_categorical_feature_list.append(True) d = gower_distances(X, categorical_features=is_categorical_feature_list) df_tsne_result = pd.DataFrame( TSNE(n_components=2, metric='precomputed', random_state=3).fit_transform(d), X.index) df_tsne_result['idx'] = whole_dataset_df['idx'] df_tsne_result['group'] = s df_tsne_result['target'] = y df_tsne_result.columns = ['dim1', 'dim2', 'idx', 'group', 'target'] df_tsne_result['dim1'] = (df_tsne_result['dim1'] - min( df_tsne_result['dim1'])) / (max(df_tsne_result['dim1']) - min(df_tsne_result['dim1'])) df_tsne_result['dim2'] = (df_tsne_result['dim2'] - min( df_tsne_result['dim2'])) / (max(df_tsne_result['dim2']) - min(df_tsne_result['dim2'])) df_group0 = df_tsne_result[df_tsne_result['group'] == 0] df_group1 = df_tsne_result[df_tsne_result['group'] == 1] hausdorff_distance = directed_hausdorff(df_group0[['dim1', 'dim2']], df_group1[['dim1', 'dim2']]) hausdorff_distance2 = directed_hausdorff(df_group1[['dim1', 'dim2']], df_group0[['dim1', 'dim2']]) return Response( json.dumps({ 'inputSpaceDist': max(hausdorff_distance[0], hausdorff_distance2[0]), 'dimReductions': df_tsne_result.to_json(orient='index') }))
def test_random_state(self): # ensure that the global random state is not modified because # the directed Hausdorff algorithm uses randomization rs = check_random_state(None) old_global_state = rs.get_state() directed_hausdorff(self.path_1, self.path_2) rs2 = check_random_state(None) new_global_state = rs2.get_state() assert_equal(new_global_state, old_global_state)
def hausdorff_distance(output, label): coor_label = np.where(label == 1) coor_label = np.asarray(coor_label).T coor_output = np.where(output == 1) coor_output = np.asarray(coor_output).T d_ab = directed_hausdorff(coor_label, coor_output)[0] d_ba = directed_hausdorff(coor_output, coor_label)[0] hd_ab = max(d_ab, d_ba) return hd_ab
def test_it_correctly_computes_haussdorf_distance(input_arrays): XA, XB = input_arrays actual_dist = hausdorff_distance(XA, XB, distance="euclidean") expected_dist = max( directed_hausdorff(XA, XB)[0], directed_hausdorff(XB, XA)[0]) np.testing.assert_almost_equal(expected_dist, actual_dist)
def test_random_state_None_int(self, seed): # check that seed values of None or int do not alter global # random state rs = check_random_state(None) old_global_state = rs.get_state() directed_hausdorff(self.path_1, self.path_2, seed) rs2 = check_random_state(None) new_global_state = rs2.get_state() assert_equal(new_global_state, old_global_state)
def test_invalid_dimensions(self): # Ensure that a ValueError is raised when the number of columns # is not the same rng = np.random.default_rng(189048172503940875434364128139223470523) A = rng.random((3, 2)) B = rng.random((3, 5)) msg = r"need to have the same number of columns" with pytest.raises(ValueError, match=msg): directed_hausdorff(A, B)
def calculate_hausdroff(component1,component2): number_points = np.shape(component1)[0] factor = 0 for i in range(0,number_points): factor = factor + max(directed_hausdorff(u, v)[i], directed_hausdorff(v, u)[i]) factor = factor/number_points return(factor)
def get_Hd_distance(truth, prediction): coor_truth = np.where(truth==1) coor_truth = np.asarray(coor_truth).T coor_preds = np.where(prediction==1) coor_preds = np.asarray(coor_preds).T d_ab = directed_hausdorff(coor_truth, coor_preds)[0] d_ba = directed_hausdorff(coor_preds, coor_truth)[0] hd_ab = max(d_ab, d_ba) return hd_ab
def novelty_score(airfoil_gen, airfoils_data): min_dist = np.inf for airfoil in tqdm(airfoils_data): dist_ab = directed_hausdorff(airfoil_gen, airfoil)[0] dist_ba = directed_hausdorff(airfoil, airfoil_gen)[0] dist = np.maximum(dist_ab, dist_ba) if dist < min_dist: min_dist = dist nearest_airfoil = airfoil return min_dist, nearest_airfoil
def test_random_state_None_int(self): # check that seed values of None or int do not alter global # random state for seed in [None, 27870671]: rs = check_random_state(None) old_global_state = rs.get_state() directed_hausdorff(self.path_1, self.path_2, seed) rs2 = check_random_state(None) new_global_state = rs2.get_state() assert_equal(new_global_state, old_global_state)
def get_hd(outputs, labels): ''' :param outputs: numpy array :param labels: numpy array :param threshold: defautl 0.5 :return: ''' hd1 = directed_hausdorff(outputs, labels)[0] hd2 = directed_hausdorff(outputs, labels)[0] return max(hd1, hd2)
def mean_hausdorff_distance(seg_pred, target): distances = np.zeros((4, )) for channel in range(seg_pred.size(1)): distances[channel] = max( directed_hausdorff( flatten(seg_pred[:, channel, ...]).cpu().detach().numpy(), flatten(target[:, channel, ...]).cpu().detach().numpy())[0], directed_hausdorff( flatten(target[:, channel, ...]).cpu().detach().numpy(), flatten(seg_pred[:, channel, ...]).cpu().detach().numpy())[0]) return distances
def __call__(self, y_true, y_pred, sample_weight=None): """Updates running mean of Hausdorff distances.""" y_pred = pred_to_one_hot(y_pred, self.data_format) y_true = tf.reshape(y_true, shape=(1, -1)) y_pred = tf.reshape(y_pred, shape=(1, -1)) haus_dist = tf.maximum( directed_hausdorff(y_true.numpy(), y_pred.numpy())[0], directed_hausdorff(y_pred.numpy(), y_true.numpy())[0]) return super(HausdorffDistance, self).update_state(haus_dist, sample_weight=sample_weight)
def test_indices(self): # Ensure that correct point indices are returned -- they should # correspond to the Hausdorff pair path_simple_1 = np.array([[-1,-12],[0,0], [1,1], [3,7], [1,2]]) path_simple_2 = np.array([[0,0], [1,1], [4,100], [10,9]]) actual = directed_hausdorff(path_simple_2, path_simple_1)[1:] expected = (2, 3) assert_array_equal(actual, expected)
def test_4d_data_reverse(self): # Ensure that 4D data is handled properly for a simple case # relative to brute force approach. actual = directed_hausdorff(self.path_2_4d, self.path_1_4d)[0] # brute force over columns: expected = max(np.amin(distance.cdist(self.path_1_4d, self.path_2_4d), axis=0)) assert_almost_equal(actual, expected, decimal=9)
def test_2d_data_forward(self): # Ensure that 2D data is handled properly for a simple case # relative to brute force approach. actual = directed_hausdorff(self.path_1[..., :2], self.path_2[..., :2])[0] expected = max(np.amin(distance.cdist(self.path_1[..., :2], self.path_2[..., :2]), axis=1)) assert_almost_equal(actual, expected, decimal=9)
def test_brute_force_comparison_reverse(self): # Ensure that the algorithm for directed_hausdorff gives the # same result as the simple / brute force approach in the # reverse direction. actual = directed_hausdorff(self.path_2, self.path_1)[0] # brute force over columns: expected = max(np.amin(distance.cdist(self.path_1, self.path_2), axis=0)) assert_almost_equal(actual, expected, decimal=9)
def handwriting_recognition(imagefile1,imagefile2): img1 = cv2.imread(imagefile1,0) ret,thresh1=cv2.threshold(img1,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) contours1,hierarchy1=cv2.findContours(thresh1,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE) #contours1=cv2.findContours(thresh1,1,2) epsilon1 = 0.1*cv2.arcLength(contours1[0],True) #epsilon1=0.2 approx1 = cv2.approxPolyDP(contours1[0],epsilon1,True) print approx1 img2 = cv2.imread(imagefile2,0) ret,thresh2=cv2.threshold(img2,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) contours2,hierarchy2=cv2.findContours(thresh2,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE) #contours2=cv2.findContours(thresh2,1,2) epsilon2 = 0.1*cv2.arcLength(contours2[0],True) #epsilon2=0.2 approx2 = cv2.approxPolyDP(contours2[0],epsilon2,True) print approx2 print "Distance between DP polynomials approximating two handwriting contours:", directed_hausdorff(approx1[0],approx2[0])
def time_directed_hausdorff(self, num_points): # time directed_hausdorff code in 3 D distance.directed_hausdorff(self.points1, self.points2)
def test_degenerate_case(self): # The directed Hausdorff distance must be zero if both input # data arrays match. actual = directed_hausdorff(self.path_1, self.path_1)[0] assert_almost_equal(actual, 0.0, decimal=9)