aboutsummaryrefslogtreecommitdiff
path: root/helium/heliumtextdetector.cpp
blob: 401597c98803f324b165b0536d21ea6b9e99efde (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright 2006 Google Inc.
// All Rights Reserved.
// Author: <renn@google.com> (Marius Renn)
//
// Local includes
#include <time.h>
#include "clusterer.h"
#include "contourdetector.h"
#include "debugging.h"
#include "edgedetector.h"
#include "gaussiansmooth.h"
#include "heliumtextdetector.h"
#include "maxtracer.h"
#include "imageenhancer.h"
#include "helium_image.h"
#include "quicksmooth.h"
#include "shapetree.h"
#include "sobeledgedetector.h"
#include "laplaceedgedetector.h"
#include "textclassifier.h"
#include "textvalidator.h"

using namespace helium;


static void ShowTrace(ContourDetector& outliner, int trace_type,
                      int width, int height) {
  Mask mask(width, height);
  outliner.PlotTracesOnto(mask, trace_type);
  Image trace_image = Image::FromMask(mask);
  // Leptonica::DisplayImage(trace_image);
}

static void ShowShapeTree(Clusterer& clusterer, ShapeTree& shapes,
                          int width, int height) {
  Image image(width, height);
  image.Clear();
  shapes.PaintShapes(image);
  clusterer.DrawClusterBounds(image);
  // Leptonica::DisplayImage(image);
}

HeliumTextDetector::HeliumTextDetector()
  : parameters_(),
    clusterer_(),
    shapemaker_(),
    text_areas_(NULL),
    show_debug_(false) {
}

HeliumTextDetector::~HeliumTextDetector() {
  delete text_areas_;
  delete parameters_.edge_detector;
  delete parameters_.tracer;
}

void HeliumTextDetector::SetDefaultParameters() {
  parameters_.use_gaussian_smoothing = false;
  parameters_.gaussian_strength = 3;
  parameters_.edge_detector = new SobelEdgeDetector();
  // parameters_.edge_detector = new LaplaceEdgeDetector();
  parameters_.tracer = new MaxTracer(24);
  parameters_.trace_threshold = 16;
}

const TextAreas& HeliumTextDetector::GetTextAreas() {
  GetMutableTextAreas();
  return *text_areas_;
}

TextAreas* HeliumTextDetector::GetMutableTextAreas() {
  if (!text_areas_) {
    text_areas_ = new TextAreas(clusterer_.clusters());
  }
  return text_areas_;
}

void HeliumTextDetector::DetectText(const Image& image) {
  ASSERT(image.Valid());

  // Clean up any remains from last detection
  delete(text_areas_);
  text_areas_ = NULL;

  // Parameters set?
  ASSERT(parameters_.edge_detector && parameters_.tracer);

  // Smooth image
  Image smooth_image;
  if (parameters_.use_gaussian_smoothing) {
    GaussianSmooth gaussian_blur(parameters_.gaussian_strength);
    smooth_image = gaussian_blur.Smooth(image);
  } else {
    smooth_image.Copy(image);
    QuickSmooth::Smooth(smooth_image);
  }

  ImageEnhancer::EnhanceColors(smooth_image, kMinDynamicRange);

  // Edge detection
  EdgeDetector* detector = parameters_.edge_detector;
  GrayMap edges = detector->DetectEdges(smooth_image);
  ImageEnhancer::LocalContrast(edges);

  // Tracing
  TextClassifier text_classifier;
  Tracer* tracer = parameters_.tracer;
  tracer->set_trace_map(&edges);
  ContourDetector outliner(*tracer, text_classifier);
  outliner.DetectContours(edges,
                          parameters_.trace_threshold,
                          smooth_image);

  // Labeling
  shapemaker_.ClearShapes();
  shapemaker_.ConvertTraces(outliner.contours(), smooth_image);

  // Clustering
  TextValidator text_validator;
  clusterer_.ClearClusters();
  clusterer_.ClusterShapes(shapemaker_.shapes(), text_validator);

  if (show_debug_) {
    // Leptonica::DisplayImage(smooth_image);
    // Leptonica::DisplayGrayMap(edges);
    ShowTrace(outliner, TRACECLASS_TEXT, image.width(), image.height());
    ShowShapeTree(clusterer_, shapemaker_, image.width(), image.height());
  }
}