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

com.irurueta.ar.epipolar.GoldStandardCorrector Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
/*
 * Copyright (C) 2015 Alberto Irurueta Carro ([email protected])
 *
 * 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 com.irurueta.ar.epipolar;

import com.irurueta.geometry.CoordinatesType;
import com.irurueta.geometry.Point2D;
import com.irurueta.geometry.estimators.LockedException;
import com.irurueta.geometry.estimators.NotReadyException;

import java.util.ArrayList;
import java.util.List;

/**
 * Fixes matched pairs of points so that they perfectly follow a given epipolar
 * geometry.
 * When matching points typically the matching precision is about 1 pixel,
 * however this makes that matched points under a given epipolar geometry (i.e.
 * fundamental or essential matrix), do not lie perfectly on the corresponding
 * epipolar plane or epipolar liens.
 * The consequence is that triangularization of these matches will fail or
 * produce inaccurate results.
 * By fixing matched points using a corrector following a given epipolar
 * geometry, this effect is alleviated.
 * This corrector uses the Gold Standard method, which is more expensive to
 * compute than the Sampson approximation, but is capable to remove larger
 * errors assuming their gaussianity. Contrary to the Sampson corrector, the
 * Gold Standard method might fail in some situations, while in those cases
 * probably the Sampson corrector produces wrong results without failing.
 */
public class GoldStandardCorrector extends Corrector {

    /**
     * Indicates that correction must fallback to Sampson method if Gold
     * Standard correction fails.
     */
    public static final boolean DEFAULT_FALLBACK_TO_SAMPSON_ENABLED = true;

    /**
     * Indicates whether correction must fallback to Sampson method if Gold
     * Standard correction fails.
     */
    private boolean mFallbackToSampsonEnabled;

    /**
     * Constructor.
     */
    public GoldStandardCorrector() {
        super();
        mFallbackToSampsonEnabled = DEFAULT_FALLBACK_TO_SAMPSON_ENABLED;
    }

    /**
     * Constructor.
     *
     * @param fundamentalMatrix fundamental matrix to be set.
     */
    public GoldStandardCorrector(final FundamentalMatrix fundamentalMatrix) {
        super(fundamentalMatrix);
        mFallbackToSampsonEnabled = DEFAULT_FALLBACK_TO_SAMPSON_ENABLED;
    }

    /**
     * Constructor.
     *
     * @param leftPoints  points to be corrected on left view.
     * @param rightPoints points to be corrected on right view.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size.
     */
    public GoldStandardCorrector(final List leftPoints,
                                 final List rightPoints) {
        super(leftPoints, rightPoints);
        mFallbackToSampsonEnabled = DEFAULT_FALLBACK_TO_SAMPSON_ENABLED;
    }

    /**
     * Constructor.
     *
     * @param leftPoints        points to be corrected on left view.
     * @param rightPoints       points to be corrected on right view.
     * @param fundamentalMatrix fundamental matrix to be set.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size.
     */
    public GoldStandardCorrector(final List leftPoints,
                                 final List rightPoints,
                                 final FundamentalMatrix fundamentalMatrix) {
        super(leftPoints, rightPoints, fundamentalMatrix);
        mFallbackToSampsonEnabled = DEFAULT_FALLBACK_TO_SAMPSON_ENABLED;
    }

    /**
     * Constructor.
     *
     * @param listener listener to handle events generated by this class.
     */
    public GoldStandardCorrector(final CorrectorListener listener) {
        super(listener);
        mFallbackToSampsonEnabled = DEFAULT_FALLBACK_TO_SAMPSON_ENABLED;
    }

    /**
     * Constructor.
     *
     * @param fundamentalMatrix fundamental matrix to be set.
     * @param listener          listener to handle events generated by this class.
     */
    public GoldStandardCorrector(final FundamentalMatrix fundamentalMatrix,
                                 final CorrectorListener listener) {
        super(fundamentalMatrix, listener);
        mFallbackToSampsonEnabled = DEFAULT_FALLBACK_TO_SAMPSON_ENABLED;
    }

    /**
     * Constructor.
     *
     * @param leftPoints  points to be corrected on left view.
     * @param rightPoints points to be corrected on right view.
     * @param listener    listener to handle events generated by this class.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size.
     */
    public GoldStandardCorrector(final List leftPoints,
                                 final List rightPoints,
                                 final CorrectorListener listener) {
        super(leftPoints, rightPoints, listener);
        mFallbackToSampsonEnabled = DEFAULT_FALLBACK_TO_SAMPSON_ENABLED;
    }

