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

com.irurueta.ar.epipolar.estimators.PlanarFundamentalMatrixEstimator Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
/*
 * Copyright (C) 2017 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.estimators;

import com.irurueta.ar.epipolar.EssentialMatrix;
import com.irurueta.ar.epipolar.FundamentalMatrix;
import com.irurueta.geometry.GeometryException;
import com.irurueta.geometry.HomogeneousPoint2D;
import com.irurueta.geometry.PinholeCameraIntrinsicParameters;
import com.irurueta.geometry.Point2D;
import com.irurueta.geometry.Rotation3D;
import com.irurueta.geometry.Transformation2D;
import com.irurueta.geometry.estimators.LockedException;
import com.irurueta.geometry.estimators.NotReadyException;

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

/**
 * This class takes an input 2D homography (e.g. transformation) and a given
 * pair of intrinsic parameters for left and right views, and estimates all
 * possible fundamental matrices generating such homography in a planar scene.
 * This estimator will generate either 2 or 4 possible solutions, however only
 * 1 solution will be physically possible, which corresponds to the solution
 * that generates triangulated points located in front of the cameras generating
 * such epipolar geometries.
 * This class is useful in planar scenes where 8-point and 7-point algorithms
 * will fail since this kind of geometry is a degenerate configuration of
 * points.
 */
public class PlanarFundamentalMatrixEstimator {

    /**
     * 2D transformation relating two views (left view to right view).
     */
    private Transformation2D mHomography;

    /**
     * Intrinsic parameters to be used on left view.
     */
    private PinholeCameraIntrinsicParameters mLeftIntrinsics;

    /**
     * Intrinsic parameters to be used on right view.
     */
    private PinholeCameraIntrinsicParameters mRightIntrinsics;

    /**
     * Listener to attend events generated by this instance.
     */
    private PlanarFundamentalMatrixEstimatorListener mListener;

    /**
     * Indicates whether estimator is locked while estimating fundamental
     * matrix.
     */
    private boolean mLocked;

    /**
     * Constructor.
     */
    public PlanarFundamentalMatrixEstimator() {
    }

    /**
     * Constructor.
     *
     * @param homography      2D transformation relating two views (left view to
     *                        right view).
     * @param leftIntrinsics  intrinsic parameters to be used on left view.
     * @param rightIntrinsics intrinsic parameters to be used on right view.
     */
    public PlanarFundamentalMatrixEstimator(final Transformation2D homography,
                                            final PinholeCameraIntrinsicParameters leftIntrinsics,
                                            final PinholeCameraIntrinsicParameters rightIntrinsics) {
        mHomography = homography;
        mLeftIntrinsics = leftIntrinsics;
        mRightIntrinsics = rightIntrinsics;
    }

    /**
     * Constructor.
     *
     * @param homography      2D transformation relating two views (left view to
     *                        right view).
     * @param leftIntrinsics  intrinsic parameters to be used on left view.
     * @param rightIntrinsics intrinsic parameters to be used on right view.
     * @param listener        listener to attend events generated by this instance.
     */
    public PlanarFundamentalMatrixEstimator(final Transformation2D homography,
                                            final PinholeCameraIntrinsicParameters leftIntrinsics,
                                            final PinholeCameraIntrinsicParameters rightIntrinsics,
                                            final PlanarFundamentalMatrixEstimatorListener listener) {
        this(homography, leftIntrinsics, rightIntrinsics);
        mListener = listener;
    }

    /**
     * Gets 2D transformation relating two views (left view to right view).
     *
     * @return 2D transformation relating two views.
     */
    public Transformation2D getHomography() {
        return mHomography;
    }

