Stereo#

kornia.metrics.mean_absolute_disparity_error(input, target, valid_mask=None, reduction='mean')[source]#

Compute the mean absolute error (MAE) between two disparity maps.

Given predicted and ground truth disparity maps \(D\) and \(D^{gt}\) with valid pixels \(\mathcal{V}\), the metric is:

\[\text{MAE}(D, D^{gt}) = \frac{1}{|\mathcal{V}|}\sum_{p \in \mathcal{V}} |D_{p} - D^{gt}_{p}|\]
Convention:
  • The maps hold disparities in pixels, have any shape \((*)\) and must have a floating dtype. 'mean' and 'sum' pool every valid pixel of every image into one 0-d value, in pixels here, so for images with different numbers of valid pixels the result is not the mean of the per-image errors. The other disparity metrics pool the same way.

  • valid_mask is broadcast to the maps from the right: an \((H, W)\) mask applies to every image of a \((B, H, W)\) batch and a \((B, 1, 1)\) mask selects whole images, while a \((B,)\) mask is matched against the last axis, not the batch. Nothing is masked automatically: a pixel with an invalid ground truth, such as a zero disparity, counts unless valid_mask excludes it.

  • A nan at a valid pixel of either map propagates into this error and the RMSE, while mean_bad_pixel_error() and kitti_d1_error() count it as a good pixel.

Parameters:
  • input (Tensor) – the predicted disparity map with arbitrary shape \((*)\).

  • target (Tensor) – the ground truth disparity map with the same shape as input.

  • valid_mask (Optional[Tensor], optional) – optional mask broadcastable to the shape of input, where nonzero (True) values mark the pixels to evaluate. Non-boolean masks are converted to boolean. If None, all pixels are evaluated. Default: None

  • reduction (str, optional) – specifies the reduction to apply to the output: 'none' | 'mean' | 'sum'. 'mean': the error is averaged over the valid pixels, 'sum': the error is summed over the valid pixels, 'none': no reduction will be applied and the per-pixel error map is returned, with masked-out positions set to zero. Default: "mean"

Return type:

Tensor

Returns:

the computed metric as a scalar, or the per-pixel error map if reduction='none'.

Note

If valid_mask selects no pixels, 'mean' reduction returns nan.

Note

Sums are accumulated in float32 for float16 and bfloat16 inputs and the result is cast back, so 'mean' stays accurate on image-sized maps. 'sum' returns the input dtype as well, so a float16 total above 65504 still saturates to inf — reduce with 'none' and sum in a wider dtype if you need totals that large.

Examples

>>> input = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
>>> target = torch.tensor([[0.0, 1.0], [2.0, 4.0]])
>>> mean_absolute_disparity_error(input, target)
tensor(0.2500)
>>> valid_mask = torch.tensor([[True, True], [True, False]])
>>> mean_absolute_disparity_error(input, target, valid_mask)
tensor(0.)
Reference:

D. Scharstein and R. Szeliski. A taxonomy and evaluation of dense two-frame stereo correspondence algorithms. IJCV 2002. https://vision.middlebury.edu/stereo/taxonomy-IJCV.pdf

kornia.metrics.root_mean_squared_disparity_error(input, target, valid_mask=None, reduction='mean')[source]#

Compute the root mean squared error (RMSE) between two disparity maps.

Given predicted and ground truth disparity maps \(D\) and \(D^{gt}\) with valid pixels \(\mathcal{V}\), the metric is:

\[\text{RMSE}(D, D^{gt}) = \sqrt{\frac{1}{|\mathcal{V}|}\sum_{p \in \mathcal{V}} (D_{p} - D^{gt}_{p})^{2}}\]
Convention:

See the Convention block of mean_absolute_disparity_error(): 'mean' gives one 0-d value in pixels, pooled over every valid pixel of the batch, and 'sum' gives \(\sqrt{\sum e^2}\), not a sum of errors.

