Proposals nms( const Proposals & proposals, const std::vector<int> & order, float max_iou ) { IOUSet iou_set( proposals.s ); std::vector< VectorXb > r; for( int i: order ) { VectorXb p = proposals.p.row( i ); // Run NMS if( p.any() && iou_set.addIfNotIntersects(p,max_iou) ) r.push_back( p ); } Proposals res; res.s = proposals.s; res.p = RMatrixXb( r.size(), proposals.p.cols() ); for( int j=0; j<r.size(); j++ ) res.p.row(j) = r[j]; return res; }
std::vector<Proposals> nms( const std::vector<Proposals> & proposals, const std::vector<int> & order, float max_iou ) { int N = 0; for( const Proposals & p: proposals ) N += p.p.rows(); std::vector<int> s_id( N ), p_id( N ); for( int i=0, k=0; i<proposals.size(); i++ ) for( int j=0; j<proposals[i].p.rows(); j++, k++ ) { s_id[k] = i; p_id[k] = j; } std::vector<RMatrixXs> s; std::vector<int> Ns; for( int i=0; i<proposals.size(); i++ ) { s.push_back( proposals[i].s ); Ns.push_back( proposals[i].s.maxCoeff()+1 ); } const RMatrixXi ms = mergeOverSegmentations(s); const int Nms = ms.maxCoeff()+1; VectorXu ms_area = VectorXu::Zero( Nms ); for( int j=0; j<ms.rows(); j++ ) for( int i=0; i<ms.cols(); i++ ) ms_area[ ms(j,i) ]++; std::vector<IOUSet> iou_set; std::vector<VectorXs> ids; for( int i=0; i<s.size(); i++ ) { iou_set.push_back( s[i] ); ids.push_back( map_id( ms, s[i] ) ); } std::vector<int> pb; pb.reserve( Nms ); std::vector< std::vector< VectorXb > > r( proposals.size() ); for( int i: order ) { VectorXb p = proposals[ s_id[i] ].p.row( p_id[i] ); // Run NMS if( !p.any() || iou_set[ s_id[i] ].intersects(p,max_iou) ) continue; Vector4s bbox = iou_set[ s_id[i] ].computeBBox( p ); // Project each segmentation onto the common OS pb.clear(); for( int j=0; j<Nms; j++ ) if( p[ ids[ s_id[i] ][j] ] ) pb.push_back( j ); bool intersects = false; for( int k=0; !intersects && k<iou_set.size(); k++ ) if( s_id[i] != k ){ // Reproject the common OS to the current os VectorXu p_area = VectorXu::Zero( Ns[k] ); for( int j: pb ) p_area[ ids[ k ][j] ] += ms_area[ j ]; // Run more NMS intersects = iou_set[k].intersects(p_area, bbox, max_iou); } if( !intersects ) { // Add the segment iou_set[ s_id[i] ].add( p ); r[ s_id[i] ].push_back( p ); } } std::vector<Proposals> res( proposals.size() ); for( int i=0; i<proposals.size(); i++ ) { res[i].s = proposals[i].s; res[i].p = RMatrixXb( r[i].size(), proposals[i].p.cols() ); for( int j=0; j<r[i].size(); j++ ) res[i].p.row(j) = r[i][j]; } return res; }