Skip to content

Commit

Permalink
Merge pull request #6 from 20treeAI/check_missing_sift
Browse files Browse the repository at this point in the history
Check missing sift
  • Loading branch information
daviddemeij authored Sep 20, 2022
2 parents 80e41fe + 9eb9a6b commit 58e0409
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 31 deletions.
35 changes: 30 additions & 5 deletions s2p/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@
from s2p import visualisation


def check_missing_sift(tiles_pairs):
missing_sift = []
with open(os.path.join(cfg["out_dir"], "missing_sift.txt"), "w") as f:
for tile, i in tiles_pairs:
out_dir = os.path.join(tile['dir'], 'pair_{}'.format(i))
path = os.path.join(out_dir, 'sift_matches.txt')
if not os.path.exists(path):
missing_sift.append(path)
f.write(path + "\n")
if len(missing_sift) > 0:
print(" --- ")
print(f"WARNING: missing {len(missing_sift)}/{len(tiles_pairs)} "
"SIFT matches, this may deteriorate output quality")
print(" --- ")

def pointing_correction(tile, i):
"""
Compute the translation that corrects the pointing error on a pair of tiles.
Expand Down Expand Up @@ -550,6 +565,7 @@ def main(user_cfg, start_from=0):
nb_workers = multiprocessing.cpu_count() # nb of available cores
if cfg['max_processes'] is not None:
nb_workers = cfg['max_processes']
print(f"Running s2p using {nb_workers} workers.")

tw, th = initialization.adjust_tile_size()
tiles_txt = os.path.join(cfg['out_dir'], 'tiles.txt')
Expand All @@ -576,6 +592,7 @@ def main(user_cfg, start_from=0):
print('1) correcting pointing locally...')
parallel.launch_calls(pointing_correction, tiles_pairs, nb_workers,
timeout=timeout)
check_missing_sift(tiles_pairs)

# global-pointing step:
if start_from <= 2:
Expand All @@ -588,17 +605,25 @@ def main(user_cfg, start_from=0):
print('3) rectifying tiles...')
parallel.launch_calls(rectification_pair, tiles_pairs, nb_workers,
timeout=timeout)
tiles = [t for t in tiles if t is not None]


# matching step:
if start_from <= 4:
print('4) running stereo matching...')
if cfg['max_processes_stereo_matching'] is not None:
nb_workers_stereo = cfg['max_processes_stereo_matching']
else:
# Set the number of stereo workers to 2/3 of the number of cores by default
nb_workers_stereo = min(1, int(2 * (nb_workers / 3)))
# Set the number of stereo workers to the number of workers divided
# by a certain amount depending on the tile_size and number of tiles
# this should be a generally safe number of workers.
divider = 2 * (cfg['tile_size'] / 800.0) * (cfg['tile_size'] / 800.0)
divider *= (len(tiles_pairs) / 500.0)
if cfg['matching_algorithm'] == 'mgm_multi':
nb_workers_stereo = int(min(nb_workers, max(1, int(nb_workers / divider))))
else:
# For non mgm_multi don't use less than 2/3 of the workers (much less RAM intensive)
nb_workers_stereo = int(min(nb_workers, max(((2 / 3) * nb_workers), nb_workers / divider)))
try:
print(f'4) running stereo matching using {nb_workers_stereo} workers...')
parallel.launch_calls(stereo_matching, tiles_pairs, nb_workers_stereo,
timeout=timeout)
except subprocess.CalledProcessError as e:
Expand Down Expand Up @@ -637,7 +662,7 @@ def main(user_cfg, start_from=0):

# local-dsm-rasterization step:
if start_from <= 6:
print('computing DSM by tile...')
print('6) computing DSM by tile...')
parallel.launch_calls(plys_to_dsm, tiles, nb_workers, timeout=timeout)

# global-dsm-rasterization step:
Expand Down
3 changes: 3 additions & 0 deletions s2p/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,9 @@ def is_this_tile_useful(x, y, w, h, images_sizes):
mask (np.array): tile validity mask. Set to None if the tile is discarded
"""
# check if the tile is partly contained in at least one other image
if w <= 0 or h <= 0:
return False, None

