static void ImageOverSegmentation_boundaryMap( MEX_ARGS ) { if( nrhs != 1 ) { mexErrMsgTxt( "Expected a ImageOverSegmentation" ); return ; } if( nlhs != 1 ) { mexErrMsgTxt( "Expected a single return argument" ); return ; } std::shared_ptr<ImageOverSegmentation> os = mat2Ptr<ImageOverSegmentation>( prhs[0] ); RMatrixXf s = os->boundaryMap(); // Create and write the resulting segmentation mwSize dims[2] = {(mwSize)s.rows(), (mwSize)s.cols()}; plhs[0] = mxCreateNumericArray( 2, dims, mxSINGLE_CLASS, mxREAL ); MatrixXf::Map( (float*)mxGetData(plhs[0]), s.rows(), s.cols() ) = s; }
RMatrixXf pairwiseDistance( const RMatrixXf & X, int N ) { static std::mt19937 gen; // Do a random pairwise projection const int M = X.cols(); RMatrixXf r( X.rows(), N ); std::vector<int> o1(N), o2(N); for( int i=0; i<N; i++ ) { int r = gen()%((M-1)*M/2); o1[i] = int(sqrt(0.25+2*r)-0.5 + 0.1/M/*for numeric stability*/); o2[i] = r - (o1[i]+1)*o1[i]/2; } for( int i=0; i<X.rows(); i++ ) for( int j=0; j<N; j++ ) r(i,j) = ((X(i,o1[j]) == X(i,o2[j]))); return r; }
VectorXf project1D( const RMatrixXf & Y, int * rep_label=NULL ) { // const int MAX_SAMPLE = 20000; const bool fast = true, very_fast = true; // Remove the DC (Y : N x M) RMatrixXf dY = Y.rowwise() - Y.colwise().mean(); // RMatrixXf sY = dY; // if( 0 < MAX_SAMPLE && MAX_SAMPLE < dY.rows() ) { // VectorXi samples = randomChoose( dY.rows(), MAX_SAMPLE ); // std::sort( samples.data(), samples.data()+samples.size() ); // sY = RMatrixXf( samples.size(), dY.cols() ); // for( int i=0; i<samples.size(); i++ ) // sY.row(i) = dY.row( samples[i] ); // } // ... and use (pc > 0) VectorXf lbl = VectorXf::Zero( Y.rows() ); // Find the largest PC of (dY.T * dY) and project onto it if( very_fast ) { // Find the largest PC using poweriterations VectorXf U = VectorXf::Random( dY.cols() ); U = U.array() / U.norm()+std::numeric_limits<float>::min(); for( int it=0; it<20; it++ ){ // Normalize VectorXf s = dY.transpose()*(dY*U); s.array() /= s.norm()+std::numeric_limits<float>::min(); if ( (U-s).norm() < 1e-6 ) break; U = s; } // Project onto the PC lbl = dY*U; } else if(fast) { // Compute the eigen values of the covariance (and project onto the largest eigenvector) MatrixXf cov = dY.transpose()*dY; SelfAdjointEigenSolver<MatrixXf> eigensolver(0.5*(cov+cov.transpose())); MatrixXf ev = eigensolver.eigenvectors(); lbl = dY * ev.col( ev.cols()-1 ); } else { // Use the SVD JacobiSVD<RMatrixXf> svd = dY.jacobiSvd(ComputeThinU | ComputeThinV ); // Project onto the largest PC lbl = svd.matrixU().col(0) * svd.singularValues()[0]; } // Find the representative label if( rep_label ) dY.array().square().rowwise().sum().minCoeff( rep_label ); return (lbl.array() < 0).cast<float>(); }
RMatrixXf evalBoundary( const RMatrixXf & d, const std::vector<RMatrixXb> & bnd, int nthres, double max_r, const RMatrixXb & mask ) { RMatrixXf r( nthres, 5 ); for( int i=0; i<nthres; i++ ) { float t = 1.0 * i / nthres; r(i,0) = t; RMatrixXb tmp = d.array() > t; if ( t > 0 ) thinningGuoHall( tmp ); r.block(i,1,1,4) = evalBoundaryBinary( tmp, bnd, max_r, mask ).cast<float>().transpose(); } return r; }
void SeedFeatureFactory::train( const std::vector< std::shared_ptr<ImageOverSegmentation> > &ios, const std::vector<VectorXs> & lbl ) { printf(" * Training SeedFeature\n"); static std::mt19937 rand; const int N_SAMPLES = 5000; int n_pos=0, n_neg=0; for( VectorXs l: lbl ) { n_pos += (l.array()>=0).cast<int>().sum(); n_neg += (l.array()==-1).cast<int>().sum(); } // Collect training examples float sampling_freq[] = {0.5f*N_SAMPLES / n_neg, 0.5f*N_SAMPLES / n_pos}; std::vector<RowVectorXf> f; std::vector<float> l; #pragma omp parallel for for( int i=0; i<ios.size(); i++ ) { RMatrixXf ftr = SeedFeature::computeObjFeatures( *ios[i] ); for( int j=0; j<ios[i]->Ns(); j++ ) if( lbl[i][j] >= -1 && rand() < rand.max()*sampling_freq[ lbl[i][j]>=0 ] ) { #pragma omp critical { l.push_back( lbl[i][j]>=0 ); f.push_back( ftr.row(j) ); } } } printf(" - Computing parameters\n"); // Fit the ranking functions RMatrixXf A( f.size(), f[0].size() ); VectorXf b( l.size() ); for( int i=0; i<f.size(); i++ ) { A.row(i) = f[i]; b[i] = l[i]; } // Solve A*x = b param_ = A.colPivHouseholderQr().solve(b); printf(" - done %f\n",(A*param_-b).array().abs().mean()); }
void Word2Vec::save_word2vec(string filename, const RMatrixXf& data, bool binary) { IOFormat CommaInitFmt(StreamPrecision, DontAlignCols); if(binary) { std::ofstream out(filename, std::ios::binary); char blank = ' '; char enter = '\n'; int size = sizeof(char); int r_size = data.cols() * sizeof(RMatrixXf::Scalar); std::string head = std::string(std::to_string(vocab.size()) + " " + std::to_string(data.cols()) + "\n"); out.write(head.c_str(),head.length()); RMatrixXf::Index r = data.rows(); RMatrixXf::Index c = data.cols(); out.write((char*) &r, sizeof(RMatrixXf::Index)); out.write(&blank, size); out.write((char*) &c, sizeof(RMatrixXf::Index)); out.write(&enter, size); for(auto v: vocab) { out.write(v->text.c_str(), v->text.size()); out.write(&blank, size); out.write((char*) data.row(v->index).data(), r_size); out.write(&enter, size); } out.close(); } else { ofstream out(filename); out << data.rows() << " " << data.cols() << std::endl; for(auto v: vocab) { out << v->text << " " << data.row(v->index).format(CommaInitFmt) << endl;; } out.close(); } }
RMatrixXf SeedFeature::computeObjFeatures( const ImageOverSegmentation & ios ) { Image rgb_im = ios.image(); const RMatrixXs & s = ios.s(); const Edges & g = ios.edges(); const int Ns = ios.Ns(); RMatrixXf r = RMatrixXf::Zero( Ns, N_OBJ_F ); if( N_OBJ_F<=1 ) return r; VectorXf area = bin( s, 1, [&](int x, int y){ return 1.f; } ); VectorXf norm = (area.array()+1e-10).cwiseInverse(); r.col(0).setOnes(); int o = 1; if (N_OBJ_COL>=6) { Image lab_im; rgb2lab( lab_im, rgb_im ); r.middleCols(o,6) = norm.asDiagonal() * bin( s, 6, [&](int x, int y){ return makeArray<6>( lab_im(y,x,0), lab_im(y,x,1), lab_im(y,x,2), lab_im(y,x,0)*lab_im(y,x,0), lab_im(y,x,1)*lab_im(y,x,1), lab_im(y,x,2)*lab_im(y,x,2) ); } ); RMatrixXf col = r.middleCols(o,3); if( N_OBJ_COL >= 9) r.middleCols(o+6,3) = col.array().square(); o += N_OBJ_COL; // Add color difference features if( N_OBJ_COL_DIFF ) { RMatrixXf bcol = RMatrixXf::Ones( col.rows(), col.cols()+1 ); bcol.leftCols(3) = col; for( int it=0; it*3+2<N_OBJ_COL_DIFF; it++ ) { // Apply a box filter on the graph RMatrixXf tmp = bcol; for( const auto & e: g ) { tmp.row(e.a) += bcol.row(e.b); tmp.row(e.b) += bcol.row(e.a); } bcol = tmp.col(3).cwiseInverse().asDiagonal()*tmp; r.middleCols(o,3) = (bcol.leftCols(3)-col).array().abs(); o += 3; } } } if( N_OBJ_POS >= 2 ) { RMatrixXf xy = norm.asDiagonal() * bin( s, 2, [&](int x, int y){ return makeArray<2>( 1.0*x/(s.cols()-1)-0.5, 1.0*y/(s.rows()-1)-0.5 ); } ); r.middleCols(o,2) = xy; o+=2; if( N_OBJ_POS >=4 ) { r.middleCols(o,2) = xy.array().square(); o+=2; } } if( N_OBJ_EDGE ) { RMatrixXf edge_map = DirectedSobel().detect( rgb_im ); for( int j=0; j<s.rows(); j++ ) for( int i=0; i<s.cols(); i++ ) { const int id = s(j,i); int bin = edge_map(j,i)*N_OBJ_EDGE; if ( bin < 0 ) bin = 0; if ( bin >= N_OBJ_EDGE ) bin = N_OBJ_EDGE-1; r(id,o+bin) += norm[id]; } o += N_OBJ_EDGE; } const int N_BASIC = o-1; // Add in context features for( int i=0; i<N_OBJ_CONTEXT; i++ ) { const int o0 = o - N_BASIC; // Box filter the edges RMatrixXf f = RMatrixXf::Ones( Ns, N_BASIC+1 ), bf = RMatrixXf::Zero( Ns, N_BASIC+1 ); f.rightCols( N_BASIC ) = r.middleCols(o0,N_BASIC); for( Edge e: g ) { bf.row(e.a) += f.row(e.b); bf.row(e.b) += f.row(e.a); } r.middleCols(o,N_BASIC) = bf.col(0).array().max(1e-10f).inverse().matrix().asDiagonal() * bf.rightCols(N_BASIC); o += N_BASIC; } return r; }
RMatrixXf evalBoundary( const RMatrixXf & d, const std::vector<RMatrixXb> & bnd, int nthres, double max_r ) { return evalBoundary( d, bnd, nthres, max_r, RMatrixXb::Ones(d.rows(),d.cols()) ); }
RMatrixXf GeodesicDistance::compute( const RMatrixXf &start ) const { RMatrixXf r = 0*start; for( int i=0; i<start.cols(); i++ ) r.col(i) = compute( (VectorXf)start.col(i) ); return r; }
LabeledSplit( const RMatrixXf & lbl, const VectorXf & weight ): weight_(weight) { if( lbl.cols()!= 1 ) throw std::invalid_argument( "Only 1d labels supported!" ); lbl_ = lbl.cast<int>(); }
static RMatrixXf exactGaussianFilter_m( const RMatrixXf & image, int rad, int R ) { RMatrixXf r( image.rows(), image.cols() ); exactGaussianFilter( r.data(), image.data(), image.cols(), image.rows(), 1, rad, R ); return r; }
/**************** filter.cpp ****************/ static RMatrixXf percentileFilter_m( const RMatrixXf & image, int rad, float p ) { RMatrixXf r( image.rows(), image.cols() ); percentileFilter( r.data(), image.data(), image.cols(), image.rows(), 1, rad, p ); return r; }