Path: blob/master/modules/calib3d/src/compat_ptsetreg.cpp
16344 views
/*M///////////////////////////////////////////////////////////////////////////////////////1//2// IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.3//4// By downloading, copying, installing or using the software you agree to this license.5// If you do not agree to this license, do not download, install,6// copy or use the software.7//8//9// License Agreement10// For Open Source Computer Vision Library11//12// Copyright (C) 2000, Intel Corporation, all rights reserved.13// Copyright (C) 2013, OpenCV Foundation, all rights reserved.14// Third party copyrights are property of their respective owners.15//16// Redistribution and use in source and binary forms, with or without modification,17// are permitted provided that the following conditions are met:18//19// * Redistribution's of source code must retain the above copyright notice,20// this list of conditions and the following disclaimer.21//22// * Redistribution's in binary form must reproduce the above copyright notice,23// this list of conditions and the following disclaimer in the documentation24// and/or other materials provided with the distribution.25//26// * The name of the copyright holders may not be used to endorse or promote products27// derived from this software without specific prior written permission.28//29// This software is provided by the copyright holders and contributors "as is" and30// any express or implied warranties, including, but not limited to, the implied31// warranties of merchantability and fitness for a particular purpose are disclaimed.32// In no event shall the Intel Corporation or contributors be liable for any direct,33// indirect, incidental, special, exemplary, or consequential damages34// (including, but not limited to, procurement of substitute goods or services;35// loss of use, data, or profits; or business interruption) however caused36// and on any theory of liability, whether in contract, strict liability,37// or tort (including negligence or otherwise) arising in any way out of38// the use of this software, even if advised of the possibility of such damage.39//40//M*/4142#include "precomp.hpp"43#include "opencv2/calib3d/calib3d_c.h"4445/************************************************************************************\46Some backward compatibility stuff, to be moved to legacy or compat module47\************************************************************************************/4849using cv::Ptr;5051////////////////// Levenberg-Marquardt engine (the old variant) ////////////////////////5253CvLevMarq::CvLevMarq()54{55lambdaLg10 = 0; state = DONE;56criteria = cvTermCriteria(0,0,0);57iters = 0;58completeSymmFlag = false;59errNorm = prevErrNorm = DBL_MAX;60solveMethod = cv::DECOMP_SVD;61}6263CvLevMarq::CvLevMarq( int nparams, int nerrs, CvTermCriteria criteria0, bool _completeSymmFlag )64{65init(nparams, nerrs, criteria0, _completeSymmFlag);66}6768void CvLevMarq::clear()69{70mask.release();71prevParam.release();72param.release();73J.release();74err.release();75JtJ.release();76JtJN.release();77JtErr.release();78JtJV.release();79JtJW.release();80}8182CvLevMarq::~CvLevMarq()83{84clear();85}8687void CvLevMarq::init( int nparams, int nerrs, CvTermCriteria criteria0, bool _completeSymmFlag )88{89if( !param || param->rows != nparams || nerrs != (err ? err->rows : 0) )90clear();91mask.reset(cvCreateMat( nparams, 1, CV_8U ));92cvSet(mask, cvScalarAll(1));93prevParam.reset(cvCreateMat( nparams, 1, CV_64F ));94param.reset(cvCreateMat( nparams, 1, CV_64F ));95JtJ.reset(cvCreateMat( nparams, nparams, CV_64F ));96JtErr.reset(cvCreateMat( nparams, 1, CV_64F ));97if( nerrs > 0 )98{99J.reset(cvCreateMat( nerrs, nparams, CV_64F ));100err.reset(cvCreateMat( nerrs, 1, CV_64F ));101}102errNorm = prevErrNorm = DBL_MAX;103lambdaLg10 = -3;104criteria = criteria0;105if( criteria.type & CV_TERMCRIT_ITER )106criteria.max_iter = MIN(MAX(criteria.max_iter,1),1000);107else108criteria.max_iter = 30;109if( criteria.type & CV_TERMCRIT_EPS )110criteria.epsilon = MAX(criteria.epsilon, 0);111else112criteria.epsilon = DBL_EPSILON;113state = STARTED;114iters = 0;115completeSymmFlag = _completeSymmFlag;116solveMethod = cv::DECOMP_SVD;117}118119bool CvLevMarq::update( const CvMat*& _param, CvMat*& matJ, CvMat*& _err )120{121matJ = _err = 0;122123assert( !err.empty() );124if( state == DONE )125{126_param = param;127return false;128}129130if( state == STARTED )131{132_param = param;133cvZero( J );134cvZero( err );135matJ = J;136_err = err;137state = CALC_J;138return true;139}140141if( state == CALC_J )142{143cvMulTransposed( J, JtJ, 1 );144cvGEMM( J, err, 1, 0, 0, JtErr, CV_GEMM_A_T );145cvCopy( param, prevParam );146step();147if( iters == 0 )148prevErrNorm = cvNorm(err, 0, CV_L2);149_param = param;150cvZero( err );151_err = err;152state = CHECK_ERR;153return true;154}155156assert( state == CHECK_ERR );157errNorm = cvNorm( err, 0, CV_L2 );158if( errNorm > prevErrNorm )159{160if( ++lambdaLg10 <= 16 )161{162step();163_param = param;164cvZero( err );165_err = err;166state = CHECK_ERR;167return true;168}169}170171lambdaLg10 = MAX(lambdaLg10-1, -16);172if( ++iters >= criteria.max_iter ||173cvNorm(param, prevParam, CV_RELATIVE_L2) < criteria.epsilon )174{175_param = param;176state = DONE;177return true;178}179180prevErrNorm = errNorm;181_param = param;182cvZero(J);183matJ = J;184_err = err;185state = CALC_J;186return true;187}188189190bool CvLevMarq::updateAlt( const CvMat*& _param, CvMat*& _JtJ, CvMat*& _JtErr, double*& _errNorm )191{192CV_Assert( !err );193if( state == DONE )194{195_param = param;196return false;197}198199if( state == STARTED )200{201_param = param;202cvZero( JtJ );203cvZero( JtErr );204errNorm = 0;205_JtJ = JtJ;206_JtErr = JtErr;207_errNorm = &errNorm;208state = CALC_J;209return true;210}211212if( state == CALC_J )213{214cvCopy( param, prevParam );215step();216_param = param;217prevErrNorm = errNorm;218errNorm = 0;219_errNorm = &errNorm;220state = CHECK_ERR;221return true;222}223224assert( state == CHECK_ERR );225if( errNorm > prevErrNorm )226{227if( ++lambdaLg10 <= 16 )228{229step();230_param = param;231errNorm = 0;232_errNorm = &errNorm;233state = CHECK_ERR;234return true;235}236}237238lambdaLg10 = MAX(lambdaLg10-1, -16);239if( ++iters >= criteria.max_iter ||240cvNorm(param, prevParam, CV_RELATIVE_L2) < criteria.epsilon )241{242_param = param;243_JtJ = JtJ;244_JtErr = JtErr;245state = DONE;246return false;247}248249prevErrNorm = errNorm;250cvZero( JtJ );251cvZero( JtErr );252_param = param;253_JtJ = JtJ;254_JtErr = JtErr;255state = CALC_J;256return true;257}258259namespace {260static void subMatrix(const cv::Mat& src, cv::Mat& dst, const std::vector<uchar>& cols,261const std::vector<uchar>& rows) {262int nonzeros_cols = cv::countNonZero(cols);263cv::Mat tmp(src.rows, nonzeros_cols, CV_64FC1);264265for (int i = 0, j = 0; i < (int)cols.size(); i++)266{267if (cols[i])268{269src.col(i).copyTo(tmp.col(j++));270}271}272273int nonzeros_rows = cv::countNonZero(rows);274dst.create(nonzeros_rows, nonzeros_cols, CV_64FC1);275for (int i = 0, j = 0; i < (int)rows.size(); i++)276{277if (rows[i])278{279tmp.row(i).copyTo(dst.row(j++));280}281}282}283284}285286287void CvLevMarq::step()288{289using namespace cv;290const double LOG10 = log(10.);291double lambda = exp(lambdaLg10*LOG10);292int nparams = param->rows;293294Mat _JtJ = cvarrToMat(JtJ);295Mat _mask = cvarrToMat(mask);296297int nparams_nz = countNonZero(_mask);298if(!JtJN || JtJN->rows != nparams_nz) {299// prevent re-allocation in every step300JtJN.reset(cvCreateMat( nparams_nz, nparams_nz, CV_64F ));301JtJV.reset(cvCreateMat( nparams_nz, 1, CV_64F ));302JtJW.reset(cvCreateMat( nparams_nz, 1, CV_64F ));303}304305Mat _JtJN = cvarrToMat(JtJN);306Mat _JtErr = cvarrToMat(JtJV);307Mat_<double> nonzero_param = cvarrToMat(JtJW);308309subMatrix(cvarrToMat(JtErr), _JtErr, std::vector<uchar>(1, 1), _mask);310subMatrix(_JtJ, _JtJN, _mask, _mask);311312if( !err )313completeSymm( _JtJN, completeSymmFlag );314315_JtJN.diag() *= 1. + lambda;316solve(_JtJN, _JtErr, nonzero_param, solveMethod);317318int j = 0;319for( int i = 0; i < nparams; i++ )320param->data.db[i] = prevParam->data.db[i] - (mask->data.ptr[i] ? nonzero_param(j++) : 0);321}322323324CV_IMPL int cvRANSACUpdateNumIters( double p, double ep, int modelPoints, int maxIters )325{326return cv::RANSACUpdateNumIters(p, ep, modelPoints, maxIters);327}328329330CV_IMPL int cvFindHomography( const CvMat* _src, const CvMat* _dst, CvMat* __H, int method,331double ransacReprojThreshold, CvMat* _mask, int maxIters,332double confidence)333{334cv::Mat src = cv::cvarrToMat(_src), dst = cv::cvarrToMat(_dst);335336if( src.channels() == 1 && (src.rows == 2 || src.rows == 3) && src.cols > 3 )337cv::transpose(src, src);338if( dst.channels() == 1 && (dst.rows == 2 || dst.rows == 3) && dst.cols > 3 )339cv::transpose(dst, dst);340341if ( maxIters < 0 )342maxIters = 0;343if ( maxIters > 2000 )344maxIters = 2000;345346if ( confidence < 0 )347confidence = 0;348if ( confidence > 1 )349confidence = 1;350351const cv::Mat H = cv::cvarrToMat(__H), mask = cv::cvarrToMat(_mask);352cv::Mat H0 = cv::findHomography(src, dst, method, ransacReprojThreshold,353_mask ? cv::_OutputArray(mask) : cv::_OutputArray(), maxIters,354confidence);355356if( H0.empty() )357{358cv::Mat Hz = cv::cvarrToMat(__H);359Hz.setTo(cv::Scalar::all(0));360return 0;361}362H0.convertTo(H, H.type());363return 1;364}365366367CV_IMPL int cvFindFundamentalMat( const CvMat* points1, const CvMat* points2,368CvMat* fmatrix, int method,369double param1, double param2, CvMat* _mask )370{371cv::Mat m1 = cv::cvarrToMat(points1), m2 = cv::cvarrToMat(points2);372373if( m1.channels() == 1 && (m1.rows == 2 || m1.rows == 3) && m1.cols > 3 )374cv::transpose(m1, m1);375if( m2.channels() == 1 && (m2.rows == 2 || m2.rows == 3) && m2.cols > 3 )376cv::transpose(m2, m2);377378const cv::Mat FM = cv::cvarrToMat(fmatrix), mask = cv::cvarrToMat(_mask);379cv::Mat FM0 = cv::findFundamentalMat(m1, m2, method, param1, param2,380_mask ? cv::_OutputArray(mask) : cv::_OutputArray());381382if( FM0.empty() )383{384cv::Mat FM0z = cv::cvarrToMat(fmatrix);385FM0z.setTo(cv::Scalar::all(0));386return 0;387}388389CV_Assert( FM0.cols == 3 && FM0.rows % 3 == 0 && FM.cols == 3 && FM.rows % 3 == 0 && FM.channels() == 1 );390cv::Mat FM1 = FM.rowRange(0, MIN(FM0.rows, FM.rows));391FM0.rowRange(0, FM1.rows).convertTo(FM1, FM1.type());392return FM1.rows / 3;393}394395396CV_IMPL void cvComputeCorrespondEpilines( const CvMat* points, int pointImageID,397const CvMat* fmatrix, CvMat* _lines )398{399cv::Mat pt = cv::cvarrToMat(points), fm = cv::cvarrToMat(fmatrix);400cv::Mat lines = cv::cvarrToMat(_lines);401const cv::Mat lines0 = lines;402403if( pt.channels() == 1 && (pt.rows == 2 || pt.rows == 3) && pt.cols > 3 )404cv::transpose(pt, pt);405406cv::computeCorrespondEpilines(pt, pointImageID, fm, lines);407408bool tflag = lines0.channels() == 1 && lines0.rows == 3 && lines0.cols > 3;409lines = lines.reshape(lines0.channels(), (tflag ? lines0.cols : lines0.rows));410411if( tflag )412{413CV_Assert( lines.rows == lines0.cols && lines.cols == lines0.rows );414if( lines0.type() == lines.type() )415transpose( lines, lines0 );416else417{418transpose( lines, lines );419lines.convertTo( lines0, lines0.type() );420}421}422else423{424CV_Assert( lines.size() == lines0.size() );425if( lines.data != lines0.data )426lines.convertTo(lines0, lines0.type());427}428}429430431CV_IMPL void cvConvertPointsHomogeneous( const CvMat* _src, CvMat* _dst )432{433cv::Mat src = cv::cvarrToMat(_src), dst = cv::cvarrToMat(_dst);434const cv::Mat dst0 = dst;435436int d0 = src.channels() > 1 ? src.channels() : MIN(src.cols, src.rows);437438if( src.channels() == 1 && src.cols > d0 )439cv::transpose(src, src);440441int d1 = dst.channels() > 1 ? dst.channels() : MIN(dst.cols, dst.rows);442443if( d0 == d1 )444src.copyTo(dst);445else if( d0 < d1 )446cv::convertPointsToHomogeneous(src, dst);447else448cv::convertPointsFromHomogeneous(src, dst);449450bool tflag = dst0.channels() == 1 && dst0.cols > d1;451dst = dst.reshape(dst0.channels(), (tflag ? dst0.cols : dst0.rows));452453if( tflag )454{455CV_Assert( dst.rows == dst0.cols && dst.cols == dst0.rows );456if( dst0.type() == dst.type() )457transpose( dst, dst0 );458else459{460transpose( dst, dst );461dst.convertTo( dst0, dst0.type() );462}463}464else465{466CV_Assert( dst.size() == dst0.size() );467if( dst.data != dst0.data )468dst.convertTo(dst0, dst0.type());469}470}471472473