Skip to content

Commit

Permalink
Merge branch '411-check-disp-map-interval' into 'release'
Browse files Browse the repository at this point in the history
fix: check disparity range inside image

See merge request 3d/PandoraBox/pandora!354
  • Loading branch information
lecontm committed Jul 12, 2024
2 parents 472cf99 + 9c0ea5c commit 6662b57
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 8 deletions.
34 changes: 27 additions & 7 deletions pandora/check_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,6 @@ def check_images(user_cfg: Dict[str, dict]) -> None:
:type user_cfg: dict
:return: None
"""

left_ = rasterio_open(user_cfg["left"]["img"])
right_ = rasterio_open(user_cfg["right"]["img"])

Expand Down Expand Up @@ -217,6 +216,20 @@ def check_band_names(dataset: xr.Dataset) -> None:
raise TypeError("Band value must be str")


def check_disparity_ranges_are_inside_image(disparity: list[int], image: rasterio.io.DatasetReader):
"""
Raise an error if disparity ranges are out off image.
:param disparity: range disparity
:type disparity: List
:param image: left image
:type image: rasterio.io.DatasetReader
"""
print(f"{disparity=}")
if np.abs(disparity).min() > image.width:
raise ValueError("Disparity range out of image")


def check_disparities_from_input(
disparity: list[int] | str | None,
img_left: str,
Expand All @@ -230,17 +243,19 @@ def check_disparities_from_input(
:type img_left: str
:return: None
"""
# Load an image to compare the grid size
img_left_ = rasterio_open(img_left)

# disparities are integers
if isinstance(disparity, list) and disparity[1] < disparity[0]:
raise ValueError("disp_max must be bigger than disp_min")
if isinstance(disparity, list):
if disparity[1] < disparity[0]:
raise ValueError("disp_max must be bigger than disp_min")
# check that disparity input are not off image
check_disparity_ranges_are_inside_image(disparity, img_left_)

# disparities are grids
if isinstance(disparity, str):
# Load an image to compare the grid size
img_left_ = rasterio_open(img_left)

disparity_reader = rasterio_open(disparity)

# check that disparity grids is a 2-channel grid
if disparity_reader.count != 2:
raise AttributeError("Disparity grids must be a 2-channel grid")
Expand All @@ -252,6 +267,11 @@ def check_disparities_from_input(
if (disparity_reader.read(1) > disparity_reader.read(2)).any():
raise ValueError("disp_max must be bigger than disp_min")

# check that disp_min and disp_max are not off image
check_disparity_ranges_are_inside_image(
[disparity_reader.read(1).min(), disparity_reader.read(2).max()], img_left_
)


def check_disparities_from_dataset(disparity: xr.DataArray) -> None:
"""
Expand Down
61 changes: 60 additions & 1 deletion tests/test_check_configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
import numpy as np
import xarray as xr
from rasterio import Affine
from skimage.io import imsave
import pytest


from pandora.img_tools import create_dataset_from_inputs, add_disparity, rasterio_open
from pandora.check_configuration import (
check_dataset,
Expand All @@ -40,6 +40,7 @@
check_disparities_from_input,
check_disparities_from_dataset,
check_attributes,
check_disparity_ranges_are_inside_image,
)
from tests import common

Expand Down Expand Up @@ -488,3 +489,61 @@ def test_fails_with_wrong_disparities(self, disparity, string_match):
"""
with pytest.raises(AttributeError, match=string_match):
check_disparities_from_dataset(disparity)


class TestDisparityRangesAreInsideImage:
"""Test that out of image disparity range are not allowed."""

@pytest.fixture()
def image_path(self, tmp_path):
path = tmp_path / "tiff_file.tif"
imsave(path, np.empty((450, 450)))
return path

@pytest.fixture()
def disp_left(self):
return [-4, 1]

@pytest.fixture()
def disp_right(self):
return [-3, 2]

@pytest.fixture()
def configuration(self, image_path, disp_left, disp_right):
return {
"input": {
"left": {"img": str(image_path), "nodata": "NaN", "disp": disp_left},
"right": {"img": str(image_path), "nodata": "NaN", "disp": disp_right},
}
}

@pytest.fixture()
def image_left_data(self, configuration):
return rasterio_open(configuration["input"]["left"]["img"])

@pytest.fixture()
def image_right_data(self, configuration):
return rasterio_open(configuration["input"]["right"]["img"])

@pytest.mark.parametrize(
"disp_left",
[
pytest.param([-460, -451], id="Out on left"),
pytest.param([451, 460], id="Out on right"),
],
)
def test_disparity_totally_out(self, configuration, image_left_data):
"""Totally out disparities should raise an error."""
with pytest.raises(ValueError, match="Disparity range out of image"):
check_disparity_ranges_are_inside_image(configuration["input"]["left"]["disp"], image_left_data)

@pytest.mark.parametrize(
"disp_right",
[
pytest.param([-460, -450], id="Partially out on left"),
pytest.param([450, 460], id="Partially out on right"),
],
)
def test_disparity_partially_out(self, configuration, image_right_data):
"""Partially out should not raise error."""
check_disparity_ranges_are_inside_image(configuration["input"]["right"]["disp"], image_right_data)

0 comments on commit 6662b57

Please sign in to comment.