diff --git a/src/openalpr/segmentation/charactersegmenter.cpp b/src/openalpr/segmentation/charactersegmenter.cpp index 6e74e02..065a5ad 100644 --- a/src/openalpr/segmentation/charactersegmenter.cpp +++ b/src/openalpr/segmentation/charactersegmenter.cpp @@ -44,7 +44,7 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data) pipeline_data->clearThresholds(); pipeline_data->thresholds = produceThresholds(pipeline_data->crop_gray, config); - + // TODO: Perhaps a bilateral filter would be better here. medianBlur(pipeline_data->crop_gray, pipeline_data->crop_gray, 3); if (this->config->debugCharSegmenter) @@ -91,20 +91,18 @@ CharacterSegmenter::CharacterSegmenter(PipelineData* pipeline_data) // imgDbgGeneral.push_back(bordered); // } - + for (uint lineidx = 0; lineidx < pipeline_data->textLines.size(); lineidx++) { this->top = pipeline_data->textLines[lineidx].topLine; this->bottom = pipeline_data->textLines[lineidx].bottomLine; - float avgCharHeight = pipeline_data->textLines[lineidx].lineHeight; float height_to_width_ratio = pipeline_data->config->charHeightMM / pipeline_data->config->charWidthMM; float avgCharWidth = avgCharHeight / height_to_width_ratio; - //float avgCharWidth = median(charWidths.data(), charWidths.size()); - //removeSmallContours(pipeline_data->thresholds, charAnalysis->allTextContours, avgCharWidth, avgCharHeight); + removeSmallContours(pipeline_data->thresholds, avgCharHeight, pipeline_data->textLines[lineidx]); // Do the histogram analysis to figure out char regions @@ -438,28 +436,38 @@ vector CharacterSegmenter::get1DHits(Mat img, int yOffset) return hits; } -//void CharacterSegmenter::removeSmallContours(vector thresholds, vector contours, float avgCharWidth, float avgCharHeight) -//{ -// //const float MIN_CHAR_AREA = 0.02 * avgCharWidth * avgCharHeight; // To clear out the tiny specks -// const float MIN_CONTOUR_HEIGHT = 0.3 * avgCharHeight; -// -// for (uint i = 0; i < thresholds.size(); i++) -// { -// for (uint c = 0; c < contours[i].contours.size(); c++) -// { -// if (contours[i].contours[c].size() == 0) -// continue; -// -// Rect mr = boundingRect(contours[i].contours[c]); -// if (mr.height < MIN_CONTOUR_HEIGHT) -// { -// // Erase it -// drawContours(thresholds[i], contours[i].contours, c, Scalar(0, 0, 0), -1); -// continue; -// } -// } -// } -//} +void CharacterSegmenter::removeSmallContours(vector thresholds, float avgCharHeight, TextLine textLine) +{ + //const float MIN_CHAR_AREA = 0.02 * avgCharWidth * avgCharHeight; // To clear out the tiny specks + const float MIN_CONTOUR_HEIGHT = 0.3 * avgCharHeight; + + Mat textLineMask = Mat::zeros(thresholds[0].size(), CV_8U); + fillConvexPoly(textLineMask, textLine.linePolygon.data(), textLine.linePolygon.size(), Scalar(255,255,255)); + + for (uint i = 0; i < thresholds.size(); i++) + { + vector > contours; + vector hierarchy; + Mat thresholdsCopy = Mat::zeros(thresholds[i].size(), thresholds[i].type()); + + thresholds[i].copyTo(thresholdsCopy, textLineMask); + findContours(thresholdsCopy, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE); + + for (uint c = 0; c < contours.size(); c++) + { + if (contours[c].size() == 0) + continue; + + Rect mr = boundingRect(contours[c]); + if (mr.height < MIN_CONTOUR_HEIGHT) + { + // Erase it + drawContours(thresholds[i], contours, c, Scalar(0, 0, 0), -1); + continue; + } + } + } +} vector CharacterSegmenter::combineCloseBoxes( vector charBoxes, float biggestCharWidth) { diff --git a/src/openalpr/segmentation/charactersegmenter.h b/src/openalpr/segmentation/charactersegmenter.h index 5540b76..b468e62 100644 --- a/src/openalpr/segmentation/charactersegmenter.h +++ b/src/openalpr/segmentation/charactersegmenter.h @@ -64,7 +64,7 @@ class CharacterSegmenter cv::Mat getCharBoxMask(cv::Mat img_threshold, std::vector charBoxes); - void removeSmallContours(std::vector thresholds, std::vector contours, float avgCharWidth, float avgCharHeight); + void removeSmallContours(std::vector thresholds, float avgCharHeight, TextLine textLine); std::vector getHistogramBoxes(VerticalHistogram histogram, float avgCharWidth, float avgCharHeight, float* score); std::vector getBestCharBoxes(cv::Mat img, std::vector charBoxes, float avgCharWidth);