|
Tesseract
3.02
|
#include <textlineprojection.h>
Public Member Functions | |
| TextlineProjection (int resolution) | |
| ~TextlineProjection () | |
| void | ConstructProjection (TO_BLOCK *input_block, const FCOORD &rotation, Pix *nontext_map) |
| void | PlotGradedBlobs (BLOBNBOX_LIST *blobs, ScrollView *win) |
| void | MoveNonTextlineBlobs (BLOBNBOX_LIST *blobs, BLOBNBOX_LIST *small_blobs) const |
| void | DisplayProjection () const |
| int | DistanceOfBoxFromPartition (const TBOX &box, const ColPartition &part, const DENORM *denorm, bool debug) const |
| int | DistanceOfBoxFromBox (const TBOX &from_box, const TBOX &to_box, bool horizontal_textline, const DENORM *denorm, bool debug) const |
| int | VerticalDistance (bool debug, int x, int y1, int y2) const |
| int | HorizontalDistance (bool debug, int x1, int x2, int y) const |
| bool | BoxOutOfHTextline (const TBOX &box, const DENORM *denorm, bool debug) const |
| int | EvaluateColPartition (const ColPartition &part, const DENORM *denorm, bool debug) const |
| int | EvaluateBox (const TBOX &box, const DENORM *denorm, bool debug) const |
Definition at line 33 of file textlineprojection.h.
| tesseract::TextlineProjection::TextlineProjection | ( | int | resolution | ) | [explicit] |
Definition at line 41 of file textlineprojection.cpp.
: x_origin_(0), y_origin_(0), pix_(NULL) { // The projection map should be about 100 ppi, whatever the input. scale_factor_ = IntCastRounded(resolution / 100.0); if (scale_factor_ < 1) scale_factor_ = 1; }
| tesseract::TextlineProjection::~TextlineProjection | ( | ) |
Definition at line 47 of file textlineprojection.cpp.
{
pixDestroy(&pix_);
}
| bool tesseract::TextlineProjection::BoxOutOfHTextline | ( | const TBOX & | box, |
| const DENORM * | denorm, | ||
| bool | debug | ||
| ) | const |
Definition at line 338 of file textlineprojection.cpp.
{
int grad1 = 0;
int grad2 = 0;
EvaluateBoxInternal(box, denorm, debug, &grad1, &grad2, NULL, NULL);
int worst_result = MIN(grad1, grad2);
int total_result = grad1 + grad2;
if (total_result >= 6) return false; // Strongly in textline.
// Medium strength: if either gradient is negative, it is likely outside
// the body of the textline.
if (worst_result < 0)
return true;
return false;
}
| void tesseract::TextlineProjection::ConstructProjection | ( | TO_BLOCK * | input_block, |
| const FCOORD & | rotation, | ||
| Pix * | nontext_map | ||
| ) |
Definition at line 58 of file textlineprojection.cpp.
{
pixDestroy(&pix_);
TBOX image_box(0, 0, pixGetWidth(nontext_map), pixGetHeight(nontext_map));
x_origin_ = 0;
y_origin_ = image_box.height();
int width = (image_box.width() + scale_factor_ - 1) / scale_factor_;
int height = (image_box.height() + scale_factor_ - 1) / scale_factor_;
pix_ = pixCreate(width, height, 8);
ProjectBlobs(&input_block->blobs, rotation, image_box, nontext_map);
ProjectBlobs(&input_block->large_blobs, rotation, image_box, nontext_map);
Pix* final_pix = pixBlockconv(pix_, 1, 1);
// Pix* final_pix = pixBlockconv(pix_, 2, 2);
pixDestroy(&pix_);
pix_ = final_pix;
}
| void tesseract::TextlineProjection::DisplayProjection | ( | ) | const |
Definition at line 117 of file textlineprojection.cpp.
{
int width = pixGetWidth(pix_);
int height = pixGetHeight(pix_);
Pix* pixc = pixCreate(width, height, 32);
int src_wpl = pixGetWpl(pix_);
int col_wpl = pixGetWpl(pixc);
uinT32* src_data = pixGetData(pix_);
uinT32* col_data = pixGetData(pixc);
for (int y = 0; y < height; ++y, src_data += src_wpl, col_data += col_wpl) {
for (int x = 0; x < width; ++x) {
int pixel = GET_DATA_BYTE(src_data, x);
l_uint32 result;
if (pixel <= 17)
composeRGBPixel(0, 0, pixel * 15, &result);
else if (pixel <= 145)
composeRGBPixel(0, (pixel - 17) * 2, 255, &result);
else
composeRGBPixel((pixel - 145) * 2, 255, 255, &result);
col_data[x] = result;
}
}
#if 0
// TODO(rays) uncomment when scrollview can display non-binary images.
ScrollView* win = new ScrollView("Projection", 0, 0,
width, height, width, height);
win->Image(pixc, 0, 0);
win->Update();
#else
pixWrite("projection.png", pixc, IFF_PNG);
#endif
pixDestroy(&pixc);
}
| int tesseract::TextlineProjection::DistanceOfBoxFromBox | ( | const TBOX & | from_box, |
| const TBOX & | to_box, | ||
| bool | horizontal_textline, | ||
| const DENORM * | denorm, | ||
| bool | debug | ||
| ) | const |
Definition at line 194 of file textlineprojection.cpp.
{
// The parallel_gap is the horizontal gap between a horizontal textline and
// the box. Analogous for vertical.
int parallel_gap = 0;
// start_pt is the box end of the line to be modified for curved space.
TPOINT start_pt;
// end_pt is the partition end of the line to be modified for curved space.
TPOINT end_pt;
if (horizontal_textline) {
parallel_gap = from_box.x_gap(to_box) + from_box.width();
start_pt.x = (from_box.left() + from_box.right()) / 2;
end_pt.x = start_pt.x;
if (from_box.top() - to_box.top() >= to_box.bottom() - from_box.bottom()) {
start_pt.y = from_box.top();
end_pt.y = MIN(to_box.top(), start_pt.y);
} else {
start_pt.y = from_box.bottom();
end_pt.y = MAX(to_box.bottom(), start_pt.y);
}
} else {
parallel_gap = from_box.y_gap(to_box) + from_box.height();
if (from_box.right() - to_box.right() >= to_box.left() - from_box.left()) {
start_pt.x = from_box.right();
end_pt.x = MIN(to_box.right(), start_pt.x);
} else {
start_pt.x = from_box.left();
end_pt.x = MAX(to_box.left(), start_pt.x);
}
start_pt.y = (from_box.bottom() + from_box.top()) / 2;
end_pt.y = start_pt.y;
}
// The perpendicular gap is the max vertical distance gap out of:
// top of from_box to to_box top and bottom of from_box to to_box bottom.
// This value is then modified for curved projection space.
// Analogous for vertical.
int perpendicular_gap = 0;
// If start_pt == end_pt, then the from_box lies entirely within the to_box
// (in the perpendicular direction), so we don't need to calculate the
// perpendicular_gap.
if (start_pt.x != end_pt.x || start_pt.y != end_pt.y) {
if (denorm != NULL) {
// Denormalize the start and end.
denorm->DenormTransform(start_pt, &start_pt);
denorm->DenormTransform(end_pt, &end_pt);
}
if (abs(start_pt.y - end_pt.y) >= abs(start_pt.x - end_pt.x)) {
perpendicular_gap = VerticalDistance(debug, start_pt.x, start_pt.y,
end_pt.y);
} else {
perpendicular_gap = HorizontalDistance(debug, start_pt.x, end_pt.x,
start_pt.y);
}
}
// The parallel_gap weighs less than the perpendicular_gap.
return perpendicular_gap + parallel_gap / kParaPerpDistRatio;
}
| int tesseract::TextlineProjection::DistanceOfBoxFromPartition | ( | const TBOX & | box, |
| const ColPartition & | part, | ||
| const DENORM * | denorm, | ||
| bool | debug | ||
| ) | const |
Definition at line 154 of file textlineprojection.cpp.
{
// Compute a partition box that uses the median top/bottom of the blobs
// within and median left/right for vertical.
TBOX part_box = part.bounding_box();
if (part.IsHorizontalType()) {
part_box.set_top(part.median_top());
part_box.set_bottom(part.median_bottom());
} else {
part_box.set_left(part.median_left());
part_box.set_right(part.median_right());
}
// Now use DistanceOfBoxFromBox to make the actual calculation.
return DistanceOfBoxFromBox(box, part_box, part.IsHorizontalType(),
denorm, debug);
}
| int tesseract::TextlineProjection::EvaluateColPartition | ( | const ColPartition & | part, |
| const DENORM * | denorm, | ||
| bool | debug | ||
| ) | const |
Definition at line 359 of file textlineprojection.cpp.
{
if (part.IsSingleton())
return EvaluateBox(part.bounding_box(), denorm, debug);
// Test vertical orientation.
TBOX box = part.bounding_box();
// Use the partition median for left/right.
box.set_left(part.median_left());
box.set_right(part.median_right());
int vresult = EvaluateBox(box, denorm, debug);
// Test horizontal orientation.
box = part.bounding_box();
// Use the partition median for top/bottom.
box.set_top(part.median_top());
box.set_bottom(part.median_bottom());
int hresult = EvaluateBox(box, denorm, debug);
if (debug) {
tprintf("Partition hresult=%d, vresult=%d from:", hresult, vresult);
part.bounding_box().print();
part.Print();
}
return hresult >= -vresult ? hresult : vresult;
}
| int tesseract::TextlineProjection::HorizontalDistance | ( | bool | debug, |
| int | x1, | ||
| int | x2, | ||
| int | y | ||
| ) | const |
Definition at line 306 of file textlineprojection.cpp.
{
x1 = ImageXToProjectionX(x1);
x2 = ImageXToProjectionX(x2);
y = ImageYToProjectionY(y);
if (x1 == x2) return 0;
int wpl = pixGetWpl(pix_);
int step = x1 < x2 ? 1 : -1;
uinT32* data = pixGetData(pix_) + y * wpl;
int prev_pixel = GET_DATA_BYTE(data, x1);
int distance = 0;
int right_way_steps = 0;
for (int x = x1; x != x2; x += step) {
int pixel = GET_DATA_BYTE(data, x + step);
if (debug)
tprintf("At (%d,%d), pix = %d, prev=%d\n",
x + step, y, pixel, prev_pixel);
if (pixel < prev_pixel)
distance += kWrongWayPenalty;
else if (pixel > prev_pixel)
++right_way_steps;
else
++distance;
prev_pixel = pixel;
}
return distance * scale_factor_ +
right_way_steps * scale_factor_ / kWrongWayPenalty;
}
| void tesseract::TextlineProjection::MoveNonTextlineBlobs | ( | BLOBNBOX_LIST * | blobs, |
| BLOBNBOX_LIST * | small_blobs | ||
| ) | const |
Definition at line 100 of file textlineprojection.cpp.
{
BLOBNBOX_IT it(blobs);
BLOBNBOX_IT small_it(small_blobs);
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
BLOBNBOX* blob = it.data();
const TBOX& box = blob->bounding_box();
bool debug = AlignedBlob::WithinTestRegion(2, box.left(),
box.bottom());
if (BoxOutOfHTextline(box, NULL, debug) && !blob->UniquelyVertical()) {
blob->ClearNeighbours();
small_it.add_to_end(it.extract());
}
}
}
| void tesseract::TextlineProjection::PlotGradedBlobs | ( | BLOBNBOX_LIST * | blobs, |
| ScrollView * | win | ||
| ) |
Definition at line 78 of file textlineprojection.cpp.
{
#ifndef GRAPHICS_DISABLED
BLOBNBOX_IT it(blobs);
for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
BLOBNBOX* blob = it.data();
const TBOX& box = blob->bounding_box();
bool bad_box = BoxOutOfHTextline(box, NULL, false);
if (blob->UniquelyVertical())
win->Pen(ScrollView::YELLOW);
else
win->Pen(bad_box ? ScrollView::RED : ScrollView::BLUE);
win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
}
win->Update();
#endif // GRAPHICS_DISABLED
}
| int tesseract::TextlineProjection::VerticalDistance | ( | bool | debug, |
| int | x, | ||
| int | y1, | ||
| int | y2 | ||
| ) | const |
Definition at line 273 of file textlineprojection.cpp.
{
x = ImageXToProjectionX(x);
y1 = ImageYToProjectionY(y1);
y2 = ImageYToProjectionY(y2);
if (y1 == y2) return 0;
int wpl = pixGetWpl(pix_);
int step = y1 < y2 ? 1 : -1;
uinT32* data = pixGetData(pix_) + y1 * wpl;
wpl *= step;
int prev_pixel = GET_DATA_BYTE(data, x);
int distance = 0;
int right_way_steps = 0;
for (int y = y1; y != y2; y += step) {
data += wpl;
int pixel = GET_DATA_BYTE(data, x);
if (debug)
tprintf("At (%d,%d), pix = %d, prev=%d\n",
x, y + step, pixel, prev_pixel);
if (pixel < prev_pixel)
distance += kWrongWayPenalty;
else if (pixel > prev_pixel)
++right_way_steps;
else
++distance;
prev_pixel = pixel;
}
return distance * scale_factor_ +
right_way_steps * scale_factor_ / kWrongWayPenalty;
}