Point LineSegment::intersection(LineSegment line) { float c1, c2; float intersection_X = -1, intersection_Y= -1; c1 = p1.y - slope * p1.x; // which is same as y2 - slope * x2 c2 = line.p2.y - line.slope * line.p2.x; // which is same as y2 - slope * x2 if( (slope - line.slope) == 0) { //std::cout << "No Intersection between the lines" << endl; } else if (p1.x == p2.x) { // Line1 is vertical return Point(p1.x, line.getPointAt(p1.x)); } else if (line.p1.x == line.p2.x) { // Line2 is vertical return Point(line.p1.x, getPointAt(line.p1.x)); } else { intersection_X = (c2 - c1) / (slope - line.slope); intersection_Y = slope * intersection_X + c1; } return Point(intersection_X, intersection_Y); }
vector<Point> CharacterAnalysis::getCharArea(LineSegment topLine, LineSegment bottomLine) { const int MAX = 100000; const int MIN= -1; int leftX = MAX; int rightX = MIN; for (uint i = 0; i < bestContours.size(); i++) { if (bestContours.goodIndices[i] == false) continue; for (uint z = 0; z < bestContours.contours[i].size(); z++) { if (bestContours.contours[i][z].x < leftX) leftX = bestContours.contours[i][z].x; if (bestContours.contours[i][z].x > rightX) rightX = bestContours.contours[i][z].x; } } vector<Point> charArea; if (leftX != MAX && rightX != MIN) { Point tl(leftX, topLine.getPointAt(leftX)); Point tr(rightX, topLine.getPointAt(rightX)); Point br(rightX, bottomLine.getPointAt(rightX)); Point bl(leftX, bottomLine.getPointAt(leftX)); charArea.push_back(tl); charArea.push_back(tr); charArea.push_back(br); charArea.push_back(bl); } return charArea; }
using namespace std; using namespace cv; using namespace alpr; TEST_CASE( "LineSegment Test", "[2d primitives]" ) { // Test a flat horizontal line LineSegment flat_horizontal(1,1, 21,1); REQUIRE( flat_horizontal.angle == 0 ); REQUIRE( flat_horizontal.slope == 0 ); REQUIRE( flat_horizontal.length == 20 ); REQUIRE( flat_horizontal.midpoint().y == 1 ); REQUIRE( flat_horizontal.midpoint().x == 11 ); REQUIRE( flat_horizontal.getPointAt(11) == 1 ); // Test distance between points calculation REQUIRE( distanceBetweenPoints(Point(10,10), Point(20,20)) == Approx(14.1421) ); REQUIRE( distanceBetweenPoints(Point(-5,10), Point(20,-12)) == Approx(33.3017) ); int testarray1[] = {1, 2, 3, 3, 4, 5 }; int testarray2[] = {0, 2, -3, 3, -4, 5 }; int *testarray3; REQUIRE( median(testarray1, 6) == 3 ); REQUIRE( median(testarray2, 6) == 1 ); REQUIRE( median(testarray3, 0) == 0 ); } TEST_CASE( "Test Levenshtein Distance", "[levenshtein]" ) {
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; }