Skip to content

Commit

Permalink
add the hability to make component labeling
Browse files Browse the repository at this point in the history
for a comparison between state of the art methods, is necessary to make component labeling. Usually Match Score is used to evaluate a text-line segmentation methods as we can see in the contest: 
 http://users.iit.demokritos.gr/~nstam/ICDAR2013HandSegmCont/Evaluation.html
  • Loading branch information
tonsquemike committed Jun 29, 2018
1 parent 4ebda7c commit cf56855
Show file tree
Hide file tree
Showing 44 changed files with 161 additions and 24 deletions.
21 changes: 21 additions & 0 deletions .vscode/c_cpp_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"configurations": [
{
"name": "Mac",
"includePath": [
"${workspaceFolder}/**",
"/usr/local/Cellar/opencv/3.4.1_5/include/opencv"
],
"defines": [],
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"compilerPath": "/usr/bin/clang",
"cStandard": "c11",
"cppStandard": "c++17",
"intelliSenseMode": "clang-x64"
}
],
"version": 4
}
20 changes: 20 additions & 0 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
// Use IntelliSense para saber los atributos posibles.
// Mantenga el puntero para ver las descripciones de los existentes atributos
// Para más información, visite: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "imageSegmentation",
"type": "cppdbg",
"request": "launch",
"program": "enter program name, for example ${workspaceFolder}/a.out",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "lldb"
}
]
}
37 changes: 37 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"files.associations": {
"__functional_base": "cpp",
"array": "cpp",
"istream": "cpp",
"locale": "cpp",
"memory": "cpp",
"tuple": "cpp",
"utility": "cpp",
"iosfwd": "cpp",
"ostream": "cpp",
"__config": "cpp",
"__nullptr": "cpp",
"cstddef": "cpp",
"exception": "cpp",
"initializer_list": "cpp",
"new": "cpp",
"stdexcept": "cpp",
"type_traits": "cpp",
"typeinfo": "cpp",
"algorithm": "cpp",
"__locale": "cpp",
"string_view": "cpp",
"iterator": "cpp",
"vector": "cpp",
"__split_buffer": "cpp",
"deque": "cpp",
"string": "cpp",
"iostream": "cpp",
"chrono": "cpp",
"limits": "cpp",
"ratio": "cpp",
"__tree": "cpp",
"bitset": "cpp",
"map": "cpp"
}
}
Binary file added img/out/Binary_image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk10.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk11.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk12.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk13.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk14.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk15.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk16.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk17.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk18.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk19.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk5.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk6.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk7.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk8.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Chunk9.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Copia de labels.bmp
Binary file not shown.
Binary file added img/out/Final_Lines.bmp
Binary file not shown.
Binary file added img/out/Initial_Lines.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Line_0.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Line_1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Line_10.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added img/out/Line_11.jpg
Binary file added img/out/Line_2.jpg
Binary file added img/out/Line_3.jpg
Binary file added img/out/Line_4.jpg
Binary file added img/out/Line_5.jpg
Binary file added img/out/Line_6.jpg
Binary file added img/out/Line_7.jpg
Binary file added img/out/Line_8.jpg
Binary file added img/out/Line_9.jpg
Binary file added img/out/contours.jpg
Binary file added img/out/labels.bmp
Binary file not shown.
78 changes: 62 additions & 16 deletions src/LineSegmentation.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#include "LineSegmentation.hpp"

LineSegmentation::LineSegmentation(string path_of_image) {
LineSegmentation::LineSegmentation(string path_of_image, string out) {
this->image_path = path_of_image;

this->OUT_PATH = out;
// Initialize Sieve.
sieve();
}
Expand All @@ -23,7 +23,7 @@ LineSegmentation::pre_process_image() {

// OTSU threshold and Binarization.
cv::threshold(smoothed_img, binary_img, 0.0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
imwrite("Binary_image.jpg", this->binary_img);
imwrite(OUT_PATH+"Binary_image.jpg", this->binary_img);
}

void
Expand Down Expand Up @@ -78,7 +78,7 @@ LineSegmentation::find_contours() {
// ToDo @Samir55 Remove.
for (size_t i = 0; i < merged_rectangles.size(); i++)
rectangle(drawing, merged_rectangles[i].tl(), merged_rectangles[i].br(), TEST_LINE_COLOR, 2, 8, 0);
cv::imwrite("contours.jpg", drawing);
cv::imwrite(OUT_PATH+"contours.jpg", drawing);
this->contours = merged_rectangles;
}

Expand All @@ -95,7 +95,7 @@ LineSegmentation::generate_chunks() {
chunk_width)));
this->chunks.push_back(c);