rpc = cfg['images'][0]['rpcm']
for img, size in zip(cfg['images'][1:], images_sizes[1:]):
coords = rpc_utils.corresponding_roi(rpc, img['rpcm'], x, y, w, h)
Expand Down
3 changes: 3 additions & 0 deletions s2p/pointing_accuracy.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ def compute_correction(img1, img2, rpc1, rpc2, x, y, w, h,
order to correct the pointing error, and the list of sift matches used
to compute this correction.
"""
if w <= 0 or h <= 0:
raise ValueError(f"width or height <= 0 for:\n{img1}\n{img2}\nx={x}, y={y}, w={w}, h={h}. Try a different"
f"tilesize or different ROI.")
m = sift.matches_on_rpc_roi(img1, img2, rpc1, rpc2, x, y, w, h,
method, sift_thresh, epipolar_threshold)

Expand Down
52 changes: 27 additions & 25 deletions s2p/visualisation.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from s2p import common
from s2p import rpc_utils

from rasterio.windows import Window

def plot_line(im, x1, y1, x2, y2, colour):
"""
Expand Down Expand Up @@ -48,46 +49,47 @@ def plot_line(im, x1, y1, x2, y2, colour):
return im


def plot_matches_low_level(img1, img2, matches, outfile):
def plot_matches_low_level(crop1, crop2, matches, outfile, max_matches=100):
"""
Displays two images side by side with matches highlighted
Args:
img1, img2 (np.array): two input images
crop1, crop2 (np.array): two input images
matches: 2D numpy array of size 4xN containing a list of matches (a
list of pairs of points, each pair being represented by x1, y1, x2,
y2)
outfile (str): path where to write the resulting image, to be displayed
"""
# transform single channel to 3-channels
if img1.ndim < 3:
img1 = np.dstack([img1] * 3)
if img2.ndim < 3:
img2= np.dstack([img2] * 3)
if crop1.shape[0] < 3:
crop1 = np.concatenate([crop1] * 3, axis=0)
if crop2.shape[0] < 3:
crop2 = np.concatenate([crop2] * 3, axis=0)

# if images have more than 3 channels, keep only the first 3
if img1.shape[2] > 3:
img1 = img1[:, :, 0:3]
if img2.shape[2] > 3:
img2 = img2[:, :, 0:3]
if crop1.shape[0] > 3:
crop1 = crop1[:3, :, :]
if crop2.shape[0] > 3:
crop2 = crop2[:3, :, :]

# build the output image
h1, w1 = img1.shape[:2]
h2, w2 = img2.shape[:2]
h1, w1 = crop1.shape[1:]
h2, w2 = crop2.shape[1:]
w = w1 + w2
h = max(h1, h2)
out = np.zeros((h, w, 3), np.uint8)
out[:h1, :w1] = img1
out[:h2, w1:w] = img2
out = np.zeros((3, h, w), np.uint8)
out[:, :h1, :w1] = crop1
out[:, :h2, w1:w] = crop2
out = np.transpose(out, [1, 2, 0])

# define colors, according to min/max intensity values
out_min = min(np.nanmin(img1), np.nanmin(img2))
out_max = max(np.nanmax(img1), np.nanmax(img2))
out_min = min(np.nanmin(crop1), np.nanmin(crop2))
out_max = max(np.nanmax(crop1), np.nanmax(crop2))
green = [out_min, out_max, out_min]
blue = [out_min, out_min, out_max]

# plot the matches
for i in range(len(matches)):
# plot the matches (not more than max_matches)
for i in range(min(max_matches, len(matches))):
x1 = matches[i, 0]
y1 = matches[i, 1]
x2 = matches[i, 2] + w1
Expand All @@ -105,7 +107,7 @@ def plot_matches_low_level(img1, img2, matches, outfile):
common.rasterio_write(outfile, out)


def plot_matches(im1, im2, rpc1, rpc2, matches, outfile, x, y, w, h):
def plot_matches(img1, img2, rpc1, rpc2, matches, outfile, x, y, w, h):
"""
Plot keypoint matches on images corresponding ROIs.
Expand All @@ -129,11 +131,11 @@ def plot_matches(im1, im2, rpc1, rpc2, matches, outfile, x, y, w, h):
x1, y1, w1, h1 = x, y, w, h
x2, y2, w2, h2 = map(int, rpc_utils.corresponding_roi(rpc1, rpc2, x1, y1, w1, h1))

# do the crops
with rasterio.open(im1, "r") as f:
crop1 = f.read(window=((y1, y1 + h1), (x1, x1 + w1)))
with rasterio.open(im2, "r") as f:
crop2 = f.read(window=((y2, y2 + h2), (x2, x2 + w2)))
# read the crops
with rasterio.open(img1, "r") as f:
crop1 = f.read(window=Window(x1, y1, w1, h1))
with rasterio.open(img2, "r") as f:
crop2 = f.read(window=Window(x2, y2, w2, h2))

crop1 = common.linear_stretching_and_quantization_8bit(crop1)
crop2 = common.linear_stretching_and_quantization_8bit(crop2)
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def finalize_options(self):
}

setup(name="s2p",
version="1.3",
version="1.3.3",
description="Satellite Stereo Pipeline.",
long_description=readme(),
long_description_content_type='text/markdown',
Expand Down

0 comments on commit 58e0409

Please sign in to comment.