134 return type1 >= type2;
150 area =
static_cast<int>(srcblob->
area());
159 BLOBNBOX_IT it = boxes;
162 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
170 auto *blob =
new C_BLOB(outline);
175 void rotate(
FCOORD rotation);
179 void reflect_box_in_y_axis();
183 void rotate_box(
FCOORD rotation);
188 base_char_top_ += v.
y();
189 base_char_bottom_ += v.
y();
192 set_diacritic_box(box);
198 BLOBNBOX_IT *start_it,
199 BLOBNBOX_IT *blob_it,
203 void NeighbourGaps(
int gaps[
BND_COUNT])
const;
204 void MinMaxGapsClipped(
int *h_min,
int *h_max,
int *v_min,
int *v_max)
const;
205 void CleanNeighbours();
208 int GoodTextBlob()
const;
210 int NoisyNeighbours()
const;
214 return owner() ==
nullptr && region_type() ==
BRT_NOISE;
221 bool DefiniteIndividualFlow();
224 bool ConfirmNoTabViolation(
const BLOBNBOX &other)
const;
227 bool MatchingStrokeWidth(
const BLOBNBOX &other,
double fractional_tolerance,
228 double constant_tolerance)
const;
232 TBOX BoundsWithinLimits(
int left,
int right);
236 void EstimateBaselinePosition();
246 base_char_top_ = box.
top();
247 base_char_bottom_ = box.bottom();
250 box = cblob_ptr->bounding_box();
251 base_char_top_ = box.top();
252 base_char_bottom_ = box.bottom();
253 baseline_y_ = box.bottom();
272 return repeated_set_;
275 repeated_set_ = set_id;
281 auto blob = cblob_ptr;
287 return left_tab_type_;
290 left_tab_type_ = new_type;
293 return right_tab_type_;
296 right_tab_type_ = new_type;
302 region_type_ = new_type;
308 spt_type_ = new_type;
317 return vert_possible_;
320 vert_possible_ =
value;
323 return horz_possible_;
326 horz_possible_ =
value;
332 left_rule_ = new_left;
338 right_rule_ = new_right;
341 return left_crossing_rule_;
344 left_crossing_rule_ = new_left;
347 return right_crossing_rule_;
350 right_crossing_rule_ = new_right;
353 return horz_stroke_width_;
356 horz_stroke_width_ = width;
359 return vert_stroke_width_;
362 vert_stroke_width_ = width;
365 return area_stroke_width_;
374 return leader_on_left_;
377 leader_on_left_ = flag;
380 return leader_on_right_;
383 leader_on_right_ = flag;
386 return neighbours_[n];
389 return good_stroke_neighbours_[n];
392 neighbours_[n] = neighbour;
393 good_stroke_neighbours_[n] = good;
396 return base_char_top_ != box.top() || base_char_bottom_ != box.bottom();
399 return base_char_top_;
402 return base_char_bottom_;
408 return line_crossings_;
411 line_crossings_ =
value;
414 base_char_top_ = diacritic_box.
top();
415 base_char_bottom_ = diacritic_box.
bottom();
418 return base_char_blob_;
421 base_char_blob_ = blob;
428 return vert_possible_ && !horz_possible_;
431 return horz_possible_ && !vert_possible_;
448 return IsLineType(
type) || IsImageType(
type);
451 static void CleanNeighbours(BLOBNBOX_LIST *blobs);
453 static void DeleteNoiseBlobs(BLOBNBOX_LIST *blobs);
456 static void ComputeEdgeOffsets(
Image thresholds,
Image grey, BLOBNBOX_LIST *blobs);
458#ifndef GRAPHICS_DISABLED
492 left_crossing_rule_ = 0;
493 right_crossing_rule_ = 0;
494 if (area_stroke_width_ == 0.0f && area > 0 && cblob() !=
nullptr && cblob()->perimeter() != 0) {
495 area_stroke_width_ = 2.0f * area / cblob()->perimeter();
498 base_char_top_ = box.top();
499 base_char_bottom_ = box.bottom();
500 baseline_y_ = box.bottom();
502 base_char_blob_ =
nullptr;
503 horz_possible_ =
false;
504 vert_possible_ =
false;
505 leader_on_left_ =
false;
506 leader_on_right_ =
false;
512 neighbours_[n] =
nullptr;
513 good_stroke_neighbours_[n] =
false;
518 C_BLOB *cblob_ptr =
nullptr;
522 int32_t repeated_set_ = 0;
529 bool reduced =
false;
530 int16_t left_rule_ = 0;
531 int16_t right_rule_ = 0;
532 int16_t left_crossing_rule_;
533 int16_t right_crossing_rule_;
534 int16_t base_char_top_;
535 int16_t base_char_bottom_;
537 int32_t line_crossings_;
541 float horz_stroke_width_ = 0.0f;
542 float vert_stroke_width_ = 0.0f;
543 float area_stroke_width_ = 0.0f;
547 bool leader_on_left_;
548 bool leader_on_right_;
552 bool owns_cblob_ =
false;
565 float bottom,
float row_size);
575 return (y_min + y_max) / 2.0f;
578 return initial_y_min;
604 float bottom,
float row_size);
614 float new_c,
float new_error) {
621 float new_c,
float new_error) {
623 para_error = new_error;
624 credibility = blobs.length() -
kErrorWeight * new_error;
625 y_origin = new_c / std::sqrt(1 + gradient * gradient);
638 return num_repeated_sets_ != -1;
641 num_repeated_sets_ = -1;
644 return num_repeated_sets_;
647 num_repeated_sets_ = num_sets;
692 int num_repeated_sets_;
716 BLOBNBOX_LIST *blobnbox_list[] = {&blobs, &underlines, &noise_blobs,
717 &small_blobs, &large_blobs,
nullptr};
718 for (BLOBNBOX_LIST **list = blobnbox_list; *list !=
nullptr; ++list) {
719 BLOBNBOX_IT it(*list);
720 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
721 it.data()->rotate(rotation);
726 block->rotate(rotation);
728 STATS widths(0, block->pdblk.bounding_box().width() - 1);
729 STATS heights(0, block->pdblk.bounding_box().height() - 1);
730 BLOBNBOX_IT blob_it(&blobs);
731 for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
732 widths.
add(blob_it.data()->bounding_box().width(), 1);
733 heights.
add(blob_it.data()->bounding_box().height(), 1);
735 block->set_median_size(
static_cast<int>(widths.
median() + 0.5),
736 static_cast<int>(heights.
median() + 0.5));
740 TO_ROW_IT row_it = &row_list;
741 for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
742 auto row = row_it.data();
743 tprintf(
"Row range (%g,%g), para_c=%g, blobcount=%" PRId32
"\n",
744 static_cast<double>(row->min_y()),
745 static_cast<double>(row->max_y()),
746 static_cast<double>(row->parallel_c()),
747 row->blob_list()->length());
755 void ReSetAndReFilterBlobs();
758 void DeleteUnownedNoise();
767 void ComputeEdgeOffsets(
Image thresholds,
Image grey);
769#ifndef GRAPHICS_DISABLED
805 TO_ROW_LIST row_list;
846#ifndef GRAPHICS_DISABLED
#define ELISTIZEH(CLASSNAME)
#define ELIST2IZEH(CLASSNAME)
C_BLOB * crotate_cblob(C_BLOB *blob, FCOORD rotation)
void tprintf(const char *format,...)
void vertical_cblob_projection(C_BLOB *blob, STATS *stats)
void find_cblob_limits(C_BLOB *blob, float leftx, float rightx, FCOORD rotation, float &ymin, float &ymax)
void plot_blob_list(ScrollView *win, BLOBNBOX_LIST *list, ScrollView::Color body_colour, ScrollView::Color child_colour)
bool DominatesInMerge(BlobTextFlowType type1, BlobTextFlowType type2)
void find_cblob_hlimits(C_BLOB *blob, float bottomy, float topy, float &xmin, float &xmax)
void vertical_coutline_projection(C_OUTLINE *outline, STATS *stats)
void find_cblob_vlimits(C_BLOB *blob, float leftx, float rightx, float &ymin, float &ymax)
TBOX box_next_pre_chopped(BLOBNBOX_IT *it)
BlobNeighbourDir DirOtherWay(BlobNeighbourDir dir)
TBOX box_next(BLOBNBOX_IT *it)
int base_char_bottom() const
int base_char_top() const
float vert_stroke_width() const
void set_vert_possible(bool value)
static bool IsImageType(BlobRegionType type)
bool good_stroke_neighbour(BlobNeighbourDir n) const
bool leader_on_right() const
const TBOX & bounding_box() const
static BLOBNBOX * RealBlob(C_OUTLINE *outline)
bool DeletableNoise() const
static bool IsTextType(BlobRegionType type)
bool UniquelyHorizontal() const
BLOBNBOX(C_BLOB *srcblob)
void set_left_tab_type(TabType new_type)
BlobRegionType region_type() const
void set_horz_possible(bool value)
bool UniquelyVertical() const
void set_left_rule(int new_left)
TabType left_tab_type() const
int32_t enclosed_area() const
void set_right_tab_type(TabType new_type)
void set_flow(BlobTextFlowType value)
int left_crossing_rule() const
void set_repeated_set(int set_id)
void set_horz_stroke_width(float width)
void set_leader_on_right(bool flag)
void set_left_crossing_rule(int new_left)
void set_line_crossings(int value)
void set_base_char_blob(BLOBNBOX *blob)
static bool IsLineType(BlobRegionType type)
void set_vert_stroke_width(float width)
BLOBNBOX * base_char_blob() const
bool vert_possible() const
void set_neighbour(BlobNeighbourDir n, BLOBNBOX *neighbour, bool good)
void set_special_text_type(BlobSpecialTextType new_type)
int line_crossings() const
static void clear_blobnboxes(BLOBNBOX_LIST *boxes)
int baseline_position() const
void set_diacritic_box(const TBOX &diacritic_box)
TabType right_tab_type() const
void set_reduced_box(TBOX new_box)
void set_owner(tesseract::ColPartition *new_owner)
BlobTextFlowType flow() const
BLOBNBOX * neighbour(BlobNeighbourDir n) const
void set_bounding_box(const TBOX &new_box)
const TBOX & reduced_box() const
void translate_box(ICOORD v)
void set_right_crossing_rule(int new_right)
float area_stroke_width() const
void compute_bounding_box()
BlobSpecialTextType special_text_type() const
bool leader_on_left() const
tesseract::ColPartition * owner() const
void set_leader_on_left(bool flag)
void set_region_type(BlobRegionType new_type)
float horz_stroke_width() const
bool horz_possible() const
void set_right_rule(int new_right)
void set_owns_cblob(bool value)
int right_crossing_rule() const
bool joined_to_prev() const
static bool UnMergeableType(BlobRegionType type)
bool rep_chars_marked() const
static const int kErrorWeight
void add_blob(BLOBNBOX *blob, float top, float bottom, float row_size)
float believability() const
void set_num_repeated_sets(int num_sets)
float initial_min_y() const
ICOORDELT_LIST char_cells
BLOBNBOX_LIST * blob_list()
void set_line(float new_m, float new_c, float new_error)
int num_repeated_sets() const
void clear_rep_chars_marked()
void set_limits(float new_min, float new_max)
float parallel_error() const
void compute_vertical_projection()
void insert_blob(BLOBNBOX *blob)
PITCH_TYPE pitch_decision
void set_parallel_line(float gradient, float new_c, float new_error)
void rotate(const FCOORD &rotation)
BLOBNBOX_LIST small_blobs
BLOBNBOX_LIST large_blobs
BLOBNBOX_LIST noise_blobs
PITCH_TYPE pitch_decision
TDimension y() const
access_function
TDimension bottom() const
void add(int32_t value, int32_t count)
TBOX bounding_box() const