Beispiel #1
0
unsigned int Sampler::inverseCumulativeSampling( const VectorXd &cdf )
{
	int i=0;
	double m=cdf.size();
	double u = unifRand();
	
	while ( i<m && cdf.coeff(i)<=u  ) ++i;
		
	return i;
}
Beispiel #2
0
VectorXd Sampler::discreteCumulativeDistribution( const VectorXd &pdf)
{
	unsigned int m=pdf.size();
	VectorXd cdf(m);
	cdf.setZero(m);
	
	cdf(0)=pdf(0);
	for (unsigned int i=1; i<m; i++)
		cdf.coeffRef(i)=cdf.coeff(i-1)+pdf.coeff(i);
		
	return cdf;
}
Beispiel #3
0
MatrixXd SolveRobustMatting( const Mat& src, const Mat& trimap, const double sigma=0.1, const double gamma=0.1  )
{
    const Size sz( src.size() );
    const Mat fg( trimap == eFG ), bg( trimap != eBG );
    const Mat Known( trimap != eUnknown ), Unknown( trimap == eUnknown ) ;
    const vector<Point> ctf( GetMaskPoints ( erode(fg)!=fg ) ), ctb( GetMaskPoints ( dilate(bg)!=bg ) );
    typedef Triplet<double> Trip;
    typedef deque< Trip > Trips;
    Trips triplets;
    BuildProblem<3>( triplets, src, Known );
    double SumWF(0), SumWB(0) ;
    const int N( sz.area( ) );
    MatrixXd Alpha(sz.height,sz.width);
# define Push(r,c,v) if(v!=0) triplets.push_back(Trip(r,c,v))
    for (int I(0), x(0); x < sz.width; ++x) for( int y(0); y < sz.height; ++y, ++I  ) {
            double &alpha( Alpha.coeffRef(y,x) ), conf(0);
            if( Unknown.at<uchar>( y, x ) ){
                const double sigma( 0.1 ), sigma2( sigma * sigma );
                const Point p(x,y);
                const Vec3i ucolor( src.at<Vec3b>( p ) ) ;
                const Vec3d dcolor( ucolor );
                const vector< Point > fg_samp ( CollectSampleSet(p,ctf) );
                const SampleColorWeights_t fg_scw( GetSampleColorWeights( src, p, fg_samp ) );
                const vector< Point > bg_samp( CollectSampleSet(p,ctb) );
                const SampleColorWeights_t bg_scw( GetSampleColorWeights( src, p, bg_samp ) );
                typedef std::pair< double, double > AE;
                std::vector< AE > ae; ae.reserve(  fg_scw.size( ) * bg_scw.size( ) );
                for( SampleColorWeights_t::const_iterator f(fg_scw.begin()); f != fg_scw.end( ); ++f ){
                    for( SampleColorWeights_t::const_iterator b(bg_scw.begin()); b != bg_scw.end( ); ++b ){
                        const Vec3i usubb( ucolor - b->first );
                        const Vec3i fsubb( f->first - b->first );
                        const double ff( fsubb.dot(fsubb) ), ffx( max(ff,1.) ), uf( usubb.dot(fsubb) ), alpha( uf/ffx ); // alpha = (usubb*fsubb')/max(fsubb*fsubb',DMin);
                        const Vec3d difference( dcolor - alpha*Vec3d(f->first) - (1-alpha)*Vec3d(b->first) ); //difference = ucolor - (alpha*fgsampcolors(i,:) + (1-alpha)*bgsampcolors(j,:));
                        const double distanceratio2( difference.ddot(difference)/ffx );  //(difference*difference')/max(fsubb*fsubb', DMin);
                        const double Exp( exp( -distanceratio2 * f->second * b->second / sigma2 ) );
                        const double Alpha( max(min( alpha, 1. ), 0. ) );
                        ae.push_back( std::make_pair( Exp, Alpha ) );
                    }
                }
                enum{ M=3 };
                struct LT{ bool operator()( const AE& a, const AE& b ){ return b<a; } };
                nth_element( ae.begin( ), ae.begin( )+M, ae.end( ), LT() );
                std::accumulate( ae.begin( ), ae.begin( )+M, AE(0,0) );
                const AE v( std::accumulate( ae.begin( ), ae.begin( )+M, AE(0,0) ) );
                conf=v.first/M;
                alpha=v.second/M;
            } else {
                alpha = fg.at<uchar>(y,x)? 1:0;
            }
            const double wf ( conf*alpha + (1-conf)*(alpha>0.5?1:0) ), WF(gamma*wf), WB(gamma*(1-wf)) ;
            SumWF += WF;
            SumWB += WB;
            Push( I,   I   , gamma );
            Push( I,   N   , -WF   );
            Push( N,   I   , -WF   );
            Push( I,   N+1 , -WB   );
            Push( N+1, I   , -WB   );
        }
    Push( N,   N   , SumWF );
    Push( N+1, N+1 , SumWB );
# undef Push
    //
    const int Total(N+2);
    typedef std::pair< int, bool > UIF;
    typedef deque<UIF> UIFS;
    UIFS unknowns, knowns, * const uk[]={ &unknowns, &knowns };
    for( int i=0; i<Total; ++i ){
        const uchar t( i<N? trimap.at<uchar>( i%sz.height, i/sz.height ):0 );
        const UIF uif( std::make_pair( i,  ( i<N? t == eFG : i==N) ) );
        uk[ ( i<N && t == eUnknown ) ? 0 : 1 ] -> push_back( uif );
    }
    const int last_unknown( unknowns.size( ) );
    VectorXi Ak( knowns.size( ) ), indmap(Total), Indeces(Total) ;
    transform( knowns.begin( ), knowns.end( ), Ak.data( ), Second( ) );
    for( int k(0), j(0); k<2; ++k ){
        const UIFS &uifs( *uk[k] );
        for( UIFS::const_iterator i( uifs.begin( ) ); i != uifs.end( ); ++i, ++j ){
            const UIF uif( *i );
            const int index( uif.first );
            Indeces.coeffRef(j) = index ;
            indmap.coeffRef(index) = j ;
        }
    }
    Trips lu, rt;
    for( Trips::const_iterator i( triplets.begin( ) ); i != triplets.end( ); ++i ){
        const int row( indmap[i->row()] ), col( indmap[i->col()] );
        const Trip t( indmap[i->row()], indmap[i->col()], i->value() );
        if( row < last_unknown ){
            if( col<last_unknown ){
                lu.push_back( Trip( row, col,i->value( ) ) );
            } else {
                rt.push_back( Trip( row, col-last_unknown,i->value( ) ) );
            }
        }
    }
    typedef SparseMatrix<double> SpMat;
    SpMat Lu(last_unknown,last_unknown);
    Lu.setFromTriplets( lu.begin( ), lu.end( ) );
    SpMat Rt(last_unknown,Total-last_unknown);
    Rt.setFromTriplets( rt.begin( ), rt.end( ) );
    const VectorXd Au( SimplicialCholesky<SpMat>(Lu).solve( -Rt*Ak.cast<double>() ) );
    for( int i(0); i< last_unknown; ++i ){
        const int ind( Indeces.coeff(i) );
        const double auki( Au.coeff( i ) ), alpha( min( 1., max(0., auki) ) );
        Alpha.coeffRef( ind % sz.height, ind / sz.height ) = alpha;
    }
    return Alpha;
}