    /**
     * Constructor.
     *
     * @param leftPoints        points to be corrected on left view.
     * @param rightPoints       points to be corrected on right view.
     * @param fundamentalMatrix fundamental matrix to be set.
     * @param listener          listener to handle events generated by this class.
     * @throws IllegalArgumentException if provided lists of points don't have
     *                                  the same size.
     */
    public GoldStandardCorrector(final List leftPoints,
                                 final List rightPoints,
                                 final FundamentalMatrix fundamentalMatrix,
                                 final CorrectorListener listener) {
        super(leftPoints, rightPoints, fundamentalMatrix, listener);
        mFallbackToSampsonEnabled = DEFAULT_FALLBACK_TO_SAMPSON_ENABLED;
    }

    /**
     * Indicates whether correction must fallback to Sampson method if Gold
     * Standard correction fails.
     * If true, whenever the correction of a matched pair of points fails,
     * its correction will be done with Sampson method instead. This allows
     * to continue correcting all points at the expense of getting worse
     * results in those points where Gold Standard method failed.
     * If false, whenever a single pair of matched pair of points fails to
     * be corrected, the algorithm stops and no points are corrected at all.
     * By default fallback is enabled.
     *
     * @return true if fallback is enabled, false otherwise..
     */
    public boolean isFallbackToSampsonEnabled() {
        return mFallbackToSampsonEnabled;
    }

    /**
     * Sets boolean indicating whether correction must fallback to Sampson
     * method if Gold Standard correction fails.
     * If true, whenever the correction of a matched pair of points fails,
     * its correction will be done with Sampson method instead. This allows
     * to continue correcting all points at the expense of getting worse
     * results in those points where Gold Standard method failed.
     * If false, whenever a single pair of matched pair of points fails to
     * be corrected, the algorithm stops and no points are corrected at all.
     * By default fallback is enabled.
     *
     * @param fallback true to enable fallback, false otherwise.
     * @throws LockedException if this instance is locked doing computations.
     */
    public void setFallbackToSampsonEnabled(final boolean fallback)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }

        mFallbackToSampsonEnabled = fallback;
    }

    /**
     * Corrects the lists of provided matched points to be corrected.
     *
     * @throws NotReadyException   if this instance is not ready (either points or
     *                             fundamental matrix has not been provided yet).
     * @throws LockedException     if this instance is locked doing computations.
     * @throws CorrectionException if correction fails.
     */
    @SuppressWarnings("DuplicatedCode")
    @Override
    public void correct() throws NotReadyException, LockedException,
            CorrectionException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        mLocked = true;

        if (mListener != null) {
            mListener.onCorrectStart(this);
        }

        Point2D leftPoint;
        Point2D rightPoint;
        Point2D leftCorrectedPoint;
        Point2D rightCorrectedPoint;
        mLeftCorrectedPoints = new ArrayList<>();
        mRightCorrectedPoints = new ArrayList<>();

        final int size = mLeftPoints.size();
        float progress;
        float previousProgress = 0.0f;
        for (int i = 0; i < size; i++) {
            leftPoint = mLeftPoints.get(i);
            rightPoint = mRightPoints.get(i);

            leftCorrectedPoint = Point2D.create(
                    CoordinatesType.HOMOGENEOUS_COORDINATES);
            rightCorrectedPoint = Point2D.create(
                    CoordinatesType.HOMOGENEOUS_COORDINATES);

            // correct single pair
            try {
                GoldStandardSingleCorrector.correct(leftPoint, rightPoint,
                        mFundamentalMatrix, leftCorrectedPoint,
                        rightCorrectedPoint);
            } catch (final CorrectionException e) {
                if (mFallbackToSampsonEnabled) {
                    // try using Sampson method instead
                    SampsonSingleCorrector.correct(leftPoint, rightPoint,
                            mFundamentalMatrix, leftCorrectedPoint,
                            rightCorrectedPoint);
                } else {
                    // let algorithm fail
                    throw e;
                }
            }

            mLeftCorrectedPoints.add(leftCorrectedPoint);
            mRightCorrectedPoints.add(rightCorrectedPoint);

            if (mListener != null) {
                progress = (float) i / (float) size;
                if (progress - previousProgress > mProgressDelta) {
                    // progress has changed significantly
                    previousProgress = progress;
                    mListener.onCorrectProgressChange(this, progress);
                }
            }
        }

        if (mListener != null) {
            mListener.onCorrectEnd(this);
        }

        mLocked = false;
    }

    /**
     * Gets type of correction being used.
     *
     * @return type of correction.
     */
    @Override
    public CorrectorType getType() {
        return CorrectorType.GOLD_STANDARD;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy