示例#1
0
vector<PlateLine> PlateLines::getLines(Mat edges, float sensitivityMultiplier, bool vertical)
{
  if (this->debug)
    cout << "PlateLines::getLines" << endl;

  static int HORIZONTAL_SENSITIVITY = pipelineData->config->plateLinesSensitivityHorizontal;
  static int VERTICAL_SENSITIVITY = pipelineData->config->plateLinesSensitivityVertical;

  vector<Vec2f> allLines;
  vector<PlateLine> filteredLines;

  int sensitivity;
  if (vertical)
    sensitivity = VERTICAL_SENSITIVITY * (1.0 / sensitivityMultiplier);
  else
    sensitivity = HORIZONTAL_SENSITIVITY * (1.0 / sensitivityMultiplier);

  HoughLines( edges, allLines, 1, CV_PI/180, sensitivity, 0, 0 );

  for( size_t i = 0; i < allLines.size(); i++ )
  {
    float rho = allLines[i][0], theta = allLines[i][1];
    Point pt1, pt2;
    double a = cos(theta), b = sin(theta);
    double x0 = a*rho, y0 = b*rho;

    double angle = theta * (180 / CV_PI);
    pt1.x = cvRound(x0 + 1000*(-b));
    pt1.y = cvRound(y0 + 1000*(a));
    pt2.x = cvRound(x0 - 1000*(-b));
    pt2.y = cvRound(y0 - 1000*(a));

    if (vertical)
    {
      if (angle < 20 || angle > 340 || (angle > 160 && angle < 210))
      {
        // good vertical

        LineSegment line;
        if (pt1.y <= pt2.y)
          line = LineSegment(pt2.x, pt2.y, pt1.x, pt1.y);
        else
          line = LineSegment(pt1.x, pt1.y, pt2.x, pt2.y);

        // Get rid of the -1000, 1000 stuff.  Terminate at the edges of the image
        // Helps with debugging/rounding issues later
        LineSegment top(0, 0, edges.cols, 0);
        LineSegment bottom(0, edges.rows, edges.cols, edges.rows);
        Point p1 = line.intersection(bottom);
        Point p2 = line.intersection(top);

	PlateLine plateLine;
	plateLine.line = LineSegment(p1.x, p1.y, p2.x, p2.y);
	plateLine.confidence = (1.0 - MIN_CONFIDENCE) * ((float) (allLines.size() - i)) / ((float)allLines.size()) + MIN_CONFIDENCE;
        filteredLines.push_back(plateLine);
      }
    }
    else
    {
      if ( (angle > 70 && angle < 110) || (angle > 250 && angle < 290))
      {
        // good horizontal

        LineSegment line;
        if (pt1.x <= pt2.x)
          line = LineSegment(pt1.x, pt1.y, pt2.x, pt2.y);
        else
          line =LineSegment(pt2.x, pt2.y, pt1.x, pt1.y);

        // Get rid of the -1000, 1000 stuff.  Terminate at the edges of the image
        // Helps with debugging/ rounding issues later
        int newY1 = line.getPointAt(0);
        int newY2 = line.getPointAt(edges.cols);

	PlateLine plateLine;
	plateLine.line = LineSegment(0, newY1, edges.cols, newY2);
	plateLine.confidence = (1.0 - MIN_CONFIDENCE) * ((float) (allLines.size() - i)) / ((float)allLines.size()) + MIN_CONFIDENCE;
        filteredLines.push_back(plateLine);
      }
    }
  }

  return filteredLines;
}
示例#2
0
		Vector<2, NumericT> normal(const LineSegment<2, NumericT> & line_segment)
		{
			return normal(line_segment.direction());
		}
