From 42b6ff0774a85f315dc45b3de55fdc5f3efa8490 Mon Sep 17 00:00:00 2001 From: Matt Hill Date: Sat, 25 Oct 2014 16:13:53 -0400 Subject: [PATCH] Added TextLineCollection to its own class file --- src/openalpr/CMakeLists.txt | 1 + src/openalpr/edges/platecorners.cpp | 147 +------------------- src/openalpr/edges/platecorners.h | 32 +---- src/openalpr/edges/textlinecollection.cpp | 160 ++++++++++++++++++++++ src/openalpr/edges/textlinecollection.h | 48 +++++++ 5 files changed, 211 insertions(+), 177 deletions(-) create mode 100644 src/openalpr/edges/textlinecollection.cpp create mode 100644 src/openalpr/edges/textlinecollection.h diff --git a/src/openalpr/CMakeLists.txt b/src/openalpr/CMakeLists.txt index 1ded621..91071cf 100644 --- a/src/openalpr/CMakeLists.txt +++ b/src/openalpr/CMakeLists.txt @@ -19,6 +19,7 @@ set(lpr_source_files segmentation/verticalhistogram.cpp edges/platecorners.cpp edges/platelines.cpp + edges/textlinecollection.cpp colorfilter.cpp textdetection/characteranalysis.cpp textdetection/platemask.cpp diff --git a/src/openalpr/edges/platecorners.cpp b/src/openalpr/edges/platecorners.cpp index 52e0e7c..3e9514f 100644 --- a/src/openalpr/edges/platecorners.cpp +++ b/src/openalpr/edges/platecorners.cpp @@ -23,7 +23,7 @@ using namespace cv; using namespace std; PlateCorners::PlateCorners(Mat inputImage, PlateLines* plateLines, PipelineData* pipelineData) : - tlc(pipelineData) + tlc(pipelineData->textLines) { this->pipelineData = pipelineData; @@ -438,151 +438,6 @@ void PlateCorners::scoreHorizontals(int h1, int h2) } } -TextLineCollection::TextLineCollection(PipelineData* pipelineData) { - - this->pipelineData = pipelineData; - - charHeight = 0; - charAngle = 0; - for (uint i = 0; i < pipelineData->textLines.size(); i++) - { - charHeight += pipelineData->textLines[i].lineHeight; - charAngle += pipelineData->textLines[i].angle; - - } - charHeight = charHeight / pipelineData->textLines.size(); - charAngle = charAngle / pipelineData->textLines.size(); - - this->topCharArea = pipelineData->textLines[0].charBoxTop; - this->bottomCharArea = pipelineData->textLines[0].charBoxBottom; - for (uint i = 1; i < pipelineData->textLines.size(); i++) - { - - if (this->topCharArea.isPointBelowLine(pipelineData->textLines[i].charBoxTop.midpoint()) == false) - this->topCharArea = pipelineData->textLines[i].charBoxTop; - - if (this->bottomCharArea.isPointBelowLine(pipelineData->textLines[i].charBoxBottom.midpoint())) - this->bottomCharArea = pipelineData->textLines[i].charBoxBottom; - - } - - longerSegment = this->bottomCharArea; - shorterSegment = this->topCharArea; - if (this->topCharArea.length > this->bottomCharArea.length) - { - longerSegment = this->topCharArea; - shorterSegment = this->bottomCharArea; - } - - findCenterHorizontal(); - findCenterVertical(); - // Center Vertical Line - - if (pipelineData->config->debugPlateCorners) - { - Mat debugImage = Mat::zeros(pipelineData->crop_gray.size(), CV_8U); - line(debugImage, this->centerHorizontalLine.p1, this->centerHorizontalLine.p2, Scalar(255,255,255), 2); - line(debugImage, this->centerVerticalLine.p1, this->centerVerticalLine.p2, Scalar(255,255,255), 2); - - displayImage(pipelineData->config, "Plate Corner Center lines", debugImage); - } -} - -// Returns 1 for above, 0 for within, and -1 for below -int TextLineCollection::isAboveText(LineSegment line) { - // Test four points (left and right corner of top and bottom line) - - Point topLeft = line.closestPointOnSegmentTo(topCharArea.p1); - Point topRight = line.closestPointOnSegmentTo(topCharArea.p2); - - bool lineIsBelowTop = topCharArea.isPointBelowLine(topLeft) || topCharArea.isPointBelowLine(topRight); - - if (!lineIsBelowTop) - return 1; - - Point bottomLeft = line.closestPointOnSegmentTo(bottomCharArea.p1); - Point bottomRight = line.closestPointOnSegmentTo(bottomCharArea.p2); - - bool lineIsBelowBottom = bottomCharArea.isPointBelowLine(bottomLeft) && - bottomCharArea.isPointBelowLine(bottomRight); - - if (lineIsBelowBottom) - return -1; - - return 0; - -} - -// Returns 1 for left, 0 for within, and -1 for to the right -int TextLineCollection::isLeftOfText(LineSegment line) { - - LineSegment leftSide = LineSegment(bottomCharArea.p1, topCharArea.p1); - - Point topLeft = line.closestPointOnSegmentTo(leftSide.p2); - Point bottomLeft = line.closestPointOnSegmentTo(leftSide.p1); - - bool lineIsAboveLeft = (!leftSide.isPointBelowLine(topLeft)) && (!leftSide.isPointBelowLine(bottomLeft)); - - if (lineIsAboveLeft) - return 1; - - LineSegment rightSide = LineSegment(bottomCharArea.p2, topCharArea.p2); - - Point topRight = line.closestPointOnSegmentTo(rightSide.p2); - Point bottomRight = line.closestPointOnSegmentTo(rightSide.p1); - - - bool lineIsBelowRight = rightSide.isPointBelowLine(topRight) && rightSide.isPointBelowLine(bottomRight); - - if (lineIsBelowRight) - return -1; - - return 0; -} - -void TextLineCollection::findCenterHorizontal() { - // To find the center horizontal line: - // Find the longer of the lines (if multiline) - // Get the nearest point on the bottom-most line for the - // left and right - - - - Point leftP1 = shorterSegment.closestPointOnSegmentTo(longerSegment.p1); - Point leftP2 = longerSegment.p1; - LineSegment left = LineSegment(leftP1, leftP2); - - Point leftMidpoint = left.midpoint(); - - - - Point rightP1 = shorterSegment.closestPointOnSegmentTo(longerSegment.p2); - Point rightP2 = longerSegment.p2; - LineSegment right = LineSegment(rightP1, rightP2); - - Point rightMidpoint = right.midpoint(); - - this->centerHorizontalLine = LineSegment(leftMidpoint, rightMidpoint); - -} - -void TextLineCollection::findCenterVertical() { - // To find the center vertical line: - // Choose the longest line (if multiline) - // Get the midpoint - // Draw a line up/down using the closest point on the bottom line - - - Point p1 = longerSegment.midpoint(); - - Point p2 = shorterSegment.closestPointOnSegmentTo(p1); - - // Draw bottom to top - if (p1.y < p2.y) - this->centerVerticalLine = LineSegment(p1, p2); - else - this->centerVerticalLine = LineSegment(p2, p1); -} diff --git a/src/openalpr/edges/platecorners.h b/src/openalpr/edges/platecorners.h index c297513..3415ee1 100644 --- a/src/openalpr/edges/platecorners.h +++ b/src/openalpr/edges/platecorners.h @@ -24,7 +24,7 @@ #include "platelines.h" #include "utility.h" #include "config.h" - +#include "textlinecollection.h" #define NO_LINE -1 @@ -42,36 +42,6 @@ #define SCORING_VERTICALDISTANCE_FROMEDGE_WEIGHT 0.05 -class TextLineCollection -{ -public: - TextLineCollection(PipelineData* pipelineData); - - int isLeftOfText(LineSegment line); - int isAboveText(LineSegment line); - - LineSegment centerHorizontalLine; - LineSegment centerVerticalLine; - - float charHeight; - float charAngle; - - - -private: - PipelineData* pipelineData; - - LineSegment topCharArea; - LineSegment bottomCharArea; - - LineSegment longerSegment; - LineSegment shorterSegment; - - cv::Mat textMask; - - void findCenterHorizontal(); - void findCenterVertical(); -}; class PlateCorners { diff --git a/src/openalpr/edges/textlinecollection.cpp b/src/openalpr/edges/textlinecollection.cpp new file mode 100644 index 0000000..a0bc7fb --- /dev/null +++ b/src/openalpr/edges/textlinecollection.cpp @@ -0,0 +1,160 @@ +/* + * File: textlinecollection.cpp + * Author: mhill + * + * Created on October 25, 2014, 4:06 PM + */ + +#include "textlinecollection.h" + +using namespace cv; +using namespace std; + +TextLineCollection::TextLineCollection(std::vector textLines) { + + + charHeight = 0; + charAngle = 0; + for (uint i = 0; i < textLines.size(); i++) + { + charHeight += textLines[i].lineHeight; + charAngle += textLines[i].angle; + + } + charHeight = charHeight / textLines.size(); + charAngle = charAngle / textLines.size(); + + this->topCharArea = textLines[0].charBoxTop; + this->bottomCharArea = textLines[0].charBoxBottom; + for (uint i = 1; i < textLines.size(); i++) + { + + if (this->topCharArea.isPointBelowLine(textLines[i].charBoxTop.midpoint()) == false) + this->topCharArea = textLines[i].charBoxTop; + + if (this->bottomCharArea.isPointBelowLine(textLines[i].charBoxBottom.midpoint())) + this->bottomCharArea = textLines[i].charBoxBottom; + + } + + longerSegment = this->bottomCharArea; + shorterSegment = this->topCharArea; + if (this->topCharArea.length > this->bottomCharArea.length) + { + longerSegment = this->topCharArea; + shorterSegment = this->bottomCharArea; + } + + findCenterHorizontal(); + findCenterVertical(); + // Center Vertical Line + + +} + +cv::Mat TextLineCollection::getDebugImage(cv::Size imageSize) { + + Mat debugImage = Mat::zeros(imageSize, CV_8U); + line(debugImage, this->centerHorizontalLine.p1, this->centerHorizontalLine.p2, Scalar(255,255,255), 2); + line(debugImage, this->centerVerticalLine.p1, this->centerVerticalLine.p2, Scalar(255,255,255), 2); + + return debugImage; + +} + + +// Returns 1 for above, 0 for within, and -1 for below +int TextLineCollection::isAboveText(LineSegment line) { + // Test four points (left and right corner of top and bottom line) + + Point topLeft = line.closestPointOnSegmentTo(topCharArea.p1); + Point topRight = line.closestPointOnSegmentTo(topCharArea.p2); + + bool lineIsBelowTop = topCharArea.isPointBelowLine(topLeft) || topCharArea.isPointBelowLine(topRight); + + if (!lineIsBelowTop) + return 1; + + Point bottomLeft = line.closestPointOnSegmentTo(bottomCharArea.p1); + Point bottomRight = line.closestPointOnSegmentTo(bottomCharArea.p2); + + bool lineIsBelowBottom = bottomCharArea.isPointBelowLine(bottomLeft) && + bottomCharArea.isPointBelowLine(bottomRight); + + if (lineIsBelowBottom) + return -1; + + return 0; + +} + +// Returns 1 for left, 0 for within, and -1 for to the right +int TextLineCollection::isLeftOfText(LineSegment line) { + + LineSegment leftSide = LineSegment(bottomCharArea.p1, topCharArea.p1); + + Point topLeft = line.closestPointOnSegmentTo(leftSide.p2); + Point bottomLeft = line.closestPointOnSegmentTo(leftSide.p1); + + bool lineIsAboveLeft = (!leftSide.isPointBelowLine(topLeft)) && (!leftSide.isPointBelowLine(bottomLeft)); + + if (lineIsAboveLeft) + return 1; + + LineSegment rightSide = LineSegment(bottomCharArea.p2, topCharArea.p2); + + Point topRight = line.closestPointOnSegmentTo(rightSide.p2); + Point bottomRight = line.closestPointOnSegmentTo(rightSide.p1); + + + bool lineIsBelowRight = rightSide.isPointBelowLine(topRight) && rightSide.isPointBelowLine(bottomRight); + + if (lineIsBelowRight) + return -1; + + return 0; +} + +void TextLineCollection::findCenterHorizontal() { + // To find the center horizontal line: + // Find the longer of the lines (if multiline) + // Get the nearest point on the bottom-most line for the + // left and right + + + + Point leftP1 = shorterSegment.closestPointOnSegmentTo(longerSegment.p1); + Point leftP2 = longerSegment.p1; + LineSegment left = LineSegment(leftP1, leftP2); + + Point leftMidpoint = left.midpoint(); + + + + Point rightP1 = shorterSegment.closestPointOnSegmentTo(longerSegment.p2); + Point rightP2 = longerSegment.p2; + LineSegment right = LineSegment(rightP1, rightP2); + + Point rightMidpoint = right.midpoint(); + + this->centerHorizontalLine = LineSegment(leftMidpoint, rightMidpoint); + +} + +void TextLineCollection::findCenterVertical() { + // To find the center vertical line: + // Choose the longest line (if multiline) + // Get the midpoint + // Draw a line up/down using the closest point on the bottom line + + + Point p1 = longerSegment.midpoint(); + + Point p2 = shorterSegment.closestPointOnSegmentTo(p1); + + // Draw bottom to top + if (p1.y < p2.y) + this->centerVerticalLine = LineSegment(p1, p2); + else + this->centerVerticalLine = LineSegment(p2, p1); +} diff --git a/src/openalpr/edges/textlinecollection.h b/src/openalpr/edges/textlinecollection.h new file mode 100644 index 0000000..660a6f6 --- /dev/null +++ b/src/openalpr/edges/textlinecollection.h @@ -0,0 +1,48 @@ +/* + * File: textlinecollection.h + * Author: mhill + * + * Created on October 25, 2014, 4:06 PM + */ + +#ifndef OPENALPR_TEXTLINECOLLECTION_H +#define OPENALPR_TEXTLINECOLLECTION_H + +#include "utility.h" + +#include "opencv2/imgproc/imgproc.hpp" +#include "textdetection/textline.h" + + +class TextLineCollection +{ +public: + TextLineCollection(std::vector textLines); + + int isLeftOfText(LineSegment line); + int isAboveText(LineSegment line); + + LineSegment centerHorizontalLine; + LineSegment centerVerticalLine; + + float charHeight; + float charAngle; + + cv::Mat getDebugImage(cv::Size imageSize); + +private: + + LineSegment topCharArea; + LineSegment bottomCharArea; + + LineSegment longerSegment; + LineSegment shorterSegment; + + cv::Mat textMask; + + void findCenterHorizontal(); + void findCenterVertical(); +}; + +#endif /* OPENALPR_TEXTLINECOLLECTION_H */ +