Skip to content

Commit

Permalink
Merge branch '218-fix-dichotomy-cpp' into 'release'
Browse files Browse the repository at this point in the history
fix: disparity to index with subpix on cost_volume

See merge request 3d/PandoraBox/pandora2d!201
  • Loading branch information
lecontm committed Feb 3, 2025
2 parents 65b27e4 + baf6b21 commit f3a46aa
Show file tree
Hide file tree
Showing 2 changed files with 161 additions and 5 deletions.
71 changes: 66 additions & 5 deletions pandora2d/refinement/dichotomy_cpp.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ def refinement_method( # pylint: disable=too-many-locals
# TO BE REMOVE WHEN CRITERIA MAP WILL BE FINISHED
criteria_map = create_criteria_map(cost_volumes, disp_map, img_left, invalid_disparity_map_mask)

subpixel = cost_volumes.attrs["subpixel"]

# Convert disparity maps to np.array to optimise performance
# Transforming disparity maps into index maps
row_map = (row_map.to_numpy() - cost_volumes.disp_row.values[0]).astype(np.float64)
col_map = (col_map.to_numpy() - cost_volumes.disp_col.values[0]).astype(np.float64)
row_map = (disparity_to_index(row_map, cost_volumes.disp_row.values[0], subpixel)).astype(np.float64)
col_map = (disparity_to_index(col_map, cost_volumes.disp_col.values[0], subpixel)).astype(np.float64)

refinement_bind.compute_dichotomy(
cost_volumes.cost_volumes.data.ravel().astype(np.float64),
Expand All @@ -132,14 +134,14 @@ def refinement_method( # pylint: disable=too-many-locals
cost_values.ravel().astype(np.float64),
criteria_map.ravel(),
refinement_bind.Cost_volume_size(cost_volumes.cost_volumes.shape),
cost_volumes.attrs["subpixel"],
subpixel,
self.cfg["iterations"],
self.filter.cpp_instance,
cost_volumes.attrs["type_measure"],
)
# Inverse transforming index maps into disparity maps
col_map += cost_volumes.disp_col.values[0]
row_map += cost_volumes.disp_row.values[0]
col_map = index_to_disparity(col_map, cost_volumes.disp_col.values[0], subpixel)
row_map = index_to_disparity(row_map, cost_volumes.disp_row.values[0], subpixel)

# Log about precision
subpixel_to_iteration = cost_volumes.attrs["subpixel"].bit_length() - 1
Expand All @@ -149,6 +151,65 @@ def refinement_method( # pylint: disable=too-many-locals
return col_map, row_map, cost_values


def disparity_to_index(disparity_map: xr.DataArray, shift: int, subpixel: int) -> np.ndarray:
"""
Transform a disparity map to index map. Indexes correspond to (row/col) disparities in cost volume.
Example:
- with subpixel=1 :
* disparity_map = -2 -1 -1 1
-1 0 -1 -1
0 1 1 1
* disparities range = [-4 -3 -2 -1 0 1 2 3]
* index_map = 2 3 3 5
3 4 3 3
4 5 5 5
- with subpixel=2 :
* disparity_map = -4 -2 -1.5 -2.5
-4 -1 -1 -1
-4 -1.5 -1 -1.5
* disparities range = [-4 -3.5 -3 -2.5 -2 -1.5 -1]
* index_map = 0 4 5 3
0 6 6 6
0 5 6 5
:param disparity_map: 2D map
:type disparity_map: xarray.DataArray
:param shift: the first value of the disparity coordinates in the cost volume
:type shift: int
:param subpixel: :sub-sampling of cost_volume
:type subpixel: int
:return: the index map
:rtype: np.ndarray
"""
return (disparity_map.to_numpy() - shift) * subpixel


def index_to_disparity(index_map: np.ndarray, shift: int, subpixel: int) -> np.ndarray:
"""
Transform an index map to disparity map. Indexes correspond to (row/col) disparities in cost volume.
For examples, see disparity_to_index method.
:param index_map: 2D map
:type index_map: np.ndarray
:param shift: the first value of the disparity coordinates in the cost volume
:type shift: int
:param subpixel: :sub-sampling of cost_volume
:type subpixel: int
:return: the index map
:rtype: np.ndarray
"""
return (index_map / subpixel) + shift


def create_cost_values_map(cost_volumes: xr.Dataset, disp_map: xr.Dataset) -> Tuple[np.ndarray, np.ndarray]:
"""
Return the map with best matching score
Expand Down
95 changes: 95 additions & 0 deletions tests/unit_tests/test_refinement/test_dichotomy.py
Original file line number Diff line number Diff line change
Expand Up @@ -1191,3 +1191,98 @@ def test_non_uniform_disparity_grid( # pylint: disable=too-many-arguments
# For point [1,0] col disparity range is not [min_disparity_col, max_disparity_col] but [min_disparity_col, 0],
# we check that resulting disparity row is in this range.
assert result_disp_col[1, 0] in range(min_disparity_col, 0 + 1)


class TestChangeDisparityToIndex:

@pytest.mark.parametrize(
["map", "shift", "subpixel", "expected"],
[
pytest.param(
xr.DataArray(
data=[[1, 2, 3], [2, 2, 3]],
dims=("row", "col"),
coords={"row": np.arange(2), "col": np.arange(3)},
),
1, # disparity range starts at 1
1,
np.array([[0, 1, 2], [1, 1, 2]]),
id="positive disparity",
),
pytest.param(
xr.DataArray(
data=[[-1, -2, -3], [-2, -2, -3]],
dims=("row", "col"),
coords={"row": np.arange(2), "col": np.arange(3)},
),
-4, # disparity range starts at -4
1,
np.array([[3, 2, 1], [2, 2, 1]]),
id="negative disparity",
),
pytest.param(
xr.DataArray(
data=[[-1, -2.5, -3], [-2, -2.5, -3]],
dims=("row", "col"),
coords={"row": np.arange(2), "col": np.arange(3)},
),
-4, # disparity range starts at -4
2,
np.array([[6, 3, 2], [4, 3, 2]]),
id="negative disparity and subpixel=0.5",
),
pytest.param(
xr.DataArray(
data=[[-1, -2.5, -3], [-2, -2.5, -3]],
dims=("row", "col"),
coords={"row": np.arange(2), "col": np.arange(3)},
),
-4, # disparity range starts at -4
4,
np.array([[12.0, 6, 4.0], [8, 6, 4]]),
id="negative disparity and subpixel=0.25",
),
],
)
def test_disparity_to_index(self, map, shift, subpixel, expected):
"""Test disparity_to_index method"""
result = refinement.dichotomy_cpp.disparity_to_index(map, shift, subpixel)
np.testing.assert_array_equal(result, expected)

@pytest.mark.parametrize(
["map", "shift", "subpixel", "expected"],
[
pytest.param(
np.array([[0, 1, 2], [1, 1, 2]]),
1, # disparity range starts at 1
1,
np.array([[1, 2, 3], [2, 2, 3]]),
id="positive disparity",
),
pytest.param(
np.array([[3, 2, 1], [2, 2, 1]]),
-4, # disparity range starts at -4
1,
np.array([[-1, -2, -3], [-2, -2, -3]]),
id="negative disparity",
),
pytest.param(
np.array([[3.0625, 2, 1.0625], [2, 2, 1]]),
-4, # disparity range starts at -4 and precision = 0.0625
2,
np.array([[-2.46875, -3.0, -3.46875], [-3.0, -3.0, -3.5]]),
id="negative disparity and subpixel=0.5",
),
pytest.param(
np.array([[3.0625, 2, 1.0625], [2, 2, 1]]),
-4, # disparity range starts at -4 and precision = 0.0625
4,
np.array([[-3.234375, -3.5, -3.734375], [-3.5, -3.5, -3.75]]),
id="negative disparity and subpixel=0.5",
),
],
)
def test_index_to_disparity(self, map, shift, subpixel, expected):
"""Test index_to_disparity_method"""
result = refinement.dichotomy_cpp.index_to_disparity(map, shift, subpixel)
np.testing.assert_array_equal(result, expected)

0 comments on commit f3a46aa

Please sign in to comment.