std::vector<LineSegment> EdgelDetector::findLineSegment(std::vector<Edgel> edgels) {
	std::vector<LineSegment> lineSegments;
	LineSegment lineSegmentInRun;

	srand(time(NULL));


	do {
		lineSegmentInRun.supportEdgels.clear();

		for (int i = 0; i < 25; i++) {	
			Edgel r1;
			Edgel r2;

			const int max_iterations = 100;
			int iteration = 0, ir1, ir2;

			//pak 2 random edgels welke compatible zijn met elkaar.
			do {
				ir1 = (rand()%(edgels.size()));
				ir2 = (rand()%(edgels.size()));

				r1 = edgels.at(ir1);
				r2 = edgels.at(ir2);
				iteration++;
			} while ( ( ir1 == ir2 || !r1.isOrientationCompatible( r2 ) ) && iteration < max_iterations );

			if( iteration < max_iterations ) {
			// 2 edgels gevonden!
				LineSegment lineSegment;
				lineSegment.start = r1;
				lineSegment.end = r2;
				lineSegment.slope = r1.slope;			
				
				//check welke edgels op dezelfde line liggen en voeg deze toe als support
				for (unsigned int o = 0; o < edgels.size(); o++) {
					if ( lineSegment.atLine( edgels.at(o) ) ) {
						lineSegment.addSupport( edgels.at(o) );
					}
				}

				if( lineSegment.supportEdgels.size() > lineSegmentInRun.supportEdgels.size() ) {
					lineSegmentInRun = lineSegment;
				}
			}
		}
		
		// slope van de line bepalen
		if( lineSegmentInRun.supportEdgels.size() >= EDGELSONLINE ) {
			float u1 = 0;
			float u2 = 50000;
			const Vector2f slope = (lineSegmentInRun.start.position - lineSegmentInRun.end.position);
			const Vector2f orientation = Vector2f( -lineSegmentInRun.start.slope.y, lineSegmentInRun.start.slope.x );
			
			if (abs (slope.x) <= abs(slope.y)) {				
				for (std::vector<Edgel>::iterator it = lineSegmentInRun.supportEdgels.begin(); it!=lineSegmentInRun.supportEdgels.end(); ++it) {

					if ((*it).position.y > u1) {
						u1 = (*it).position.y;
						lineSegmentInRun.start = (*it);
					}

					if ((*it).position.y < u2) {
						u2 = (*it).position.y;
						lineSegmentInRun.end = (*it);
					}
				}
			} else {
				for (std::vector<Edgel>::iterator it = lineSegmentInRun.supportEdgels.begin(); it!=lineSegmentInRun.supportEdgels.end(); ++it) {

					if ((*it).position.x > u1) {
						u1 = (*it).position.x;
						lineSegmentInRun.start = (*it);
					}

					if ((*it).position.x < u2) {
						u2 = (*it).position.x;
						lineSegmentInRun.end = (*it);
					}
				}
			}
			
			// switch startpoint and endpoint according to orientation of edge
			
			if( dot( lineSegmentInRun.end.position - lineSegmentInRun.start.position, orientation ) < 0.0f ) {
				std::swap( lineSegmentInRun.start, lineSegmentInRun.end );
			}
			
			
			lineSegmentInRun.slope = (lineSegmentInRun.end.position - lineSegmentInRun.start.position).get_normalized();

			// heeft de lineSegmentInRun voldoende dan toevoegen aan lineSegments,
			// gebruikte edgels verwijderen..

			lineSegments.push_back( lineSegmentInRun );

			//TODO: Dit moet sneller!
			for(unsigned int i=0; i<lineSegmentInRun.supportEdgels.size(); i++) {
				for (std::vector<Edgel>::iterator it = edgels.begin(); it!=edgels.end(); ++it) {
					if( (*it).position.x == lineSegmentInRun.supportEdgels.at(i).position.x &&
						(*it).position.y == lineSegmentInRun.supportEdgels.at(i).position.y ) {
						edgels.erase( it );   
						break;
					}
				}
			}
		}

	} while( lineSegmentInRun.supportEdgels.size() >= EDGELSONLINE && edgels.size() >= EDGELSONLINE );
	
	return lineSegments;
}
示例#4
0
template<UnsignedInt dimensions> bool Sphere<dimensions>::operator%(const LineSegment<dimensions>& other) const {
    return Distance::lineSegmentPointSquared(other.a(), other.b(), _position) < Math::pow<2>(_radius);
}
 bool LL_SHARED intersection_of_lines_in_two_dimensions(LineSegment first_line,LineSegment second_line,
                                                        float* x,float* y)
 {
     if(first_line.get_dimension()!=second_line.get_dimension() or first_line.get_dimension()!=2)
         return false;
     if((first_line.get_ini_point()==first_line.get_end_point())
        or (second_line.get_ini_point()==second_line.get_end_point()))
         return false;
     if(((first_line.get_end_point()[0]-first_line.get_ini_point()[0])
             *(second_line.get_end_point()[1]-second_line.get_ini_point()[1]))
        !=((first_line.get_end_point()[1]-first_line.get_ini_point()[1])
             *(second_line.get_end_point()[0]-second_line.get_ini_point()[0])))
     {
         float intersection_point_x,intersection_point_y;
         if(first_line.get_end_point()[0]==first_line.get_ini_point()[0])
         {
             float m2=((second_line.get_end_point()[1]-second_line.get_ini_point()[1])/
                       (second_line.get_end_point()[0]-second_line.get_ini_point()[0]));
             float b2=second_line.get_ini_point()[1]-m2*second_line.get_ini_point()[0];
             intersection_point_x=first_line.get_ini_point()[0];
             intersection_point_y=m2*intersection_point_x+b2;
         }
         else if(second_line.get_end_point()[0]==second_line.get_ini_point()[0])
         {
             float m1=((first_line.get_end_point()[1]-first_line.get_ini_point()[1])/
                       (first_line.get_end_point()[0]-first_line.get_ini_point()[0]));
             float b1=first_line.get_ini_point()[1]-m1*first_line.get_ini_point()[0];
             intersection_point_x=second_line.get_ini_point()[0];
             intersection_point_y=m1*intersection_point_x+b1;
         }
         else
         {
             float m1=((first_line.get_end_point()[1]-first_line.get_ini_point()[1])/
                       (first_line.get_end_point()[0]-first_line.get_ini_point()[0]));
             float b1=first_line.get_ini_point()[1]-m1*first_line.get_ini_point()[0];
             float m2=((second_line.get_end_point()[1]-second_line.get_ini_point()[1])/
                       (second_line.get_end_point()[0]-second_line.get_ini_point()[0]));
             float b2=second_line.get_ini_point()[1]-m2*second_line.get_ini_point()[0];
             intersection_point_x=(b2-b1)/(m1-m2);
             intersection_point_y=m1*intersection_point_x+b1;
         }
         if(x and y)
         {
             *x=intersection_point_x;
             *y=intersection_point_y;
         }
         return true;
     }
     return false;
 }
