From 32ffa1c14486eb473b1d1d33ea2beaf73c779184 Mon Sep 17 00:00:00 2001 From: Samir55 Date: Sat, 2 Dec 2017 19:53:32 +0200 Subject: [PATCH] Update Valley Class. --- src/LineSegmentation.cpp | 39 ++++++++++++++++++++-------- src/LineSegmentation.hpp | 55 +++++++++++++++++++++++++++------------- 2 files changed, 67 insertions(+), 27 deletions(-) diff --git a/src/LineSegmentation.cpp b/src/LineSegmentation.cpp index 3aa5c2a..a012607 100755 --- a/src/LineSegmentation.cpp +++ b/src/LineSegmentation.cpp @@ -58,7 +58,7 @@ LineSegmentation::find_contours() { // Check for intersection/union. if ((rectangle3.area() == bound_rect[i].area()) || (rectangle3.area() == bound_rect[j].area())) { is_repeated = true; - rectangle3 = bound_rect[i] | bound_rect[j]; //merging + rectangle3 = bound_rect[i] | bound_rect[j]; // Merging. Rect2d merged_rectangle(rectangle3.tl().x, rectangle3.tl().y, rectangle3.width, rectangle3.height); // Push in merged rectangle after checking all the inner loop. @@ -353,13 +353,14 @@ LineSegmentation::get_regions() { return ret; } -Chunk::Chunk(int o, int c, int w, cv::Mat i) : valleys(vector()), peaks(vector()) { - this->order = o; +Chunk::Chunk(int i, int c, int w, cv::Mat m) : valleys(vector()), peaks(vector()) { + this->index = i; this->start_col = c; this->width = w; - this->img = i.clone(); + this->img = m.clone(); this->histogram.resize((unsigned long) this->img.rows); this->avg_height = 0; + this->avg_white_height = 0; this->lines_count = 0; } @@ -370,7 +371,9 @@ Chunk::calculate_histogram() { cv::medianBlur(this->img, img_clone, 5); this->img = img_clone; - int black_count = 0, current_height = 0; + int black_count = 0, current_height = 0, current_white_count = 0, white_lines_count = 0; + vector white_spaces; + for (int i = 0; i < img_clone.rows; ++i) { black_count = 0; for (int j = 0; j < img_clone.cols; ++j) { @@ -379,8 +382,14 @@ Chunk::calculate_histogram() { this->histogram[i]++; } } - if (black_count) current_height++; - else { + if (black_count) { + current_height++; + if (current_white_count) { + white_spaces.push_back(current_white_count); + } + current_white_count = 0; + } else { + current_white_count++; if (current_height) { lines_count++; avg_height += current_height; @@ -389,7 +398,16 @@ Chunk::calculate_histogram() { } } - // Calculate the average height. + // Calculate the white spaces average height. + sort(white_spaces.begin(), white_spaces.end()); + for (int i = 0; i < white_spaces.size(); ++i) { + if (white_spaces[i] > 4 * avg_height) break; + avg_white_height += white_spaces[i]; + white_lines_count++; + } + if (white_lines_count) avg_white_height /= white_lines_count; + + // Calculate the average line height. if (lines_count) avg_height /= lines_count; avg_height = max(30, int(avg_height + (avg_height / 2.0))); } @@ -447,10 +465,11 @@ Chunk::find_peaks_valleys() { min_position = j; } } - Valley *new_valley = new Valley(this->order, int(all_valleys_ids.size()), min_position, min_value); + + Valley *new_valley = new Valley(this->index, min_position); valleys.push_back(new_valley); - all_valleys_ids[valleys.back()->valley_id] = new_valley; + map_valley[new_valley->valley_id] = new_valley; } return int(ceil(avg_height)); } diff --git a/src/LineSegmentation.hpp b/src/LineSegmentation.hpp index 670051c..951a571 100755 --- a/src/LineSegmentation.hpp +++ b/src/LineSegmentation.hpp @@ -24,7 +24,8 @@ using namespace std; class LineSegmentation; /// A class representing the separator between line regions. -struct Line { +class Line +{ friend class LineSegmentation; friend class Region; @@ -55,18 +56,24 @@ struct Line { }; /// A class representing the peaks (local maximum points in the histogram). -class Peak { +class Peak +{ public: int position; ///< The row position. int value; ///< The number of foreground pixels. - Peak() {} + Peak() + {} - Peak(int p, int v) : position(p), value(v) {} + Peak(int p, int v) + : position(p), value(v) + {} - Peak(int p, int v, int s, int e) : position(p), value(v) {} + Peak(int p, int v, int s, int e) + : position(p), value(v) + {} /// Compare according to the value. // ToDo @Samir55 change that when finishing. bool @@ -78,7 +85,8 @@ class Peak { }; /// A class representing the valleys (local minimum points in the histogram) -class Valley { +class Valley +{ public: static int ID; ///< Next available id. @@ -90,19 +98,24 @@ class Valley { ///< The row position. bool used; /// Whether it's used by a line or not. - Line* line; + Line *line; /// The line to which this valley is connected. - Valley() : valley_id(ID++), used(false) {} + Valley() + : valley_id(ID++), used(false) + {} - Valley(int c_id, int p) : chunk_index(c_id), valley_id(ID++), position(p), used(false) {} + Valley(int c_id, int p) + : chunk_index(c_id), valley_id(ID++), position(p), used(false) + {} static bool comp(const Valley *a, const Valley *b); }; /// A class representing the line regions. -class Region { +class Region +{ friend class LineSegmentation; private: @@ -148,16 +161,18 @@ class Region { }; /// Image Chunk. -class Chunk { +class Chunk +{ friend class LineSegmentation; /// Valleys and peaks detection in this image chunk. + /// \param map_valley to fill it /// \return int the average line height in this chunk. int - find_peaks_valleys(); + find_peaks_valleys(map& map_valley); private: - int order; + int index; /// The index of the chunk. int start_col; ///< The start column position. @@ -173,6 +188,8 @@ class Chunk { ///< The found valleys in this chunk. int avg_height; ///< The average line height in this chunk. + int avg_white_height; + ///< The average space height in this chunk. int lines_count; ///< The estimated number of lines in this chunk. @@ -180,17 +197,21 @@ class Chunk { /// Calculate the chunk histogram (Y projection profile). /// This function is called by find_peaks_valleys. - void calculate_histogram(); + void + calculate_histogram(); }; /// Line Segmentation class. -class LineSegmentation { +class LineSegmentation +{ private: bool notPrimesArr[100007]; vector primes; - void sieve(); - void addPrimesToVector(int, vector &); + void + sieve(); + void + addPrimesToVector(int, vector &); public: LineSegmentation(string path_of_image);