    /**
     * Sets 2D transformation relating two views (left view to right view).
     *
     * @param homography 2D transformation relating two views.
     * @throws LockedException if estimator is locked.
     */
    public void setHomography(final Transformation2D homography)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        mHomography = homography;
    }

    /**
     * Gets intrinsic parameters to be used on left view.
     *
     * @return intrinsic parameters to be used on left view.
     */
    public PinholeCameraIntrinsicParameters getLeftIntrinsics() {
        return mLeftIntrinsics;
    }

    /**
     * Sets intrinsic parameters to be used on left view.
     *
     * @param leftIntrinsics intrinsic parameters to be used on left view.
     * @throws LockedException if estimator is locked.
     */
    public void setLeftIntrinsics(
            final PinholeCameraIntrinsicParameters leftIntrinsics)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        mLeftIntrinsics = leftIntrinsics;
    }

    /**
     * Gets intrinsic parameters to be used on right view.
     *
     * @return intrinsic parameters to be used on right view.
     */
    public PinholeCameraIntrinsicParameters getRightIntrinsics() {
        return mRightIntrinsics;
    }

    /**
     * Sets intrinsic parameters to be used on right view.
     *
     * @param rightIntrinsics intrinsic parameters to be used on right view.
     * @throws LockedException if estimator is locked.
     */
    public void setRightIntrinsics(
            final PinholeCameraIntrinsicParameters rightIntrinsics)
            throws LockedException {
        if (isLocked()) {
            throw new LockedException();
        }
        mRightIntrinsics = rightIntrinsics;
    }

    /**
     * Gets listener to attend events generated by this instance.
     *
     * @return listener to attend events generated by this instance.
     */
    public PlanarFundamentalMatrixEstimatorListener getListener() {
        return mListener;
    }

    /**
     * Sets listener to attend events generated by this instance.
     *
     * @param listener listener to attend events generated by this instance.
     */
    public void setListener(final PlanarFundamentalMatrixEstimatorListener listener) {
        mListener = listener;
    }

    /**
     * Indicates whether estimator is locked while estimating fundamental
     * matrix.
     *
     * @return true if estimator is locked, false otherwise.
     */
    public boolean isLocked() {
        return mLocked;
    }

    /**
     * Indicates whether estimator is ready to start the estimation when all
     * required data has been provided.
     *
     * @return true if estimator is ready, false otherwise.
     */
    public boolean isReady() {
        return mHomography != null && mLeftIntrinsics != null &&
                mRightIntrinsics != null;
    }

    /**
     * Estimates fundamental matrices and returns the estimated result.
     *
     * @return estimated fundamental matrices.
     * @throws LockedException                     if estimator is locked.
     * @throws NotReadyException                   if estimator is not ready.
     * @throws FundamentalMatrixEstimatorException if estimation fails for some
     *                                             reason.
     */
    public List estimate() throws LockedException,
            NotReadyException, FundamentalMatrixEstimatorException {
        final List result = new ArrayList<>();
        estimate(result);
        return result;
    }

    /**
     * Estimates fundamental matrices and stores result into provided instance.
     *
     * @param result instance where result will be stored.
     * @throws LockedException                     if estimator is locked.
     * @throws NotReadyException                   if estimator is not ready.
     * @throws FundamentalMatrixEstimatorException if estimation fails for some
     *                                             reason.
     */
    public void estimate(final List result) throws LockedException,
            NotReadyException, FundamentalMatrixEstimatorException {
        if (isLocked()) {
            throw new LockedException();
        }
        if (!isReady()) {
            throw new NotReadyException();
        }

        try {
            mLocked = true;

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

            final HomographyDecomposer decomposer = new HomographyDecomposer(
                    mHomography, mLeftIntrinsics, mRightIntrinsics);

            final List decompositions =
                    decomposer.decompose();
            result.clear();
            for (final HomographyDecomposition decomposition : decompositions) {
                final Rotation3D rotation = decomposition.getTransformation().
                        getRotation();
                final Point2D translation = new HomogeneousPoint2D(
                        decomposition.getTransformation().getTranslation());
                final EssentialMatrix essential = new EssentialMatrix(rotation,
                        translation);
                final FundamentalMatrix fundamentalMatrix = essential.
                        toFundamentalMatrix(mLeftIntrinsics, mRightIntrinsics);
                result.add(fundamentalMatrix);
            }

            if (mListener != null) {
                mListener.onEstimateEnd(this, result);
            }

        } catch (final GeometryException e) {
            throw new FundamentalMatrixEstimatorException(e);
        } finally {
            mLocked = false;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy