def loss(self, anchor, positive, anchor_kp, positive_kp): """ HardNetNeiMask margin loss - calculates loss based on distance matrix based on positive distance and closest negative distance. if set C=0 the loss function is same as hard loss. """ "Input sizes between positive and negative must be equal." assert anchor.size() == positive.size() "Inputd must be a 2D matrix." assert anchor.dim() == 2 dist_matrix = distance_matrix_vector(anchor, positive) eye = torch.eye(dist_matrix.size(1)).to(dist_matrix.device) # steps to filter out same patches that occur in distance matrix as negatives pos = dist_matrix.diag() dist_without_min_on_diag = dist_matrix + eye * 10 # neighbor mask coo_dist_matrix = pairwise_distances( anchor_kp[:, 1:3].to(torch.float), anchor_kp[:, 1:3].to(torch.float) ).lt(self.C) dist_without_min_on_diag = ( dist_without_min_on_diag + coo_dist_matrix.to(torch.float) * 10 ) coo_dist_matrix = pairwise_distances( positive_kp[:, 1:3].to(torch.float), positive_kp[:, 1:3].to(torch.float) ).lt(self.C) dist_without_min_on_diag = ( dist_without_min_on_diag + coo_dist_matrix.to(torch.float) * 10 ) col_min = dist_without_min_on_diag.min(dim=1)[0] row_min = dist_without_min_on_diag.min(dim=0)[0] col_row_min = torch.min(col_min, row_min) # triplet loss hard_loss = torch.clamp(self.MARGIN + pos - col_row_min, min=0.0) hard_loss = hard_loss.mean() return hard_loss
def nearest_neighbor_match_score(des1, des2, kp1w, kp2, visible, COO_THRSH): des_dist_matrix = distance_matrix_vector(des1, des2) nn_value, nn_idx = des_dist_matrix.min(dim=-1) nn_kp2 = kp2.index_select(dim=0, index=nn_idx) coo_dist_matrix = pairwise_distances(kp1w[:, 1:3].float(), nn_kp2[:, 1:3].float()).diag() correct_match_label = coo_dist_matrix.le(COO_THRSH) * visible correct_matches = correct_match_label.sum().item() predict_matches = max(visible.sum().item(), 1) return correct_matches, predict_matches
def caluseful(kp1c_, kp2c_, homo12_, im2_data_, coo_t=5.0): kp2_ = torch.from_numpy(kp2c_).float() kp1w = torch.from_numpy(ptCltoCr(kp1c_, homo12_)).float() maxh, maxw = np.shape(im2_data_) # (1280 960) visible = kp1w[:, 0].lt(maxw) * kp1w[:, 1].lt(maxh) useful_ = visible.sum().item() coo_dist_matrix = pairwise_distances(kp1w, kp2_) visible = visible.unsqueeze(-1).repeat(1, coo_dist_matrix.size(1)) repeats_ = coo_dist_matrix.le(coo_t) repeatable_ = (repeats_ * visible).sum(dim=1).gt(0).sum().item() return repeatable_, max(useful_, 1)
def threshold_match_score(des1, des2, kp1w, kp2, visible, DES_THRSH, COO_THRSH): des_dist_matrix = distance_matrix_vector(des1, des2) visible = visible.unsqueeze(-1).repeat(1, des_dist_matrix.size(1)) predict_label = des_dist_matrix.lt(DES_THRSH) * visible coo_dist_matrix = pairwise_distances(kp1w[:, 1:3].float(), kp2[:, 1:3].float()) correspondences_label = coo_dist_matrix.le(COO_THRSH) * visible correct_match_label = predict_label * correspondences_label correct_matches = correct_match_label.sum().item() predict_matches = max(predict_label.sum().item(), 1) correspond_matches = max(correspondences_label.sum().item(), 1) return correct_matches, predict_matches, correspond_matches
def nearest_neighbor_distance_ratio_match_score( des1, des2, kp1w, kp2, visible, COO_THRSH, threshold=0.7 ): predict_label, nn_kp2 = nearest_neighbor_distance_ratio_match( des1, des2, kp2, threshold ) predict_label = predict_label * visible coo_dist_matrix = pairwise_distances( kp1w[:, 1:3].float(), nn_kp2[:, 1:3].float() ).diag() correspondences_label = coo_dist_matrix.le(COO_THRSH) * visible correct_match_label = predict_label * correspondences_label correct_matches = correct_match_label.sum().item() predict_matches = max(predict_label.sum().item(), 1) return correct_matches, predict_matches