All Downloads are FREE. Search and download functionalities are using the official Maven repository.

boofcv.alg.disparity.DisparityBlockMatchRowFormat Maven / Gradle / Ivy

Go to download

BoofCV is an open source Java library for real-time computer vision and robotics applications.

There is a newer version: 1.1.7
Show newest version
/*
 * Copyright (c) 2023, Peter Abeles. All Rights Reserved.
 *
 * This file is part of BoofCV (http://boofcv.org).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package boofcv.alg.disparity;

import boofcv.alg.InputSanityCheck;
import boofcv.alg.border.GrowBorder;
import boofcv.alg.disparity.block.DisparitySelect;
import boofcv.core.image.border.FactoryImageBorder;
import boofcv.struct.border.ImageBorder;
import boofcv.struct.image.GrayF32;
import boofcv.struct.image.ImageBase;
import boofcv.struct.image.ImageGray;
import boofcv.struct.image.ImageType;
import lombok.Getter;
import lombok.Setter;
import org.jetbrains.annotations.Nullable;

/**
 * 

* Base class for all dense stereo disparity score algorithms whose score's can be processed by * {@link DisparitySelect}. The scores for all possible disparities at each pixel is computed for * an entire row at once. Then {@link DisparitySelect} is called to process this score. *

* *

* Score Format: The index of the score for column i ≥ radiusX + minDisparity at disparity d is:
* index = imgWidth*(d-minDisparity-radiusX) + i - minDisparity-radiusX
* Format Comment:
* This ordering is a bit unnatural when searching for the best disparity, but reduces cache misses * when writing. Performance boost is about 20%-30% depending on max disparity and image size. *

* * @author Peter Abeles */ public abstract class DisparityBlockMatchRowFormat , Disparity extends ImageGray> { // the minimum disparity value (inclusive) protected @Getter int disparityMin; // maximum allowed image disparity (exclusive) protected @Getter int disparityMax; // difference between max and min protected @Getter int disparityRange; // number of score elements: image_width*rangeDisparity protected int widthDisparityBlock; // radius of the region along x and y axis protected @Getter int radiusX, radiusY; // size of the region: radius*2 + 1 protected @Getter int regionWidth, regionHeight; // Used to extract a row with the border added to it protected @Getter GrowBorder growBorderL; protected @Getter GrowBorder growBorderR; /** *

To speed up computations a rolling sum is performed where it subtracts the old row then adds the new row * from the score sum. Every time you update the sum noise is added. When disparity values get small then * this error becomes noticeable and can lead to drastically incorrect answers. This * is known as catastrophic cancellation. To fix this issue, the sum is recomputed from scratch every N rows.

* *

* NOTE: Under nominal situations this won't be noticeable. A specialized performance benchmark where a flat * plane was moved away from the camera is where it was first noticed and only when very far away. * How bad the errors are also depends on the error distribution. This only affects floating point scores. * CENSUS has integer scores and is unaffected. *

* *

The value below was determined empirically in a test scenario. Set to 1 to always run.

*/ public @Setter @Getter int catastrophicReset = 25; /** * Configures disparity calculation. * * @param regionRadiusX Radius of the rectangular region along x-axis. * @param regionRadiusY Radius of the rectangular region along y-axis. */ protected DisparityBlockMatchRowFormat( int regionRadiusX, int regionRadiusY, ImageType imageType ) { this.radiusX = regionRadiusX; this.radiusY = regionRadiusY; this.regionWidth = regionRadiusX*2 + 1; this.regionHeight = regionRadiusY*2 + 1; growBorderL = (GrowBorder)FactoryImageBorder.createGrowBorder(imageType); growBorderR = (GrowBorder)FactoryImageBorder.createGrowBorder(imageType); } public void setBorder( ImageBorder border ) { growBorderL.setBorder(border.copy()); growBorderR.setBorder(border.copy()); } /** * Configures the disparity search * * @param disparityMin Minimum disparity that it will check. Must be ≥ 0 and < maxDisparity * @param disparityRange Number of possible disparity values estimated. The max possible disparity is min+range-1. */ public void configure( int disparityMin, int disparityRange ) { if (disparityMin < 0) throw new IllegalArgumentException("Min disparity must be greater than or equal to zero. max=" + disparityMin); if (disparityRange <= 0) throw new IllegalArgumentException("Disparity range must be more than 0"); this.disparityMin = disparityMin; this.disparityRange = disparityRange; this.disparityMax = disparityMin + disparityRange - 1; } /** * Computes disparity between two stereo images * * @param left Left rectified stereo image. Input * @param right Right rectified stereo image. Input * @param disparity Disparity between the two images. Output * @param score Optional storage for best fit score */ public void process( Input left, Input right, Disparity disparity, @Nullable GrayF32 score ) { // initialize data structures InputSanityCheck.checkSameShape(left, right); // Stores error for all x-coordinates and disparity values along a single row widthDisparityBlock = left.width*disparityRange; _process(left, right, disparity, score); } /** * Inner function that computes the disparity. */ public abstract void _process( Input left, Input right, Disparity disparity, @Nullable GrayF32 score ); public abstract ImageType getInputType(); public abstract Class getDisparityType(); public int getBorderX() { return 0; } public int getBorderY() { return radiusY; } /** * The maximum possible error for the region */ public int getMaxRegionError() { return regionWidth*regionHeight*getMaxPerPixelError(); } protected abstract int getMaxPerPixelError(); }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy