Пример #1
0
unsigned int NormalDetector::computeInterestPoints(const LaserReading& reading, const std::vector<double>& signal, std::vector<InterestPoint*>& point, 
						   std::vector< std::vector<unsigned int> >& indexes, std::vector<unsigned int>& maxRangeMapping) const
{
    point.clear();
    point.reserve(reading.getRho().size());
    const std::vector<Point2D>& worldPoints = reading.getWorldCartesian();
    for(unsigned int i = 0; i < indexes.size(); i++){
		for(unsigned int j = 0; j < indexes[i].size(); j++){
			OrientedPoint2D pose;
			unsigned int pointIndex = maxRangeMapping[indexes[i][j]];
		
			// Reomoving the detection in the background and pushing it to the foreground
			double rangeBefore = (pointIndex > 1)? reading.getRho()[pointIndex - 1] : reading.getMaxRange();
			double rangeAfter = (pointIndex < worldPoints.size() - 1)? reading.getRho()[pointIndex + 1] : reading.getMaxRange();
			double rangeCurrent = reading.getRho()[pointIndex];
			if(rangeBefore < rangeAfter){
				if(rangeBefore < rangeCurrent){
					pointIndex = pointIndex - 1;
				}
			} else if(rangeAfter < rangeCurrent){
				pointIndex = pointIndex + 1;
			}
			
			// Removing max range reading
			if(reading.getRho()[pointIndex] >= reading.getMaxRange()){
				continue;
			}

			pose.x =  (reading.getWorldCartesian()[pointIndex]).x;
			pose.y =  (reading.getWorldCartesian()[pointIndex]).y;
			pose.theta = normAngle(signal[indexes[i][j]], -M_PI);
			
			bool exists = false;
			for(unsigned int k = 0; !exists && k < point.size(); k++){
				exists = exists || (fabs(pose.x - point[k]->getPosition().x) <= 0.2 &&  fabs(pose.y - point[k]->getPosition().y) <= 0.2);
			}
			if(exists) continue;

	    unsigned int first = indexes[i][j] - floor((int)m_filterBank[i].size()/2.0);
	    unsigned int last = indexes[i][j] + floor((int)m_filterBank[i].size()/2.0);
	    std::vector<Point2D> support(last - first + 1);
	    for(unsigned int p = 0; p < support.size(); p++) {
		support[p] = Point2D(worldPoints[maxRangeMapping[p + first]]);
	    }
	    
			double maxDistance = -1e20;
			for(unsigned int k = 0; k < support.size(); k++){
				double distance = sqrt((pose.x - support[k].x)*(pose.x - support[k].x) + (pose.y - support[k].y)*(pose.y - support[k].y));
				maxDistance = maxDistance < distance ? distance : maxDistance;
			}
			InterestPoint *interest = new InterestPoint(pose, maxDistance);
	// 	    InterestPoint *interest = new InterestPoint(pose, m_scales[i]);
			interest->setSupport(support);
			interest->setScaleLevel(i);
			point.push_back(interest);
		}
    }
    return point.size();
}
void match(unsigned int position)
{
//     cairo_set_line_cap(cairoOut, CAIRO_LINE_CAP_ROUND);
    
    m_sensorReference.seek(position);
    cairo_matrix_t m1;
    cairo_get_matrix(cairoOut, &m1);
    cairo_identity_matrix(cairoOut);
    cairo_set_source_surface(cairoOut, cairo_get_target(cairoMap), 0., 0.);
    cairo_paint(cairoOut);
    cairo_set_matrix(cairoOut, &m1);
//     cairo_set_line_width(cairoOut, 1./(2.*scaleFactor));
    
    std::vector<InterestPoint *> pointsLocal(m_pointsReference[position].size());
    const LaserReading* lreadReference = dynamic_cast<const LaserReading*>(m_sensorReference.current());
    for(unsigned int j = 0; j < m_pointsReference[position].size(); j++){
	InterestPoint * point = new InterestPoint(*m_pointsReference[position][j]);
	point->setPosition(lreadReference->getLaserPose().ominus(point->getPosition()));
	pointsLocal[j] = point;
    }
    
    
    for(unsigned int i = 0; i < m_pointsReference.size(); i++){
	if(i == position) {
	    continue;
	}
	OrientedPoint2D transform;
	std::vector< std::pair<InterestPoint*, InterestPoint* > > correspondences;
	double result = m_ransac->matchSets(m_pointsReference[i], pointsLocal, transform, correspondences);
	if(correspondences.size() >= corresp) {
	    cairo_matrix_t m;
	    cairo_get_matrix(cairoOut, &m);
	    cairo_translate(cairoOut, transform.x, transform.y);
	    cairo_rotate(cairoOut, transform.theta);
	    
	    cairo_set_source_rgba(cairoOut, 1., 0., 0., 1. - result/(acceptanceSigma * acceptanceSigma * 5.99 * double(pointsLocal.size())));
	    cairo_move_to(cairoOut, 0., -0.3);
	    cairo_line_to(cairoOut, 0.6, 0.);
	    cairo_line_to(cairoOut, 0., 0.3);
	    cairo_close_path(cairoOut);
	    cairo_fill(cairoOut);
	    cairo_set_matrix(cairoOut, &m);
	}
    }
    
    cairo_matrix_t m;
    cairo_get_matrix(cairoOut, &m);
    cairo_translate(cairoOut, lreadReference->getLaserPose().x, lreadReference->getLaserPose().y);
    cairo_rotate(cairoOut, lreadReference->getLaserPose().theta);
    cairo_set_source_rgba(cairoOut, 0., 0., 1., 1.);
    cairo_move_to(cairoOut, 0., -0.3);
    cairo_line_to(cairoOut, 0.6, 0.);
    cairo_line_to(cairoOut, 0., 0.3);
    cairo_close_path(cairoOut);
    cairo_stroke(cairoOut);
    cairo_set_matrix(cairoOut, &m);
//     cairo_show_page(cairoOut);
}
Пример #3
0
InterestPoint::InterestPoint(const InterestPoint& _point):
    m_position(_point.getPosition()),
    m_scale(_point.getScale()),
    m_scaleLevel(_point.getScaleLevel())
{
    if(_point.getDescriptor()) 
	m_descriptor = _point.getDescriptor()->clone();
    else
	m_descriptor = 0;
}
Пример #4
0
InterestPoint* fromRos (const InterestPointRos& m)
{
  OrientedPoint2D pose(m.pose.x, m.pose.y, m.pose.theta);
  Descriptor* descriptor = fromRos(m.descriptor);
  InterestPoint* pt = new InterestPoint(pose, m.scale, descriptor);
  pt->setScaleLevel(m.scale_level);
  vector<Point2D> support_points(m.support_points.size());
  transform(m.support_points.begin(), m.support_points.end(),
            support_points.begin(), toPoint2D);
  pt->setSupport(support_points);
  return pt;
}
Пример #5
0
void writeBoW(std::ofstream& out){
    std::string bar(50, ' ');
    bar[0] = '#';

    unsigned int progress = 0;
    struct timeval start, end;
    gettimeofday(&start, NULL);
    for(unsigned int i = 0; i < m_pointsReference.size(); i++){
	unsigned int currentProgress = (i*100)/(m_pointsReference.size() - 1);
	if (progress < currentProgress){
	    progress = currentProgress;
	    bar[progress/2] = '#';
	    std::cout << "\rDescribing scans  [" << bar << "] " << progress << "%" << std::flush;
	}
	std::multimap<double,WordResult> signature;
	for(unsigned int j = 0; j < m_pointsReference[i].size(); j++){
	    InterestPoint * point = m_pointsReference[i][j];
	    OrientedPoint2D localpose = m_posesReference[i].ominus(point->getPosition());
	    double angle = atan2(localpose.y, localpose.x);
	    unsigned int bestWord = 0;
	    double bestMatch = 0.;
	    std::vector<double> descriptor;
	    std::vector<double> weights;
	    point->getDescriptor()->getWeightedFlatDescription(descriptor, weights);
	    HistogramFeatureWord word(descriptor, NULL, weights);
	    for(unsigned int w = 0; w < histogramVocabulary.size(); w++) {
		double score = histogramVocabulary[w].sim(&word);
		if(score > bestMatch) {
		    bestMatch = score;
		    bestWord = w;
		}
	    }
	    WordResult best; best.pose = localpose; best.word = bestWord;
	    signature.insert(std::make_pair(angle,best));
	}
	out << m_pointsReference[i].size();
	for(std::multimap<double,WordResult>::const_iterator it = signature.begin(); it != signature.end(); it++){
	  out << " " << it->second.word << " " << it->second.pose.x << " " << it->second.pose.y;
	}
	out <<std::endl;
    }
    gettimeofday(&end,NULL);
    timersub(&end,&start,&vocabularyTime);
    std::cout << " done." << std::endl;
}
Пример #6
0
InterestPointRos toRos (const InterestPoint& pt)
{
  InterestPointRos m;

  m.pose.x = pt.getPosition().x;
  m.pose.y = pt.getPosition().y;
  m.pose.theta = pt.getPosition().theta;

  m.support_points.reserve(pt.getSupport().size());
  BOOST_FOREACH (const Point2D& p, pt.getSupport()) 
    m.support_points.push_back(toPoint(p));

  m.scale = pt.getScale();
  m.scale_level = pt.getScaleLevel();
  m.descriptor = toRos(pt.getDescriptor());
  
  return m;
}
Пример #7
0
unsigned int CurvatureDetector::computeInterestPoints(const LaserReading& reading, const std::vector< std::vector<Point2D> >& operatorA, std::vector<InterestPoint*>& point, 
						      const std::vector< std::vector<unsigned int> >& indexes, std::vector<unsigned int>& maxRangeMapping) const
{
    point.clear();
    point.reserve(reading.getRho().size());
    const std::vector<Point2D>& worldPoints = reading.getWorldCartesian();
    for(unsigned int i = 0; i < indexes.size(); i++){
		for(unsigned int j = 0; j < indexes[i].size(); j++){
			OrientedPoint2D pose;
			unsigned int pointIndex = maxRangeMapping[indexes[i][j]];
			
			// Reomoving the detection in the background and pushing it to the foreground
			double rangeBefore = (pointIndex > 1)? reading.getRho()[pointIndex - 1] : reading.getMaxRange();
			double rangeAfter = (pointIndex < worldPoints.size() - 1)? reading.getRho()[pointIndex + 1] : reading.getMaxRange();
			double rangeCurrent = reading.getRho()[pointIndex];
			if(rangeBefore < rangeAfter){
				if(rangeBefore < rangeCurrent){
					pointIndex = pointIndex - 1;
				}
			} else if(rangeAfter < rangeCurrent){
				pointIndex = pointIndex + 1;
			}
			
			// Removing max range reading
			if(reading.getRho()[pointIndex] >= reading.getMaxRange()){
				continue;
			}

			
			pose.x =  (worldPoints[pointIndex]).x;
			pose.y =  (worldPoints[pointIndex]).y;
			Point2D difference = operatorA[i][indexes[i][j]] - worldPoints[pointIndex];
			pose.theta = atan2(difference.y, difference.x);
			
			bool exists = false;
			for(unsigned int k = 0; !exists && k < point.size(); k++){
				exists = exists || (fabs(pose.x - point[k]->getPosition().x) <= 0.2 &&  fabs(pose.y - point[k]->getPosition().y) <= 0.2);
			}
			if(exists) continue;

			double distance = 2. * m_scales[i];
			Point2D diffStart = pose - worldPoints.front();
			Point2D diffEnd = pose - worldPoints.back();
			
			if(hypot(diffStart.x, diffStart.y) < distance || hypot(diffEnd.x, diffEnd.y) < distance){
				continue;
			}
			
			std::vector<Point2D> support;
			for(unsigned int k = 0; k < worldPoints.size(); k++){
				Point2D diff2 = pose - worldPoints[k];
				if(hypot(diff2.x, diff2.y) < distance) support.push_back(worldPoints[k]);
			}

	    LineParameters param = computeNormals(support);
	    pose.theta = normAngle(param.alpha, - M_PI);    
	    
			InterestPoint *interest = new InterestPoint(pose, distance);
		//  InterestPoint *interest = new InterestPoint(pose, m_scales[i]);
			interest->setSupport(support);
			interest->setScaleLevel(i);
			point.push_back(interest);
		}
    }
    return point.size();
    
}
vector<InterestPoint> InterestPointsDetector::calculateOrientations(
        const vector<InterestPoint>& points) {
    Kernel gaussKernel = Kernel::createGaussKernelByRadius(radiusOfNeighborhood);

    vector<InterestPoint> result = vector<InterestPoint>();
    foreach (InterestPoint point, points) {
        float rBaskets[ROTATION_INV_BASKET_COUNT] = {0.f};
        //заполнить корзины
        for (int dx = -radiusOfNeighborhood; dx <= radiusOfNeighborhood; ++dx) {
            for (int dy = -radiusOfNeighborhood; dy <= radiusOfNeighborhood; ++dy) {
                int x1 = ImageUtil::handleEdgeEffect(dx + point.x + 1, source.getWidth(), type);
                int x2 = ImageUtil::handleEdgeEffect(dx + point.x - 1, source.getWidth(), type);
                int y1 = ImageUtil::handleEdgeEffect(dy + point.y + 1, source.getHeight(), type);
                int y2 = ImageUtil::handleEdgeEffect(dy + point.y - 1, source.getHeight(), type);
                int x0 = ImageUtil::handleEdgeEffect(dx + point.x, source.getWidth(), type);
                int y0 = ImageUtil::handleEdgeEffect(dy + point.y, source.getHeight(), type);
                if(ImageUtil::insideImage(x1, y0)
                        && ImageUtil::insideImage(x2, y0)
                        && ImageUtil::insideImage(x0, y1)
                        && ImageUtil::insideImage(x0, y2)){

                    float lx1y0 = source.getValue(x1, y0);
                    float lx2y0 = source.getValue(x2, y0);

                    float lx0y1 = source.getValue(x0, y1);
                    float lx0y2 = source.getValue(x0, y2);

                    float dlx = lx1y0 - lx2y0;
                    float dly = lx0y1 - lx0y2;
                    float gradientLength = sqrtf(dlx * dlx + dly * dly);
                    float angle = atan2(dly, dlx) + M_PI;
                    gradientLength *= gaussKernel.getValue(dx, dy);

                    //узнать номер текущей козины
                    int basketNumber = (int)(angle / R_DPHI);
                    float mod = angle - basketNumber * R_DPHI;

                    //узнать номер соседней корзины
                    int basketNumberNei = calculateNumberOfNeighbornBasket(
                                              R_HALF_DPHI, mod,
                                              basketNumber, ROTATION_INV_BASKET_COUNT);
                    //узнать расстояние до центра текущей корзины
                    float centerOfBasket = basketNumber * R_DPHI + R_HALF_DPHI;
                    float distanceToCenter = fabs(angle - fabs(centerOfBasket));
                    float distanceToCenterNei = R_DPHI - distanceToCenter;
                    float ratio = 1. - distanceToCenter / R_DPHI;
                    float ratioNei = 1. - distanceToCenterNei / R_DPHI;
                    rBaskets[basketNumber] += gradientLength * ratio;
                    rBaskets[basketNumberNei] += gradientLength * ratioNei;
                }

            }
        }
        //найти пики
        int peakIndex = 0;
        float peakValue = rBaskets[peakIndex];
        for (int i = 1; i < ROTATION_INV_BASKET_COUNT; ++i) {
            if (rBaskets[i] > peakValue) {
                peakValue = rBaskets[i];
                peakIndex = i;
            }
        }
        int xL, xR;
        if (peakIndex == 0){
            xL = ROTATION_INV_BASKET_COUNT - 1;
        } else {
            xL = peakIndex - 1;
        }
        if (peakIndex == ROTATION_INV_BASKET_COUNT - 1){
            xR = 0;
        } else {
            xR = peakIndex + 1;
        }
        double angleOfPeak = maxInterp3f(rBaskets[xL], peakValue, rBaskets[xR]);
        point.setOrientation(angleOfPeak);
        result.push_back(point);

        int subPeakIndex = -1;
        float subPeakValue = 0.8 * peakValue;
        for (int i = 0; i < ROTATION_INV_BASKET_COUNT; ++i) {
            if (peakIndex != i && rBaskets[i] > subPeakValue) {
                subPeakValue = rBaskets[i];
                subPeakIndex = i;
            }
        }
        if (subPeakIndex != -1) {
            if (subPeakIndex == 0){
                xL = ROTATION_INV_BASKET_COUNT - 1;
            } else {
                xL = subPeakIndex - 1;
            }
            if (subPeakIndex == ROTATION_INV_BASKET_COUNT - 1){
                xR = 0;
            } else {
                xR = subPeakIndex + 1;
            }
            double angleOfSubPeak = maxInterp3f(
                                        rBaskets[xL], subPeakValue, rBaskets[xR]);
            InterestPoint copy = InterestPoint(point.x, point.y, point.value);
            copy.setOrientation(angleOfSubPeak);
            result.push_back(copy);
        }
    }
void match(unsigned int position)
{
    m_sensorReference.seek(position);
    
    std::vector<InterestPoint *> pointsLocal(m_pointsReference[position].size());
    const LaserReading* lreadReference = dynamic_cast<const LaserReading*>(m_sensorReference.current());
    for(unsigned int j = 0; j < m_pointsReference[position].size(); j++){
	InterestPoint * point = new InterestPoint(*m_pointsReference[position][j]);
	point->setPosition(lreadReference->getLaserPose().ominus(point->getPosition()));
	pointsLocal[j] = point;
    }
       
    unsigned int inliers[m_pointsReference.size()];
    double results[m_pointsReference.size()];
    double linearErrors[m_pointsReference.size()];
    double angularErrors[m_pointsReference.size()];
    struct timeval start, end, diff, sum;
    for(unsigned int i = 0; i < m_pointsReference.size(); i++){
	if(fabs(double(i) - double(position)) < m_localSkip) {
	    results[i] = 1e17;
	    inliers[i] = 0;
	    linearErrors[i] = 1e17;
	    angularErrors[i] = 1e17;
	    continue;
	}
	OrientedPoint2D transform;
	std::vector< std::pair<InterestPoint*, InterestPoint* > > correspondences;
	gettimeofday(&start,NULL);
// 	std::cout << m_pointsReference[i].size() << " vs. " << pointsLocal.size() << std::endl;
	results[i] = m_ransac->matchSets(m_pointsReference[i], pointsLocal, transform, correspondences);
	gettimeofday(&end,NULL);
	timersub(&end, &start, &diff);
	timeradd(&ransacTime, &diff, &sum);
	ransacTime = sum;
	inliers[i] = correspondences.size();
	OrientedPoint2D delta = m_posesReference[position] - transform; 
	linearErrors[i] = correspondences.size() ? delta * delta : 1e17;
	angularErrors[i] = correspondences.size() ? delta.theta * delta.theta : 1e17;
    }
    
    for(unsigned int c = 0; c < 8; c++){
	unsigned int maxCorres = 0;
	double maxResult = 1e17;
	double linError = 1e17, angError = 1e17;
	double linErrorC = 1e17, angErrorC = 1e17;
	double linErrorR = 1e17, angErrorR = 1e17;
	bool valid = false;
        for(unsigned int i = 0; i < m_pointsReference.size(); i++){
	    if(linError + angError > linearErrors[i] + angularErrors[i]) {
		linError = linearErrors[i];
		angError = angularErrors[i];
	    }
	    if(maxCorres < inliers[i]){
		linErrorC = linearErrors[i];
		angErrorC = angularErrors[i];
		maxCorres = inliers[i];
	    }
	    if(maxResult > results[i]){
		linErrorR = linearErrors[i];
		angErrorR = angularErrors[i];
		maxResult = results[i];
	    }
	    valid = valid || inliers[i] >= corresp[c];
	}
	
	
	if(valid){
	    m_match[c] += (linError <= (linErrorTh * linErrorTh) && angError <= (angErrorTh * angErrorTh) );
	    m_matchC[c] += (linErrorC <= (linErrorTh * linErrorTh) && angErrorC <= (angErrorTh * angErrorTh) );
	    m_matchR[c] += (linErrorR <= (linErrorTh * linErrorTh) && angErrorR <= (angErrorTh * angErrorTh) );
	    
	    m_error[c] += sqrt(linError + angError);
	    m_errorC[c] += sqrt(linErrorC + angErrorC);
	    m_errorR[c] += sqrt(linErrorR + angErrorR);
	    
	    m_valid[c]++;
	}
    }

}