示例#6
0
Ray::Ray(const LineSegment &lineSegment)
:pos(lineSegment.a), dir(lineSegment.Dir())
{
}
示例#7
0
  std::vector<cv::Point2f> EdgeFinder::findEdgeCorners() {

    TextLineCollection tlc(pipeline_data->textLines);

    vector<Point> corners;

    // If the character segment is especially small, just expand the existing box
    // If it's a nice, long segment, then guess the correct box based on character height/position
    if (tlc.longerSegment.length > tlc.charHeight * 3)
    {

      float charHeightToPlateWidthRatio = pipeline_data->config->plateWidthMM / pipeline_data->config->avgCharHeightMM;
      float idealPixelWidth = tlc.charHeight *  (charHeightToPlateWidthRatio * 1.03);	// Add 3% so we don't clip any characters

      float charHeightToPlateHeightRatio = pipeline_data->config->plateHeightMM / pipeline_data->config->avgCharHeightMM;
      float idealPixelHeight = tlc.charHeight *  charHeightToPlateHeightRatio;


      float verticalOffset = (idealPixelHeight * 1.5 / 2);
      float horizontalOffset = (idealPixelWidth * 1.25 / 2);
      LineSegment topLine = tlc.centerHorizontalLine.getParallelLine(verticalOffset);
      LineSegment bottomLine = tlc.centerHorizontalLine.getParallelLine(-1 * verticalOffset);

      LineSegment leftLine = tlc.centerVerticalLine.getParallelLine(-1 * horizontalOffset);
      LineSegment rightLine = tlc.centerVerticalLine.getParallelLine(horizontalOffset);

      Point topLeft = topLine.intersection(leftLine);
      Point topRight = topLine.intersection(rightLine);
      Point botRight = bottomLine.intersection(rightLine);
      Point botLeft = bottomLine.intersection(leftLine);

      corners.push_back(topLeft);
      corners.push_back(topRight);
      corners.push_back(botRight);
      corners.push_back(botLeft);
    }
    else
    {

      int expandX = (int) ((float) pipeline_data->crop_gray.cols) * 0.15f;
      int expandY = (int) ((float) pipeline_data->crop_gray.rows) * 0.15f;
      int w = pipeline_data->crop_gray.cols;
      int h = pipeline_data->crop_gray.rows;

      corners.push_back(Point(-1 * expandX, -1 * expandY));
      corners.push_back(Point(expandX + w, -1 * expandY));
      corners.push_back(Point(expandX + w, expandY + h));
      corners.push_back(Point(-1 * expandX, expandY + h));

  //    for (int i = 0; i < 4; i++)
  //    {
  //      std::cout << "CORNER: " << corners[i].x << " - " << corners[i].y << std::endl;
  //    }
    }

    // Re-crop an image (from the original image) using the new coordinates
    Transformation imgTransform(pipeline_data->grayImg, pipeline_data->crop_gray, pipeline_data->regionOfInterest);
    vector<Point2f> remappedCorners = imgTransform.transformSmallPointsToBigImage(corners);

    Size cropSize = imgTransform.getCropSize(remappedCorners, 
            Size(pipeline_data->config->templateWidthPx, pipeline_data->config->templateHeightPx));

    Mat transmtx = imgTransform.getTransformationMatrix(remappedCorners, cropSize);
    Mat newCrop = imgTransform.crop(cropSize, transmtx);

    // Re-map the textline coordinates to the new crop  
    vector<TextLine> newLines;
    for (unsigned int i = 0; i < pipeline_data->textLines.size(); i++)
    {        
      vector<Point2f> textArea = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].textArea);
      vector<Point2f> linePolygon = imgTransform.transformSmallPointsToBigImage(pipeline_data->textLines[i].linePolygon);

      vector<Point2f> textAreaRemapped;
      vector<Point2f> linePolygonRemapped;

      textAreaRemapped = imgTransform.remapSmallPointstoCrop(textArea, transmtx);
      linePolygonRemapped = imgTransform.remapSmallPointstoCrop(linePolygon, transmtx);

      newLines.push_back(TextLine(textAreaRemapped, linePolygonRemapped, newCrop.size()));
    }

    // Find the PlateLines for this crop
    PlateLines plateLines(pipeline_data);
    plateLines.processImage(newCrop, newLines, 1.05);

    // Get the best corners
    PlateCorners cornerFinder(newCrop, &plateLines, pipeline_data, newLines);
    vector<Point> smallPlateCorners = cornerFinder.findPlateCorners();


    // Transform the best corner points back to the original image
    std::vector<Point2f> imgArea;
    imgArea.push_back(Point2f(0, 0));
    imgArea.push_back(Point2f(newCrop.cols, 0));
    imgArea.push_back(Point2f(newCrop.cols, newCrop.rows));
    imgArea.push_back(Point2f(0, newCrop.rows));
    Mat newCropTransmtx = imgTransform.getTransformationMatrix(imgArea, remappedCorners);

    vector<Point2f> cornersInOriginalImg = imgTransform.remapSmallPointstoCrop(smallPlateCorners, newCropTransmtx);

    return cornersInOriginalImg;

  }
