def get_inliers(loc1, desc1, loc2, desc2):
    n_feat1, n_feat2 = loc1.shape[0], loc2.shape[0]

    # from scipy.spatial import cKDTree
    KD_THRESH = 0.8
    d1_tree = cKDTree(desc1)
    distances, indices = d1_tree.query(desc2, distance_upper_bound=KD_THRESH)

    loc2_to_use = np.array(
        [loc2[i, ] for i in range(n_feat2) if indices[i] != n_feat1])
    loc1_to_use = np.array(
        [loc1[indices[i], ] for i in range(n_feat2) if indices[i] != n_feat1])

    np.random.seed(114514)

    # from skimage.measure import ransac as _ransac
    # from skimage.transform import AffineTransform
    model_robust, inliers = _ransac((loc1_to_use, loc2_to_use),
                                    AffineTransform,
                                    min_samples=3,
                                    residual_threshold=20,
                                    max_trials=1000)

    return sum(inliers)
예제 #2
0
def get_ransac_inlier(kp1, kp2, des1, des2,
                      is_binary_descriptor=False,
                      matcher_method="FLANN",
                      verification_method="opencv_ransac_6dof",
                      min_samples=3,
                      residual_threshold=5.0,
                      max_trials=1000):
    """
    Args:
      verification_method: "opencv_ransac_6dof", "scikit", "fsm_5dof"
    """
    des1 = sift_to_rootsift(des1)
    des2 = sift_to_rootsift(des2)
    matches = get_matches(des1, des2, matcher_method, is_binary_descriptor=False)
    if len(matches) < 5:
        # print("not enough matches: {}".format(len(matches)))
        return []

    # Perform geometric verification using RANSAC.
    if verification_method == "opencv_ransac_6dof":
        src_pts = np.float32([cv2.KeyPoint(kp1[m.queryIdx][0], kp1[m.queryIdx][1], 1).pt for m in matches ]).reshape(-1,1,2)
        dst_pts = np.float32([cv2.KeyPoint(kp2[m.trainIdx][0], kp2[m.trainIdx][1], 1).pt for m in matches ]).reshape(-1,1,2)

        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, residual_threshold)

        matchesMask = mask.ravel().tolist()

        inlier_idxs = np.nonzero(matchesMask)[0]
    elif verification_method == "scikit":
        locations_1_to_use = []
        locations_2_to_use = []
        for match in matches:
            locations_1_to_use.append((kp1[match.queryIdx].pt[1], kp1[match.queryIdx].pt[0])) # (row, col)
            locations_2_to_use.append((kp2[match.trainIdx].pt[1], kp2[match.trainIdx].pt[0]))

        locations_1_to_use = np.array(locations_1_to_use)
        locations_2_to_use = np.array(locations_2_to_use)
        _, inliers = _ransac(
        (locations_1_to_use, locations_2_to_use),
        AffineTransform,
        min_samples=min_samples,
        residual_threshold=residual_threshold,
        max_trials=max_trials)

        inlier_idxs = np.nonzero(inliers)[0]
    elif verification_method == "fsm_5dof":
        affine_matches = []
        # TODO: handle multi match.
        # when one key points matches multiple key points. check data structure for this and fsm.

        for match_idx, m in enumerate(matches):
            am = AffineMatch(m.queryIdx, kp1[m.queryIdx])

            feature2 = FeatureGeometryAffine()
            feature2.feature_id_ = m.trainIdx
            feature2.setPosition(kp2[m.trainIdx][0], kp2[m.trainIdx][1])
            feature2.a_ = kp2[m.trainIdx][2]
            feature2.b_ = kp2[m.trainIdx][3]
            feature2.c_ = kp2[m.trainIdx][4]

            am.features2.append(feature2)
            am.word_ids.append(m.trainIdx) # pass dummy word_id. We may don't use value for FSM.

            affine_matches.append(am)

        # TODO: check do we need sort by size of features2 (smaller first) for matches. for FSM
        # print("num matches:", len(affine_matches))
        match_list = affine_matches
        match_obj_list = []
        for m in affine_matches:
            match_obj_list.append(m.get_object())


        transform, inliers = fsmmatcher.perform_spatial_verification(match_obj_list)

        # print("transform from SFM:", transform)
        # print("num inliers from SFM:", len(inliers))

        inlier_idxs = []
        for match_idx, feature_idx in inliers:
            inlier_idxs.append(match_idx)
    else:
        raise Exception()

    inlier_match = []
    for idx in inlier_idxs:
        inlier_match.append(matches[idx])

    # print("num kp1: {}, kp2: {}, match: {}, inlier: {}".format(len(kp1), len(kp2), len(matches), len(inlier_match)))
    return inlier_match
