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; }