示例#8
0
/* NOTE: this is called findSegmentIndexToSnap in JTS */
CoordinateList::iterator
LineStringSnapper::findSegmentToSnap(
    const Coordinate& snapPt,
    CoordinateList::iterator from,
    CoordinateList::iterator too_far)
{
    LineSegment seg;
    double minDist = snapTolerance; // make sure the first closer then
    // snapTolerance is accepted
    CoordinateList::iterator match = too_far;

    // TODO: use std::find_if
    for(; from != too_far; ++from) {
        seg.p0 = *from;
        CoordinateList::iterator to = from;
        ++to;
        seg.p1 = *to;

#if GEOS_DEBUG
        cerr << " Checking segment " << seg << endl;
#endif

        /**
         * Check if the snap pt is equal to one of
         * the segment endpoints.
         *
         * If the snap pt is already in the src list,
         * don't snap at all (unless allowSnappingToSourceVertices
         * is set to true)
         */
        if(seg.p0.equals2D(snapPt) || seg.p1.equals2D(snapPt)) {

            if(allowSnappingToSourceVertices) {
#if GEOS_DEBUG
                cerr << "   snap point matches a segment endpoint, checking next segment"
                     << endl;
#endif
                continue;
            }
            else {
#if GEOS_DEBUG
                cerr << "   snap point matches a segment endpoint, giving up seek" << endl;
#endif
                return too_far;
            }
        }

        double dist = seg.distance(snapPt);
        if(dist >= minDist) {
#if GEOS_DEBUG
            cerr << "   snap point distance " << dist
                 << " not smaller than tolerance "
                 << snapTolerance << " or previous closest "
                 << minDist << endl;
#endif
            continue;
        }

#if GEOS_DEBUG
        cerr << "   snap point distance " << dist << " within tolerance "
             << snapTolerance << " and closer than previous candidate "
             << minDist << endl;
#endif

        if(dist == 0.0) {
            return from;    // can't find any closer
        }

        match = from;
        minDist = dist;

    }

    return match;
}
示例#9
0
float3 Ray::ClosestPoint(const LineSegment &other, float *d, float *d2) const
{
	float u, u2;
	float3 closestPoint = Line::ClosestPointLineLine(pos, pos + dir, other.a, other.b, &u, &u2);
	if (u < 0.f)
	{
		if (u2 >= 0.f && u2 <= 1.f)
		{
			if (d)
				*d = 0.f;
			if (d2)
				other.ClosestPoint(pos, d2);
			return pos;
		}

		float3 p;
		float t2;

		if (u2 < 0.f)
		{
			p = other.a;
			t2 = 0.f;
		}
		else // u2 > 1.f
		{
			p = other.b;
			t2 = 1.f;
		}

		closestPoint = ClosestPoint(p, &u);
		float3 closestPoint2 = other.ClosestPoint(pos, &u2);
		if (closestPoint.DistanceSq(p) <= closestPoint2.DistanceSq(pos))
		{
			if (d)
				*d = u;
			if (d2)
				*d2 = t2;
			return closestPoint;
		}
		else
		{
			if (d)
				*d = 0.f;
			if (d2)
				*d2 = u2;
			return pos;
		}
	}
	else if (u2 < 0.f)
	{
		closestPoint = ClosestPoint(other.a, d);
		if (d2)
			*d2 = 0.f;
		return closestPoint;
	}
	else if (u2 > 1.f)
	{
		closestPoint = ClosestPoint(other.b, d);
		if (d2)
			*d2 = 1.f;
		return closestPoint;
	}
	else
	{
		if (d)
			*d = u;
		if (d2)
			*d2 = u2;
		return closestPoint;
	}
}
示例#10
0
Option<Vec2> Intersection::get(const LineSegment& a, const LineSegment& b) {
	auto Intersection = get(a.containingLine(), b.containingLine());
	if (!Intersection)
		return nullptr;
	if (aeq(Intersection.value(), a.pointA()))
		Intersection = a.pointA();
	if (aeq(Intersection.value(), a.pointB()))
		Intersection = a.pointB();
	if (aeq(Intersection.value(), b.pointA()))
		Intersection = b.pointA();
	if (aeq(Intersection.value(), b.pointB()))
		Intersection = b.pointB();

	auto dirA = a.pointB() - a.pointA();
	const auto dirALen = dirA.length();
	dirA /= dirALen;
	auto dirB = b.pointB() - b.pointA();
	const auto dirBLen = dirB.length();
	dirB /= dirBLen;
	const auto t = dot(Intersection.value() - a.pointA(), dirA);
	const auto u = dot(Intersection.value() - b.pointA(), dirB);
	if (t >= 0 && u >= 0 && t <= dirALen && u <= dirBLen)
		return Intersection;
	else
		return nullptr;
}
示例#11
0
bool Intersection::test(const LineSegment& a, const Vec2& b) {
	return a.containsPoint(b, true);
}
示例#12
0
	inline double getUpdateCoef(double coef, LineSegment line)
	{
		return getUpdateCoef(coef,
				line.GetClosestPointOnLineSegment(cv::Point2d(0, 0)))
				* line.getProbability();
	}
示例#13
0
 inline double length(const LineSegment& s)
 {
   return (s.p2()-s.p1()).norm();
 }
示例#14
0
 inline double squared_length(const LineSegment& s)
 {
   return (s.p2()-s.p1()).squaredNorm();
 }
示例#15
0
 inline Vector2d dir(const LineSegment& s)
 {
   return s.p2() - s.p1();
 }
示例#16
0
Line::Line(const LineSegment &lineSegment)
:pos(lineSegment.a), dir(lineSegment.Dir())
{
}