Parameters:
  • input (Tensor) – the predicted disparity map with arbitrary shape \((*)\).

  • target (Tensor) – the ground truth disparity map with the same shape as input.

  • valid_mask (Optional[Tensor], optional) – optional mask broadcastable to the shape of input, where nonzero (True) values mark the pixels to evaluate. Non-boolean masks are converted to boolean. If None, all pixels are evaluated. Default: None

  • reduction (str, optional) – specifies the reduction to apply to the squared error before the square root: 'none' | 'mean' | 'sum'. 'mean': the squared error is averaged over the valid pixels, 'sum': the squared error is summed over the valid pixels, 'none': no reduction will be applied and the per-pixel absolute error map is returned, with masked-out positions set to zero. Default: "mean"

Return type:

Tensor

Returns:

the computed metric as a scalar, or the per-pixel error map if reduction='none'.

Note

If valid_mask selects no pixels, 'mean' reduction returns nan.

Note

For float16 and bfloat16 inputs the squared error and its reduction are computed in float32 and only the final value is cast back. Without that, a disparity error above 256 px would already saturate the float16 squared error to inf.

Examples

>>> input = torch.zeros(2, 2)
>>> target = torch.tensor([[0.0, 0.0], [0.0, 1.0]])
>>> root_mean_squared_disparity_error(input, target)
tensor(0.5000)
Reference:

D. Scharstein and R. Szeliski. A taxonomy and evaluation of dense two-frame stereo correspondence algorithms. IJCV 2002. https://vision.middlebury.edu/stereo/taxonomy-IJCV.pdf

kornia.metrics.mean_bad_pixel_error(input, target, threshold=3.0, valid_mask=None, reduction='mean')[source]#

Compute the bad pixel ratio between two disparity maps.

A pixel is considered bad when its absolute disparity error is strictly greater than threshold. Given predicted and ground truth disparity maps \(D\) and \(D^{gt}\) with valid pixels \(\mathcal{V}\), the metric is:

\[\text{Bad}_{\tau}(D, D^{gt}) = \frac{1}{|\mathcal{V}|}\sum_{p \in \mathcal{V}} [|D_{p} - D^{gt}_{p}| > \tau]\]

This corresponds to the bad-pixel percentage reported by the Middlebury stereo benchmark, expressed as a fraction in \([0, 1]\) instead of a percentage. It is not the number KITTI reports: that benchmark uses D1, which adds a relative criterion on top of this one. See kitti_d1_error().

Convention:

See the Convention block of mean_absolute_disparity_error(): 'mean' gives one 0-d value pooled over every valid pixel of the batch, here a fraction in \([0, 1]\), and 'sum' the number of bad pixels.

Parameters:
  • input (Tensor) – the predicted disparity map with arbitrary shape \((*)\).

  • target (Tensor) – the ground truth disparity map with the same shape as input.

  • threshold (float, optional) – the disparity error above which a pixel is considered bad. Default: 3.0

  • valid_mask (Optional[Tensor], optional) – optional mask broadcastable to the shape of input, where nonzero (True) values mark the pixels to evaluate. Non-boolean masks are converted to boolean. If None, all pixels are evaluated. Default: None

  • reduction (str, optional) – specifies the reduction to apply to the output: 'none' | 'mean' | 'sum'. 'mean': the fraction of bad pixels among the valid pixels, 'sum': the number of bad pixels among the valid pixels, 'none': no reduction will be applied and the per-pixel bad-pixel map is returned, with masked-out positions set to zero. Default: "mean"

Return type:

Tensor

Returns:

the computed metric as a scalar, or the per-pixel bad-pixel map if reduction='none'.

Note

If valid_mask selects no pixels, 'mean' reduction returns nan.

Note

This is an indicator metric built from comparisons, so it has no useful gradient. The output does not require grad and cannot be used as a loss.

Note

Sums are accumulated in float32 for float16 and bfloat16 inputs and the result is cast back, so 'mean' stays accurate on image-sized maps. 'sum' returns the input dtype as well, so a float16 count above 65504 still saturates to inf — reduce with 'none' and sum in a wider dtype if you need counts that large.

Examples

>>> input = torch.zeros(2, 2)
>>> target = torch.tensor([[0.0, 1.0], [2.0, 4.0]])
>>> mean_bad_pixel_error(input, target, threshold=1.5)
tensor(0.5000)
Reference:

