Esempio n. 1
0
def _cv2_estimate_E_with_intrinsics(cfg, matches, kps1, kps2, calib1, calib2):
    '''Estimate the Essential matrix from correspondences. Assumes known
    intrinsics.
    '''

    # Reference: https://docs.opencv.org/3.4.7/d9/d0c/group__calib3d.html
    # Defalt values for confidence: 0.99 (F), 0.999 (E)
    # Default value for the reprojection threshold: 3
    cur_key = 'config_{}_{}'.format(cfg.dataset, cfg.task)
    geom = cfg.method_dict[cur_key]['geom']
    if geom['method'].lower() == 'cv2-ransac-e':
        cv_method = 'FM_RANSAC'
        cv_threshold = geom['threshold']
        cv_confidence = geom['confidence']
    elif geom['method'].lower() == 'cv2-lmeds-e':
        cv_method = 'FM_LMEDS'
        cv_threshold = None
        cv_confidence = geom['confidence']
    else:
        raise ValueError('Unknown method to estimate E')

    is_valid, matches, kp1, kp2 = _preprocess(matches, kps1, kps2, 5)
    if not is_valid:
        return _fail()

    # Normalize keypoints with ground truth intrinsics
    kp1_n = normalize_keypoints(kp1, calib1['K'])
    kp2_n = normalize_keypoints(kp2, calib2['K'])

    cv2.setRNGSeed(cfg.opencv_seed)
    E, mask_E = cv2.findEssentialMat(kp1_n,
                                     kp2_n,
                                     method=getattr(cv2, cv_method),
                                     threshold=cv_threshold,
                                     prob=cv_confidence)
    mask_E = mask_E.astype(bool).flatten()

    # OpenCV can return multiple values as 6x3 or 9x3 matrices
    if E is None:
        return _fail()
    elif E.shape[0] != 3:
        Es = np.split(E, len(E) / 3)
    # Or a single matrix
    else:
        Es = [E]

    # Find the best E
    E, num_inlier = None, 0
    # mask_E_cheirality_check = None
    for _E in Es:
        _num_inlier, _R, _t, _mask = cv2.recoverPose(_E, kp1_n[mask_E],
                                                     kp2_n[mask_E])
        if _num_inlier >= num_inlier:
            num_inlier = _num_inlier
            E = _E
            # This is unused for now
            # mask_E_cheirality_check = _mask.flatten().astype(bool)

    indices = matches[:, mask_E.flatten()]
    return E, indices
Esempio n. 2
0
def _cmp_estimate_E_without_intrinsics(cfg,
                                       matches,
                                       kps1,
                                       kps2,
                                       calib1,
                                       calib2,
                                       img1_fname=None,
                                       img2_fname=None,
                                       scales1=None,
                                       scales2=None,
                                       ori1=None,
                                       ori2=None,
                                       A1=None,
                                       A2=None):
    '''Estimate the Essential matrix from correspondences. Computes the
    Fundamental Matrix first and then retrieves the Essential matrix assuming
    known intrinsics.
    '''

    cur_key = 'config_{}_{}'.format(cfg.dataset, cfg.task)
    geom = cfg.method_dict[cur_key]['geom']

    min_matches = 8
    is_valid, matches, kp1, kp2 = _preprocess(matches, kps1, kps2, min_matches)
    if not is_valid:
        return _fail()

    if geom['method'] == 'cmp-degensac-f-laf':
        sc1 = scales1[matches[0]]
        sc2 = scales2[matches[1]]
        ang1 = ori1[matches[0]]
        ang2 = ori2[matches[1]]
        if A1 is not None:
            A1 = A1[matches[0]]
            A2 = A2[matches[1]]
        else:
            A1 = None
            A2 = None
        laf1 = get_LAF(kp1, sc1, ang1, A1)
        laf2 = get_LAF(kp2, sc2, ang2, A2)
        # print (laf1[:2])
        # print (laf2[:2])
        F, mask_F = pyransac.findFundamentalMatrix(
            laf1,
            laf2,
            geom['threshold'],
            geom['confidence'],
            geom['max_iter'],
            2.0,
            error_type=geom['error_type'],
            symmetric_error_check=True,
            enable_degeneracy_check=geom['degeneracy_check'])
    elif geom['method'] == 'cmp-degensac-f':
        F, mask_F = pyransac.findFundamentalMatrix(
            kp1,
            kp2,
            geom['threshold'],
            geom['confidence'],
            geom['max_iter'],
            0,
            error_type=geom['error_type'],
            symmetric_error_check=True,
            enable_degeneracy_check=geom['degeneracy_check'])
    elif geom['method'] == 'cmp-gc-ransac-f':
        F, mask_F = pygcransac.findFundamentalMatrix(kp1, kp2,
                                                     geom['threshold'],
                                                     geom['confidence'],
                                                     geom['max_iter'])
    elif geom['method'] == 'cmp-magsac-f':
        F, mask_F = pymagsac.findFundamentalMatrix(kp1, kp2, geom['threshold'],
                                                   geom['confidence'],
                                                   geom['max_iter'])
    else:
        raise ValueError('Unknown method: {}'.format(geom['method']))

    mask_F = mask_F.astype(bool).flatten()

    # OpenCV can return multiple values as 6x3 or 9x3 matrices
    if F is None:
        return _fail()
    elif F.shape[0] != 3:
        Fs = np.split(F, len(F) / 3)
    else:
        Fs = [F]
    if mask_F.sum() < 8:
        return _fail()

    # Find the best F
    K1, K2 = calib1['K'], calib2['K']
    kp1n = normalize_keypoints(kp1, K1)
    kp2n = normalize_keypoints(kp2, K2)
    E, num_inlier = None, 0
    # mask_E_cheirality_check = None
    for _F in Fs:
        _E = np.matmul(np.matmul(K2.T, _F), K1)
        _E = _E.astype(np.float64)
        _num_inlier, _R, _t, _mask = cv2.recoverPose(_E, kp1n[mask_F],
                                                     kp2n[mask_F])
        if _num_inlier >= num_inlier:
            num_inlier = _num_inlier
            E = _E
            # This is unused for now
            # mask_E_cheirality_check = _mask.flatten().astype(bool)

    # Return the initial list of matches (from F)
    indices = matches[:, mask_F.flatten()]
    return E, indices