imwrite("Chunk" + to_string(i_chunk) + ".jpg", this->chunks.back()->img);
imwrite(OUT_PATH+"Chunk" + to_string(i_chunk) + ".jpg", this->chunks.back()->img);

start_pixel += chunk_width;
}
Expand Down Expand Up @@ -173,28 +173,76 @@ LineSegmentation::save_image_with_lines(string path) {

for (auto line : initial_lines) {
int last_row = -1;

//std::cout<<"new line"<<endl;
for (auto point : line->points) {
img_clone.at<Vec3b>(point.x, point.y) = TEST_LINE_COLOR;

//std::cout<<" ii="+std::to_string(point.y)+" jj="+std::to_string(point.x)<<endl;

// Check and draw vertical lines if found.
if (last_row != -1 && point.x != last_row) {
for (int i = min(last_row, point.x); i < max(last_row, point.x); i++) {
img_clone.at<Vec3b>(i, point.y) = TEST_LINE_COLOR;
//std::cout<<" i="+std::to_string(point.y)+" j="+std::to_string(i)<<endl;
}
}

last_row = point.x;
}
}
//cvtColor(img_clone,img_clone,CV_8UC3);
cv::imwrite(path, img_clone);
}

void
LineSegmentation::save_lines_to_file(const vector<cv::Mat> &lines, string path) {
LineSegmentation::save_lines_to_file(const vector<cv::Mat> &lines) {
int idx = 0;
for (auto m : lines) {
imwrite(path + "Line " + to_string(idx++) + ".jpg", m);
imwrite(OUT_PATH + "Line_" + to_string(idx++) + ".jpg", m);
}
}

void
LineSegmentation::labelImage(string path) {
cv::Mat img_clone = this->color_img.clone();
vector<cv::Point> pointactualLine(initial_lines[0]->points.size());
vector<cv::Point> pointnextLine;
//initialize line at 0,0
for(int i = 0; i<pointactualLine.size(); i++)
pointactualLine[i] = cv::Point(0,0);

for (int indexLine = 0; indexLine<initial_lines.size(); indexLine++) {
pointnextLine = initial_lines[indexLine]->points;

this->labelComponent(pointnextLine, pointactualLine, img_clone);

pointactualLine = pointnextLine;
}

//for label last text line
for(int i = 0; i<pointnextLine.size(); i++)
pointnextLine[i] = cv::Point(this->color_img.cols, 0);

this->labelComponent(pointnextLine, pointactualLine, img_clone);
cv::imwrite(path, img_clone);
}

void
LineSegmentation::labelComponent(const std::vector<cv::Point> &pointnextLine, const vector<cv::Point> &pointactualLine, cv::Mat &img_clone){
//for random color generation
int max = 220;
int min = 30;
cv::Vec3b randomColor = cv::Vec3b(rand() % max + min,rand() % max + min, redStart);

for (int indexPoint = 0; indexPoint < pointactualLine.size(); indexPoint++)
{
auto nextPoint = pointnextLine [indexPoint];
auto point = pointactualLine[indexPoint];

for(int x_ = point.x; x_<nextPoint.x; x_++) {
if(img_clone.at<Vec3b>(x_, indexPoint)[2]<125)
img_clone.at<Vec3b>(x_, indexPoint) = randomColor;
}
redStart+=5;
}
}

Expand Down Expand Up @@ -228,7 +276,6 @@ LineSegmentation::generate_regions() {

if (bottom_line != nullptr)
bottom_line->above = r;

if (!res) {
this->line_regions.push_back(r);
if (r->height < this->predicted_line_height * 2.5)
Expand All @@ -247,12 +294,10 @@ LineSegmentation::repair_lines() {
// Loop over the regions.
for (Line *line : initial_lines) {
map<int, bool> column_processed = map<int, bool>();

for (int i = 0; i < line->points.size(); i++) {
Point &point = line->points[i];

int x = (line->points[i]).x, y = (line->points[i]).y;

// Check for vertical line intersection
// In lines, we don't save all the vertical points we save only the start point and the end point.
// So in line->points all we save is the horizontal points so, we know there exists a vertical line by
Expand Down Expand Up @@ -281,7 +326,6 @@ LineSegmentation::repair_lines() {

// Mark column as processed.
column_processed[y] = true;

for (auto contour : this->contours) {
// Check line & contour intersection
if (y >= contour.tl().x && y <= contour.br().x && x >= contour.tl().y && x <= contour.br().y) {
Expand All @@ -299,7 +343,6 @@ LineSegmentation::repair_lines() {
new_row = contour.br().y;
line->max_row_position = max(new_row, line->max_row_position);
}

for (int k = contour.tl().x; k < contour.tl().x + contour.width; k++) {
line->points[k].x = new_row;
}
Expand Down Expand Up @@ -368,7 +411,7 @@ LineSegmentation::segment() {

// Get initial lines.
this->get_initial_lines();
this->save_image_with_lines("Initial_Lines.jpg");
this->save_image_with_lines(OUT_PATH+"Initial_Lines.jpg");

// Get initial line regions.
this->generate_regions();
Expand All @@ -379,7 +422,10 @@ LineSegmentation::segment() {
// Generate the final line regions.
this->generate_regions();

this->save_image_with_lines("Final_Lines.jpg");
this->save_image_with_lines(OUT_PATH+"Final_Lines.bmp");

//is neccesary to use bitmap or tiff for componente labeling
this->labelImage(OUT_PATH+"labels.bmp");

return this->get_regions();
}
Expand Down
22 changes: 17 additions & 5 deletions src/LineSegmentation.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif

//In the paper is explained that every chunk have a 5% of the width
#define CHUNKS_NUMBER 20
#define CHUNKS_TO_BE_PROCESSED 5
#define TEST_LINE_COLOR cv::Vec3b(255, 0, 255) // Magenta color.
#define TEST_LINE_COLOR cv::Vec3b(0, 0, 255) // Magenta color.

typedef int valley_id;

Expand All @@ -30,7 +30,7 @@ class LineSegmentation;
class Region;

class Valley;

extern string OUT_PATH;
/// A class representing the separator between line regions.
class Line {
friend class LineSegmentation;
Expand Down Expand Up @@ -213,8 +213,11 @@ class LineSegmentation {
void
addPrimesToVector(int, vector<int> &);

//first color index for identify regions from up to down
int redStart = 20;

public:
LineSegmentation(string path_of_image);
LineSegmentation(string path_of_image, string out);

/// Generate the lines found in the saved image.
/// \return vector<cv::Mat> a vector containing each line as a 2D mat.
Expand All @@ -224,9 +227,18 @@ class LineSegmentation {
/// Save current line regions returned from get_regions() or segment() functions in jpg files.
/// \param lines
/// \param path
void save_lines_to_file(const vector<cv::Mat> &lines, string path);
void save_lines_to_file(const vector<cv::Mat> &lines);

//document image labelling
void labelImage(string path);
//label a section of the image from y-pointactualLine to y1 pointnextLine
void
labelComponent(const vector<cv::Point> &pointnextLine, const vector<cv::Point> &pointactualLine, cv::Mat &img_clone);



private:
string OUT_PATH;
string image_path;
///< Path of the image.
cv::Mat color_img;
Expand Down
7 changes: 4 additions & 3 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@

int main(int argc, char *argv[]) {
cout << argv[1] << endl;
cout << argv[2] << endl;

string img_path = argv[1];
LineSegmentation line_segmentation(img_path);
LineSegmentation line_segmentation(img_path, argv[2]);
vector<cv::Mat> lines = line_segmentation.segment();

// Save lines to path.
line_segmentation.save_lines_to_file(lines, "");
line_segmentation.save_lines_to_file(lines);
return 0;
}

0 comments on commit cf56855

Please sign in to comment.