VectorXi IOUSet::computeTree(const VectorXb & s) const {
    VectorXi r = VectorXi::Zero(parent_.size());
    std::copy( s.data(), s.data()+s.size(), r.data() );

    for( int i=0; i<r.size(); i++ )
        if( parent_[i] >= 0 )
            r[ parent_[i] ] += r[i];
    return r;
}
Пример #2
0
typename pcl::PointCloud<T>::Ptr maskFilterDisorganized(typename pcl::PointCloud<T>::ConstPtr in, const VectorXb& mask) {
  int n = mask.sum();
  typename pcl::PointCloud<T>::Ptr out(new typename pcl::PointCloud<T>());
  out->points.reserve(n);
  for (int i=0; i < mask.size(); ++i) {
    if (mask[i]) out->points.push_back(in->points[i]);
  }
  setWidthToSize(out);
  return out;
}
Пример #3
0
std::vector<T> filter( const std::vector<T> & v, const VectorXb & x ) {
	std::vector<T> r( x.cast<int>().array().sum() );
	for( int i=0, j=0; i<x.size(); i++ )
		if( x[i] )
			r[j++] = v[i];
	return r;
}
Пример #4
0
static VectorXi find( const VectorXb & mask ) {
	VectorXi r( mask.cast<int>().sum() );
	for( int i=0, k=0; i<mask.size(); i++ )
		if( mask[i] )
			r[k++] = i;
	return r;
}
Пример #5
0
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;
}
Пример #6
0
typename pcl::PointCloud<T>::Ptr maskFilterOrganized(typename pcl::PointCloud<T>::ConstPtr in, const VectorXb& mask) {
  typename pcl::PointCloud<T>::Ptr out(new typename pcl::PointCloud<T>(*in));
  for (int i=0; i < mask.size(); ++i) {
    if (!mask[i]) {
      T& pt = out->points[i];
      pt.x = NAN;
      pt.y = NAN;
      pt.z = NAN;
    }
  }
  return out;
}
Пример #7
0
void build_dedge(const MatrixXu &F, const MatrixXf &V, VectorXu &V2E,
                         VectorXu &E2E, VectorXb &boundary, VectorXb &nonManifold,
                         const ProgressCallback &progress, bool quiet) {
    if (!quiet) {
        cout << "Building a directed edge data structure .. ";
        cout.flush();
    }
    Timer<> timer;

    if (progress && !quiet)
        progress("Building directed edge data structure", 0.0f);

    V2E.resize(V.cols());
    V2E.setConstant(INVALID);

    uint32_t deg = F.rows();
    std::vector<std::pair<uint32_t, uint32_t>> tmp(F.size());

    tbb::parallel_for(
        tbb::blocked_range<uint32_t>(0u, (uint32_t) F.cols(), GRAIN_SIZE),
        [&](const tbb::blocked_range<uint32_t> &range) {
            for (uint32_t f = range.begin(); f != range.end(); ++f) {
                for (uint32_t i = 0; i < deg; ++i) {
                    uint32_t idx_cur = F(i, f),
                             idx_next = F((i+1)%deg, f),
                             edge_id = deg * f + i;
                    if (idx_cur >= V.cols() || idx_next >= V.cols())
                        throw std::runtime_error("Mesh data contains an out-of-bounds vertex reference!");
                    if (idx_cur == idx_next)
                        continue;

                    tmp[edge_id] = std::make_pair(idx_next, INVALID);
                    if (!atomicCompareAndExchange(&V2E[idx_cur], edge_id, INVALID)) {
                        uint32_t idx = V2E[idx_cur];
                        while (!atomicCompareAndExchange(&tmp[idx].second, edge_id, INVALID))
                            idx = tmp[idx].second;
                    }
                }
            }
            if (!quiet)
                SHOW_PROGRESS_RANGE(range, F.cols(), "Building directed edge data structure (1/3)");
        }
    );

    nonManifold.resize(V.cols());
    nonManifold.setConstant(false);

    E2E.resize(F.cols() * deg);
    E2E.setConstant(INVALID);

    tbb::parallel_for(
        tbb::blocked_range<uint32_t>(0u, (uint32_t) F.cols(), GRAIN_SIZE),
        [&](const tbb::blocked_range<uint32_t> &range) {
            for (uint32_t f = range.begin(); f != range.end(); ++f) {
                for (uint32_t i = 0; i < deg; ++i) {
                    uint32_t idx_cur = F(i, f),
                             idx_next = F((i+1)%deg, f),
                             edge_id_cur = deg * f + i;

                    if (idx_cur == idx_next)
                        continue;

                    uint32_t it = V2E[idx_next], edge_id_opp = INVALID;
                    while (it != INVALID) {
                        if (tmp[it].first == idx_cur) {
                            if (edge_id_opp == INVALID) {
                                edge_id_opp = it;
                            } else {
                                nonManifold[idx_cur] = true;
                                nonManifold[idx_next] = true;
                                edge_id_opp = INVALID;
                                break;
                            }
                        }
                        it = tmp[it].second;
                    }

                    if (edge_id_opp != INVALID && edge_id_cur < edge_id_opp) {
                        E2E[edge_id_cur] = edge_id_opp;
                        E2E[edge_id_opp] = edge_id_cur;
                    }
                }
            }
            if (!quiet)
                SHOW_PROGRESS_RANGE(range, F.cols(), "Building directed edge data structure (2/3)");
        }
    );

    std::atomic<uint32_t> nonManifoldCounter(0), boundaryCounter(0), isolatedCounter(0);

    boundary.resize(V.cols());
    boundary.setConstant(false);

    /* Detect boundary regions of the mesh and adjust vertex->edge pointers*/
    tbb::parallel_for(
        tbb::blocked_range<uint32_t>(0u, (uint32_t) V.cols(), GRAIN_SIZE),
        [&](const tbb::blocked_range<uint32_t> &range) {
            for (uint32_t i = range.begin(); i != range.end(); ++i) {
                uint32_t edge = V2E[i];
                if (edge == INVALID) {
                    isolatedCounter++;
                    continue;
                }
                if (nonManifold[i]) {
                    nonManifoldCounter++;
                    V2E[i] = INVALID;
                    continue;
                }

                /* Walk backwards to the first boundary edge (if any) */
                uint32_t start = edge, v2e = INVALID;
                do {
                    v2e  = std::min(v2e, edge);
                    uint32_t prevEdge = E2E[dedge_prev(edge, deg)];
                    if (prevEdge == INVALID) {
                        /* Reached boundary -- update the vertex->edge link */
                        v2e = edge;
                        boundary[i] = true;
                        boundaryCounter++;
                        break;
                    }
                    edge = prevEdge;
                } while (edge != start);
                V2E[i] = v2e;
            }
            if (!quiet)
                SHOW_PROGRESS_RANGE(range, V.cols(), "Building directed edge data structure (3/3)");
        }
    );

    if (!quiet) {
        cout << "done. (";
        if (nonManifoldCounter)
            cout << nonManifoldCounter << " non-manifold vertices, ";
        if (boundaryCounter)
            cout << boundaryCounter << " boundary vertices, ";
        if (isolatedCounter)
            cout << isolatedCounter << " isolated vertices, ";
        cout << "took " << timeString(timer.value()) << ")" << endl;
    }
}
Пример #8
0
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;
}