D. Scharstein and R. Szeliski. A taxonomy and evaluation of dense two-frame stereo correspondence algorithms. IJCV 2002. https://vision.middlebury.edu/stereo/taxonomy-IJCV.pdf

kornia.metrics.kitti_d1_error(input, target, abs_threshold=3.0, rel_threshold=0.05, valid_mask=None, reduction='mean')[source]#

Compute the KITTI D1 error between two disparity maps.

A pixel is considered an outlier when its absolute disparity error exceeds abs_threshold and its relative disparity error exceeds rel_threshold. Given predicted and ground truth disparity maps \(D\) and \(D^{gt}\) with valid pixels \(\mathcal{V}\), the metric is:

\[\text{D1}(D, D^{gt}) = \frac{1}{|\mathcal{V}|}\sum_{p \in \mathcal{V}} \left[|D_{p} - D^{gt}_{p}| > \tau_{abs} \;\wedge\; \frac{|D_{p} - D^{gt}_{p}|}{|D^{gt}_{p}|} > \tau_{rel}\right]\]

This is the outlier ratio reported by the KITTI 2015 stereo benchmark, expressed as a fraction in \([0, 1]\) instead of a percentage.

Convention:
  • See the Convention block of mean_absolute_disparity_error(): 'mean' gives one 0-d value pooled over every valid pixel of the batch, here a fraction in \([0, 1]\), and 'sum' the number of outliers. Losses and metrics relates it to the KITTI devkit.

  • The relative error divides by target, so the two maps are not interchangeable: swapping them can change the result.

Parameters:
  • input (Tensor) – the predicted disparity map with arbitrary shape \((*)\).

  • target (Tensor) – the ground truth disparity map with the same shape as input.

  • abs_threshold (float, optional) – the absolute disparity error above which a pixel may be an outlier. Default: 3.0

  • rel_threshold (float, optional) – the relative disparity error above which a pixel may be an outlier. Default: 0.05

  • valid_mask (Optional[Tensor], optional) – optional mask broadcastable to the shape of input, where nonzero (True) values mark the pixels to evaluate. Non-boolean masks are converted to boolean. If None, all pixels are evaluated. Default: None

  • reduction (str, optional) – specifies the reduction to apply to the output: 'none' | 'mean' | 'sum'. 'mean': the fraction of outliers among the valid pixels, 'sum': the number of outliers among the valid pixels, 'none': no reduction will be applied and the per-pixel outlier map is returned, with masked-out positions set to zero. Default: "mean"

Return type:

Tensor

Returns:

the computed metric as a scalar, or the per-pixel outlier map if reduction='none'.

Note

If valid_mask selects no pixels, 'mean' reduction returns nan.

Note

This is an indicator metric built from comparisons, so it has no useful gradient. The output does not require grad and cannot be used as a loss.

Note

Pixels with a zero ground truth disparity yield a non-finite relative error. Because both criteria must hold, such pixels are classified by abs_threshold alone and the output stays finite. KITTI marks these pixels as invalid, so prefer passing valid_mask.

Note

A nan in either map is counted as an inlier, because every comparison against nan is false and both criteria must hold. The metric therefore stays finite where mean_absolute_disparity_error() would propagate the nan. Mask non-finite pixels out with valid_mask rather than relying on either behaviour.

Note

Sums are accumulated in float32 for float16 and bfloat16 inputs and the result is cast back, so 'mean' stays accurate on image-sized maps. 'sum' returns the input dtype as well, so a float16 count above 65504 still saturates to inf — reduce with 'none' and sum in a wider dtype if you need counts that large.

Examples

>>> input = torch.tensor([1.0, 5.0, 104.0, 20.0])
>>> target = torch.tensor([1.0, 1.0, 100.0, 10.0])
>>> kitti_d1_error(input, target)
tensor(0.5000)
Reference:

M. Menze and A. Geiger. Object Scene Flow for Autonomous Vehicles. CVPR 2015. https://www.cvlibs.net/datasets/kitti/eval_scene_flow.php?benchmark=stereo