mirror of
https://github.com/kerberos-io/openalpr-base.git
synced 2025-10-06 21:12:47 +08:00
Added TextLineCollection to its own class file
This commit is contained in:
@@ -19,6 +19,7 @@ set(lpr_source_files
|
|||||||
segmentation/verticalhistogram.cpp
|
segmentation/verticalhistogram.cpp
|
||||||
edges/platecorners.cpp
|
edges/platecorners.cpp
|
||||||
edges/platelines.cpp
|
edges/platelines.cpp
|
||||||
|
edges/textlinecollection.cpp
|
||||||
colorfilter.cpp
|
colorfilter.cpp
|
||||||
textdetection/characteranalysis.cpp
|
textdetection/characteranalysis.cpp
|
||||||
textdetection/platemask.cpp
|
textdetection/platemask.cpp
|
||||||
|
@@ -23,7 +23,7 @@ using namespace cv;
|
|||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
PlateCorners::PlateCorners(Mat inputImage, PlateLines* plateLines, PipelineData* pipelineData) :
|
PlateCorners::PlateCorners(Mat inputImage, PlateLines* plateLines, PipelineData* pipelineData) :
|
||||||
tlc(pipelineData)
|
tlc(pipelineData->textLines)
|
||||||
{
|
{
|
||||||
this->pipelineData = pipelineData;
|
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@@ -24,7 +24,7 @@
|
|||||||
#include "platelines.h"
|
#include "platelines.h"
|
||||||
#include "utility.h"
|
#include "utility.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "textlinecollection.h"
|
||||||
|
|
||||||
#define NO_LINE -1
|
#define NO_LINE -1
|
||||||
|
|
||||||
@@ -42,36 +42,6 @@
|
|||||||
|
|
||||||
#define SCORING_VERTICALDISTANCE_FROMEDGE_WEIGHT 0.05
|
#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
|
class PlateCorners
|
||||||
{
|
{
|
||||||
|
160
src/openalpr/edges/textlinecollection.cpp
Normal file
160
src/openalpr/edges/textlinecollection.cpp
Normal file
@@ -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<TextLine> 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);
|
||||||
|
}
|
48
src/openalpr/edges/textlinecollection.h
Normal file
48
src/openalpr/edges/textlinecollection.h
Normal file
@@ -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<TextLine> 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 */
|
||||||
|
|
Reference in New Issue
Block a user