np::ndarray cleanVOC( const np::ndarray& lbl ) { unsigned char * plbl = (unsigned char *)lbl.get_data(); np::ndarray r = np::zeros( lbl.get_nd(), lbl.get_shape(), np::dtype::get_builtin<short>() ); short * pr = (short *)r.get_data(); for( int i=0; i<lbl.shape(0)*lbl.shape(1); i++ ) pr[i] = (plbl[i]>250)?-2:(short)plbl[i]-1; return r; }
/**************** other ****************/ static np::ndarray extractPatch( const np::ndarray &a, const RMatrixXi & l, const VectorXi & s ) { // Check the input if( !(a.get_flags() & np::ndarray::C_CONTIGUOUS) ) throw std::invalid_argument( "Contiguous array required!" ); if( l.cols() != a.get_nd() ) throw std::invalid_argument("location dimension does not match matrix"); if( l.cols() != s.size() ) throw std::invalid_argument("patch size and locations have different dimension"); for( int i=0; i<l.rows(); i++ ) for( int j=0; j<s.size(); j++ ) if( l(i,j)<0 || l(i,j)+s[j] > a.shape(j) ) throw std::invalid_argument("location out of range! Dimension "+std::to_string(j)+" : "+std::to_string(l(i,j))+" + "+std::to_string(s[j])+" ( 0 .. "+std::to_string(a.shape(j))+" )"); const int itemsize = a.get_dtype().get_itemsize(); // Create the output array std::vector<Py_intptr_t> out_size; out_size.push_back( l.rows() ); for( int i=0; i<s.size(); i++ ) if( s[i]>1 ) out_size.push_back( s[i] ); np::ndarray res = np::empty( out_size.size(), out_size.data(), a.get_dtype() ); // Prepare the patches const int ls = s[s.size()-1]; // Radius of the last dimension std::vector<int> patch_offsets(1,0); for( int d=0; d<s.size()-1; d++ ) { std::vector<int> opo = patch_offsets; patch_offsets.clear(); for( int i=0; i<s[d]; i++ ) for( int o: opo ) patch_offsets.push_back( a.shape(d+1)*(o+i) ); } const char * pa = a.get_data(); char * pres = res.get_data(); for( int i=0,k=0; i<l.rows(); i++ ) { int o=0; for( int d=0; d<s.size(); d++ ) o = a.shape(d)*o + l(i,d); // Extract the patches for( int po: patch_offsets ) { memcpy( pres+k*itemsize, pa+(po+o)*itemsize, ls*itemsize ); k += ls; } } return res; }
np::ndarray boundaryDistance( const np::ndarray & sg ) { checkArray( sg, short, 2, 2, true ); const int W = sg.shape(1), H = sg.shape(0); np::ndarray r = np::zeros( make_tuple(H,W), np::dtype::get_builtin<float>() ); const short * psg = (const short*)sg.get_data(); float * pr = (float*) r.get_data(); std::fill( pr, pr+W*H, 1e10 ); for( int it=0; it<10; it++ ) { for( int j=0,k=0; j<H; j++ ) for( int i=0; i<W; i++,k++ ) { if( i ) { if( psg[k] != psg[k-1] ) pr[k] = 0; else pr[k] = std::min( pr[k], pr[k-1]+1 ); } if( j ) { if( psg[k] != psg[k-W] ) pr[k] = 0; else pr[k] = std::min( pr[k], pr[k-W]+1 ); } } for( int j=H-1,k=W*H-1; j>=0; j-- ) for( int i=W-1; i>=0; i--,k-- ) { if( i ) { if( psg[k] != psg[k-1] ) pr[k-1] = 0; else pr[k-1] = std::min( pr[k]+1, pr[k-1] ); } if( j ) { if( psg[k] != psg[k-W] ) pr[k-W] = 0; else pr[k-W] = std::min( pr[k]+1, pr[k-W] ); } } } return r; }