diff --git a/s2p/__init__.py b/s2p/__init__.py index 90a472d0..34628448 100644 --- a/s2p/__init__.py +++ b/s2p/__init__.py @@ -23,7 +23,6 @@ import os.path import json import datetime -import subprocess import multiprocessing import numpy as np @@ -43,7 +42,6 @@ from s2p import triangulation from s2p import fusion from s2p import visualisation -from s2p import ply def pointing_correction(tile, i): @@ -63,7 +61,11 @@ def pointing_correction(tile, i): # correct pointing error print('correcting pointing on tile {} {} pair {}...'.format(x, y, i)) - A, m = pointing_accuracy.compute_correction(img1, img2, rpc1, rpc2, x, y, w, h) + method = 'relative' if cfg['relative_sift_match_thresh'] is True else 'absolute' + A, m = pointing_accuracy.compute_correction( + img1, img2, rpc1, rpc2, x, y, w, h, method, + cfg['sift_match_thresh'], cfg['max_pointing_error'] + ) if A is not None: # A is the correction matrix np.savetxt(os.path.join(out_dir, 'pointing.txt'), A, fmt='%6.3f') diff --git a/s2p/estimation.py b/s2p/estimation.py index 8d93d62f..5529748c 100644 --- a/s2p/estimation.py +++ b/s2p/estimation.py @@ -5,8 +5,6 @@ import numpy as np -from s2p import common - def fundamental_matrix_cameras(P1, P2): """ diff --git a/s2p/initialization.py b/s2p/initialization.py index 14fd0c73..6ead6feb 100644 --- a/s2p/initialization.py +++ b/s2p/initialization.py @@ -7,19 +7,15 @@ import sys import json import copy -import shutil import rasterio -import warnings import numpy as np import rpcm -from pyproj.exceptions import CRSError from s2p import common from s2p import geographiclib from s2p import rpc_utils from s2p import masking from s2p import parallel -from s2p import geographiclib from s2p.config import cfg # This function is here as a workaround to python bug #24313 When diff --git a/s2p/masking.py b/s2p/masking.py index 33b5f672..4f78b3bb 100644 --- a/s2p/masking.py +++ b/s2p/masking.py @@ -3,7 +3,6 @@ # Copyright (C) 2015, Enric Meinhardt # Copyright (C) 2015, Julien Michel -import os import subprocess import numpy as np import warnings diff --git a/s2p/pointing_accuracy.py b/s2p/pointing_accuracy.py index 1833fc5e..cca73149 100644 --- a/s2p/pointing_accuracy.py +++ b/s2p/pointing_accuracy.py @@ -6,7 +6,6 @@ import os import numpy as np -import rpcm from s2p import sift from s2p import rpc_utils @@ -100,7 +99,8 @@ def local_translation(r1, r2, x, y, w, h, m): return A -def compute_correction(img1, img2, rpc1, rpc2, x, y, w, h): +def compute_correction(img1, img2, rpc1, rpc2, x, y, w, h, + method, sift_thresh, epipolar_threshold): """ Computes pointing correction matrix for specific ROI @@ -113,13 +113,16 @@ def compute_correction(img1, img2, rpc1, rpc2, x, y, w, h): image. (x, y) is the top-left corner, and (w, h) are the dimensions of the rectangle. The ROI may be as big as you want. If bigger than 1 Mpix, only five crops will be used to compute sift matches. + method, sift_thresh, epipolar_threshold: see docstring of + s2p.sift.keypoints_match() Returns: a 3x3 matrix representing the planar transformation to apply to img2 in order to correct the pointing error, and the list of sift matches used to compute this correction. """ - m = sift.matches_on_rpc_roi(img1, img2, rpc1, rpc2, x, y, w, h) + m = sift.matches_on_rpc_roi(img1, img2, rpc1, rpc2, x, y, w, h, + method, sift_thresh, epipolar_threshold) if m is not None: A = local_translation(rpc1, rpc2, x, y, w, h, m) diff --git a/s2p/rectification.py b/s2p/rectification.py index 4ddaf5f3..c3bb4774 100644 --- a/s2p/rectification.py +++ b/s2p/rectification.py @@ -7,14 +7,12 @@ import warnings import numpy as np -import rpcm from s2p import rpc_utils from s2p import estimation from s2p import evaluation from s2p import common from s2p import visualisation -from s2p import block_matching from s2p.config import cfg @@ -297,7 +295,7 @@ def rectify_pair(im1, im2, rpc1, rpc2, x, y, w, h, out1, out2, A=None, sift_matc module. sift_matches (optional): Nx4 numpy array containing a list of sift matches, in the full image coordinates frame - method (default: 'rpc'): option to decide wether to use rpc of sift + method (default: 'rpc'): option to decide whether to use rpc of sift matches for the fundamental matrix estimation. {h,v}margin (optional): horizontal and vertical margins added on the sides of the rectified images diff --git a/s2p/rpc_utils.py b/s2p/rpc_utils.py index 85a25630..96b6c2ec 100644 --- a/s2p/rpc_utils.py +++ b/s2p/rpc_utils.py @@ -3,8 +3,6 @@ # Copyright (C) 2015, Enric Meinhardt -import json -import datetime import warnings import rasterio import numpy as np diff --git a/s2p/sift.py b/s2p/sift.py index 64732aeb..bddd53cd 100644 --- a/s2p/sift.py +++ b/s2p/sift.py @@ -12,10 +12,8 @@ from numpy.ctypeslib import ndpointer import ransac -from s2p import common from s2p import rpc_utils from s2p import estimation -from s2p.config import cfg # Locate sift4ctypes library and raise an ImportError if it can not be # found This call will raise an exception if library can not be found, @@ -155,7 +153,7 @@ def keypoints_match(k1, k2, method='relative', sift_thresh=0.6, F=None, k2 (array): numpy array of shape (m, 132), where each row represents a sift keypoint method (optional, default is 'relative'): flag ('relative' or - 'absolute') indicating wether to use absolute distance or relative + 'absolute') indicating whether to use absolute distance or relative distance sift_thresh (optional, default is 0.6): threshold for distance between SIFT descriptors. These descriptors are 128-vectors, whose coefficients @@ -239,7 +237,8 @@ def keypoints_match_from_nparray(k1, k2, method, sift_threshold, return matches.reshape((nb_matches.value, 4)) -def matches_on_rpc_roi(im1, im2, rpc1, rpc2, x, y, w, h): +def matches_on_rpc_roi(im1, im2, rpc1, rpc2, x, y, w, h, + method, sift_thresh, epipolar_threshold): """ Compute a list of SIFT matches between two images on a given roi. @@ -252,6 +251,8 @@ def matches_on_rpc_roi(im1, im2, rpc1, rpc2, x, y, w, h): x, y, w, h: four integers defining the rectangular ROI in the first image. (x, y) is the top-left corner, and (w, h) are the dimensions of the rectangle. + method, sift_thresh, epipolar_threshold: see docstring of + s2p.sift.keypoints_match() Returns: matches: 2D numpy array containing a list of matches. Each line @@ -264,16 +265,13 @@ def matches_on_rpc_roi(im1, im2, rpc1, rpc2, x, y, w, h): rpc_matches = rpc_utils.matches_from_rpc(rpc1, rpc2, x, y, w, h, 5) F = estimation.affine_fundamental_matrix(rpc_matches) - # sift matching method: - method = 'relative' if cfg['relative_sift_match_thresh'] is True else 'absolute' - # if less than 10 matches, lower thresh_dog. An alternative would be ASIFT thresh_dog = 0.0133 - for i in range(2): + for _ in range(2): p1 = image_keypoints(im1, x, y, w, h, thresh_dog=thresh_dog) p2 = image_keypoints(im2, x2, y2, w2, h2, thresh_dog=thresh_dog) - matches = keypoints_match(p1, p2, method, cfg['sift_match_thresh'], F, - epipolar_threshold=cfg['max_pointing_error'], + matches = keypoints_match(p1, p2, method, sift_thresh, F, + epipolar_threshold=epipolar_threshold, model='fundamental') if matches is not None and matches.ndim == 2 and matches.shape[0] > 10: break diff --git a/s2p/visualisation.py b/s2p/visualisation.py index 6f65c3d7..d219b5d2 100644 --- a/s2p/visualisation.py +++ b/s2p/visualisation.py @@ -4,13 +4,9 @@ import numpy as np import rasterio -import rpcm from s2p import common -from s2p import sift -from s2p import estimation from s2p import rpc_utils -import s2p.pointing_accuracy def plot_line(im, x1, y1, x2, y2, colour): diff --git a/tests/sift_test.py b/tests/sift_test.py index 5653166e..f9605b56 100644 --- a/tests/sift_test.py +++ b/tests/sift_test.py @@ -41,7 +41,10 @@ def test_matches_on_rpc_roi(): img2 = data_path('input_triplet/img_02.tif') rpc1 = rpcm.rpc_from_geotiff(img1) rpc2 = rpcm.rpc_from_geotiff(img2) - computed = sift.matches_on_rpc_roi(img1, img2, rpc1, rpc2, 100, 100, 200, 200) + computed = sift.matches_on_rpc_roi( + img1, img2, rpc1, rpc2, 100, 100, 200, 200, + method='relative', sift_thresh=0.6, epipolar_threshold=10 + ) expected = np.loadtxt(data_path('expected_output/units/matches_on_rpc_roi.txt')) np.testing.assert_allclose(computed, expected, rtol=0.01, atol=0.1, verbose=True)