예제 #3
0
def ransac(img1, img2, detector, descriptor_extractor, is_binary_descriptor,
           match_method, description):
    # find the keypoints and descriptors
    kp1 = detector.detect(img1, None)
    kp1, des1 = descriptor_extractor.compute(img1, kp1)
    print(len(kp1))
    kp2 = detector.detect(img2, None)
    kp2, des2 = descriptor_extractor.compute(img2, kp2)
    print(len(kp2))

    matches = get_matches(des1,
                          des2,
                          'BRUTE_FORCE',
                          is_binary_descriptor=is_binary_descriptor)
    matches = matches[:100]
    print(len(matches))
    print("------------------------------------------------------------")

    # # Draw matches. flag: cv2.DrawMatchesFlags.DRAW_RICH_KEYPOINTS 4
    # matching_img = cv2.drawMatches(img1, kp1, img2, kp2, matches, None, flags=0)
    # matching_img = cv2.cvtColor(matching_img, cv2.COLOR_BGR2RGB);

    # plt.figure(figsize=(16, 12))
    # plt.imshow(matching_img)
    # plt.show()

    locations_1_to_use = []
    locations_2_to_use = []

    for match in matches:
        locations_1_to_use.append((kp1[match.queryIdx].pt[1],
                                   kp1[match.queryIdx].pt[0]))  # (row, col)
        locations_2_to_use.append(
            (kp2[match.trainIdx].pt[1], kp2[match.trainIdx].pt[0]))

    locations_1_to_use = np.array(locations_1_to_use)
    locations_2_to_use = np.array(locations_2_to_use)

    # Perform geometric verification using RANSAC.
    model_robust, inliers = _ransac((locations_1_to_use, locations_2_to_use),
                                    AffineTransform,
                                    min_samples=5,
                                    residual_threshold=1,
                                    max_trials=1000)
    T, mask = cv2.findHomography(locations_1_to_use,
                                 locations_2_to_use,
                                 cv2.RANSAC,
                                 ransacReprojThreshold=3.0)
    #print  (T)
    inlier_idxs = np.nonzero(inliers)[0]

    inlier_match = []
    for idx in inlier_idxs:
        inlier_match.append(matches[idx])

    # Does ransac consider size and orientation of keypoints?
    ransac_img = cv2.drawMatches(img1,
                                 kp1,
                                 img2,
                                 kp2,
                                 inlier_match,
                                 None,
                                 flags=0)

    if inliers is None:
        score = 0
    else:
        score = len(inliers)

    return ransac_img, score
예제 #4
0
def get_ransac_inlier(kp1,
                      kp2,
                      des1,
                      des2,
                      is_binary_descriptor=False,
                      matcher_method="FLANN",
                      min_samples=3,
                      residual_threshold=5,
                      max_trials=1000):
    """
    """
    des1 = sift_to_rootsift(des1)
    des2 = sift_to_rootsift(des2)
    matches = get_matches(des1,
                          des2,
                          matcher_method,
                          is_binary_descriptor=False)
    if len(matches) < 5:
        # print("not enough matches: {}".format(len(matches)))
        return []

    # Perform geometric verification using RANSAC.
    # ransac_lib = "scikit"
    ransac_lib = "opencv"
    if ransac_lib == "opencv":
        src_pts = np.float32([kp1[m.queryIdx].pt
                              for m in matches]).reshape(-1, 1, 2)
        dst_pts = np.float32([kp2[m.trainIdx].pt
                              for m in matches]).reshape(-1, 1, 2)

        M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC, 5.0)
        matchesMask = mask.ravel().tolist()
        # print(matchesMask)
        inlier_idxs = np.nonzero(matchesMask)[0]
    elif ransac_lib == "scikit":
        locations_1_to_use = []
        locations_2_to_use = []
        for match in matches:
            locations_1_to_use.append(
                (kp1[match.queryIdx].pt[1],
                 kp1[match.queryIdx].pt[0]))  # (row, col)
            locations_2_to_use.append(
                (kp2[match.trainIdx].pt[1], kp2[match.trainIdx].pt[0]))

        locations_1_to_use = np.array(locations_1_to_use)
        locations_2_to_use = np.array(locations_2_to_use)
        _, inliers = _ransac((locations_1_to_use, locations_2_to_use),
                             AffineTransform,
                             min_samples=min_samples,
                             residual_threshold=residual_threshold,
                             max_trials=max_trials)

        inlier_idxs = np.nonzero(inliers)[0]

    inlier_match = []
    for idx in inlier_idxs:
        inlier_match.append(matches[idx])

    print("num kp1: {}, kp2: {}, match: {}, inlier: {}".format(
        len(kp1), len(kp2), len(matches), len(inlier_match)))
    return inlier_match