Esempio n. 3
0
def _cmp_estimate_E_with_intrinsics(cfg,
                                    matches,
                                    kps1,
                                    kps2,
                                    calib1,
                                    calib2,
                                    img1_fname=None,
                                    img2_fname=None):
    '''Estimate the Essential matrix from correspondences. Assumes known
    intrinsics.
    '''

    # Reference: https://docs.opencv.org/3.4.7/d9/d0c/group__calib3d.html
    # Defalt values for confidence: 0.99 (F), 0.999 (E)
    # Default value for the reprojection threshold: 3
    # (We set them to -1 when not applicable as OpenCV complains otherwise)

    is_valid, matches, kp1, kp2 = _preprocess(matches, kps1, kps2, 5)
    if not is_valid:
        return _fail()

    # Normalize keypoints with ground truth intrinsics
    kp1_n = normalize_keypoints(kp1, calib1['K'])
    kp2_n = normalize_keypoints(kp2, calib2['K'])
    if img1_fname is not None:
        s = (cv2.imread(img1_fname)).size
        h1, w1 = s[0], s[1]
        s = (cv2.imread(img2_fname)).size
        h2, w2 = s[0], s[1]
    else:
        raise ValueError('Requires image filenames')

    cv2.setRNGSeed(cfg.opencv_seed)
    E, mask_E = pygcransac.findEssentialMatrix(kp1, kp2, calib1['K'],
                                               calib2['K'], h1, w1, h2, w2,
                                               cfg.method_geom['threshold'],
                                               cfg.method_geom['confidence'],
                                               cfg.method_geom['max_iter'])
    mask_E = mask_E.astype(bool).flatten()

    # OpenCV can return multiple values as 6x3 or 9x3 matrices
    if E is None:
        return _fail()
    elif E.shape[0] != 3:
        Es = np.split(E, len(E) / 3)
    # Or a single matrix
    else:
        Es = [E]

    # Find the best E
    E, num_inlier = None, 0
    # mask_E_cheirality_check = None
    for _E in Es:
        _num_inlier, _R, _t, _mask = cv2.recoverPose(_E, kp1_n[mask_E],
                                                     kp2_n[mask_E])
        if _num_inlier >= num_inlier:
            num_inlier = _num_inlier
            E = _E
            # This is unused for now
            # mask_E_cheirality_check = _mask.flatten().astype(bool)

    indices = matches[:, mask_E.flatten()]
    return E, indices
Esempio n. 4
0
def _skimage_estimate_E_without_intrinsics(cfg, matches, kps1, kps2, calib1,
                                           calib2):
    '''Estimate the Essential matrix from correspondences. Computes the
    Fundamental Matrix first and then retrieves the Essential matrix assuming
    known intrinsics.
    '''

    # Reference: https://docs.opencv.org/3.4.7/d9/d0c/group__calib3d.html
    # Defalt values for confidence: 0.99 (F), 0.999 (E)
    # Default value for the reprojection threshold: 3
    # (We set them to -1 when not applicable as OpenCV complains otherwise)
    method_geom = cfg.method_geom['method']
    if method_geom.lower() == 'skimage-ransac-f':
        min_matches = 9
        cv_reprojection_threshold = cfg.method_geom['threshold']
        cv_confidence = cfg.method_geom['confidence']
        max_iters = cfg.method_geom['max_iter']
    else:
        raise ValueError('Unknown method to estimate F')

    is_valid, matches, kp1, kp2 = _preprocess(matches, kps1, kps2, min_matches)
    if not is_valid:
        return _fail()
    if len(kp1) < 9:
        return _fail()
    try:
        F, mask_F = skransac((kp1, kp2),
                             FundamentalMatrixTransform,
                             min_samples=8,
                             residual_threshold=cv_reprojection_threshold,
                             max_trials=max_iters,
                             stop_probability=cv_confidence)
    except Exception:
        return _fail()

    mask_F = mask_F.astype(bool).flatten()
    F = F.params
    # OpenCV can return multiple values as 6x3 or 9x3 matrices
    if F is None:
        return _fail()
    elif F.shape[0] != 3:
        Fs = np.split(F, len(F) / 3)
    else:
        Fs = [F]

    # Find the best F
    K1, K2 = calib1['K'], calib2['K']
    kp1n = normalize_keypoints(kp1, K1)
    kp2n = normalize_keypoints(kp2, K2)
    E, num_inlier = None, 0
    # mask_E_cheirality_check = None
    for _F in Fs:
        _E = np.matmul(np.matmul(K2.T, _F), K1)
        _E = _E.astype(np.float64)
        _num_inlier, _R, _t, _mask = cv2.recoverPose(_E, kp1n[mask_F],
                                                     kp2n[mask_F])
        if _num_inlier >= num_inlier:
            num_inlier = _num_inlier
            E = _E
            # This is unused for now
            # mask_E_cheirality_check = _mask.flatten().astype(bool)

    # Return the initial list of matches (from F)
    indices = matches[:, mask_F.flatten()]
    return E, indices
Esempio n. 5
0
def _cv2_estimate_E_without_intrinsics(cfg, matches, kps1, kps2, calib1,
                                       calib2):
    '''Estimate the Essential matrix from correspondences. Computes the
    Fundamental Matrix first and then retrieves the Essential matrix assuming
    known intrinsics.
    '''

    # Reference: https://docs.opencv.org/3.4.7/d9/d0c/group__calib3d.html
    # Defalt values for confidence: 0.99 (F), 0.999 (E)
    # Default value for the reprojection threshold: 3
    # (We set them to -1 when not applicable as OpenCV complains otherwise)
    cur_key = 'config_{}_{}'.format(cfg.dataset, cfg.task)
    geom = cfg.method_dict[cur_key]['geom']
    if geom['method'].lower() in ['cv2-ransac-f', 'cv2-patched-ransac-f']:
        min_matches = 8
        cv_method = 'FM_RANSAC'
        cv_reprojection_threshold = geom['threshold']
        cv_confidence = geom['confidence']
        if geom['method'].lower() == 'cv2-patched-ransac-f':
            cv_max_iter = geom['max_iter']
    elif geom['method'].lower() == 'cv2-lmeds-f':
        min_matches = 8
        cv_method = 'FM_LMEDS'
        cv_reprojection_threshold = -1
        cv_confidence = geom['confidence']
    elif geom['method'].lower() == 'cv2-7pt':
        # This should actually be *equal* to 7? We'll probably never use it...
        min_matches = 7
        cv_method = 'FM_7POINT'
        cv_reprojection_threshold = -1
        cv_confidence = -1
    elif geom['method'].lower() == 'cv2-8pt':
        min_matches = 8
        cv_method = 'FM_8POINT'
        cv_reprojection_threshold = -1
        cv_confidence = -1
    else:
        raise ValueError('Unknown method to estimate F')

    is_valid, matches, kp1, kp2 = _preprocess(matches, kps1, kps2, min_matches)
    if not is_valid:
        return _fail()

    cv2.setRNGSeed(cfg.opencv_seed)

    # Temporary fix to allow for patched opencv
    if geom['method'].lower() == 'cv2-patched-ransac-f':
        F, mask_F = cv2.findFundamentalMat(
            kp1,
            kp2,
            method=getattr(cv2, cv_method),
            ransacReprojThreshold=cv_reprojection_threshold,
            confidence=cv_confidence,
            maxIters=cv_max_iter)
    else:
        F, mask_F = cv2.findFundamentalMat(
            kp1,
            kp2,
            method=getattr(cv2, cv_method),
            ransacReprojThreshold=cv_reprojection_threshold,
            confidence=cv_confidence)
    mask_F = mask_F.astype(bool).flatten()

    # OpenCV can return multiple values as 6x3 or 9x3 matrices
    if F is None:
        return _fail()
    elif F.shape[0] != 3:
        Fs = np.split(F, len(F) / 3)
    else:
        Fs = [F]

    # Find the best F
    K1, K2 = calib1['K'], calib2['K']
    kp1n = normalize_keypoints(kp1, K1)
    kp2n = normalize_keypoints(kp2, K2)
    E, num_inlier = None, 0
    # mask_E_cheirality_check = None
    for _F in Fs:
        _E = np.matmul(np.matmul(K2.T, _F), K1)
        _E = _E.astype(np.float64)
        _num_inlier, _R, _t, _mask = cv2.recoverPose(_E, kp1n[mask_F],
                                                     kp2n[mask_F])
        if _num_inlier >= num_inlier:
            num_inlier = _num_inlier
            E = _E
            # This is unused for now
            # mask_E_cheirality_check = _mask.flatten().astype(bool)

    # Return the initial list of matches (from F)
    indices = matches[:, mask_F.flatten()]
    return E, indices