本文整理汇总了C++中WERD::cblob_list方法的典型用法代码示例。如果您正苦于以下问题:C++ WERD::cblob_list方法的具体用法?C++ WERD::cblob_list怎么用?C++ WERD::cblob_list使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类WERD
的用法示例。
在下文中一共展示了WERD::cblob_list方法的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: clean_small_noise_from_words
// Remove outlines that are a tiny fraction in either width or height
// of the word height.
void Textord::clean_small_noise_from_words(ROW *row) {
WERD_IT word_it(row->word_list());
for (word_it.mark_cycle_pt(); !word_it.cycled_list(); word_it.forward()) {
WERD* word = word_it.data();
int min_size = static_cast<int>(
textord_noise_hfract * word->bounding_box().height() + 0.5);
C_BLOB_IT blob_it(word->cblob_list());
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
C_BLOB* blob = blob_it.data();
C_OUTLINE_IT out_it(blob->out_list());
for (out_it.mark_cycle_pt(); !out_it.cycled_list(); out_it.forward()) {
C_OUTLINE* outline = out_it.data();
outline->RemoveSmallRecursive(min_size, &out_it);
}
if (blob->out_list()->empty()) {
delete blob_it.extract();
}
}
if (word->cblob_list()->empty()) {
if (!word_it.at_last()) {
// The next word is no longer a fuzzy non space if it was before,
// since the word before is about to be deleted.
WERD* next_word = word_it.data_relative(1);
if (next_word->flag(W_FUZZY_NON)) {
next_word->set_flag(W_FUZZY_NON, false);
}
}
delete word_it.extract();
}
}
}
示例2: PrintSegmentationStats
void PrintSegmentationStats(BLOCK_LIST* block_list) {
int num_blocks = 0;
int num_rows = 0;
int num_words = 0;
int num_blobs = 0;
BLOCK_IT block_it(block_list);
for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
BLOCK* block = block_it.data();
++num_blocks;
ROW_IT row_it(block->row_list());
for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
++num_rows;
ROW* row = row_it.data();
// Iterate over all werds in the row.
WERD_IT werd_it(row->word_list());
for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
WERD* werd = werd_it.data();
++num_words;
num_blobs += werd->cblob_list()->length();
}
}
}
tprintf("Block list stats:\nBlocks = %d\nRows = %d\nWords = %d\nBlobs = %d\n",
num_blocks, num_rows, num_words, num_blobs);
}
示例3: SetupApplyBoxes
/// Builds a PAGE_RES from the block_list in the way required for ApplyBoxes:
/// All fuzzy spaces are removed, and all the words are maximally chopped.
PAGE_RES* Tesseract::SetupApplyBoxes(const GenericVector<TBOX>& boxes,
BLOCK_LIST *block_list) {
PreenXHeights(block_list);
// Strip all fuzzy space markers to simplify the PAGE_RES.
BLOCK_IT b_it(block_list);
for (b_it.mark_cycle_pt(); !b_it.cycled_list(); b_it.forward()) {
BLOCK* block = b_it.data();
ROW_IT r_it(block->row_list());
for (r_it.mark_cycle_pt(); !r_it.cycled_list(); r_it.forward ()) {
ROW* row = r_it.data();
WERD_IT w_it(row->word_list());
for (w_it.mark_cycle_pt(); !w_it.cycled_list(); w_it.forward()) {
WERD* word = w_it.data();
if (word->cblob_list()->empty()) {
delete w_it.extract();
} else {
word->set_flag(W_FUZZY_SP, false);
word->set_flag(W_FUZZY_NON, false);
}
}
}
}
PAGE_RES* page_res = new PAGE_RES(false, block_list, NULL);
PAGE_RES_IT pr_it(page_res);
WERD_RES* word_res;
while ((word_res = pr_it.word()) != NULL) {
MaximallyChopWord(boxes, pr_it.block()->block,
pr_it.row()->row, word_res);
pr_it.forward();
}
return page_res;
}
示例4: make_pseudo_word
PAGE_RES_IT* make_pseudo_word(PAGE_RES* page_res, const TBOX& selection_box) {
PAGE_RES_IT pr_it(page_res);
C_BLOB_LIST new_blobs; // list of gathered blobs
C_BLOB_IT new_blob_it = &new_blobs; // iterator
for (WERD_RES* word_res = pr_it.word(); word_res != NULL;
word_res = pr_it.forward()) {
WERD* word = word_res->word;
if (word->bounding_box().overlap(selection_box)) {
C_BLOB_IT blob_it(word->cblob_list());
for (blob_it.mark_cycle_pt();
!blob_it.cycled_list(); blob_it.forward()) {
C_BLOB* blob = blob_it.data();
if (blob->bounding_box().overlap(selection_box)) {
new_blob_it.add_after_then_move(C_BLOB::deep_copy(blob));
}
}
if (!new_blobs.empty()) {
WERD* pseudo_word = new WERD(&new_blobs, 1, NULL);
word_res = pr_it.InsertSimpleCloneWord(*word_res, pseudo_word);
PAGE_RES_IT* it = new PAGE_RES_IT(page_res);
while (it->word() != word_res && it->word() != NULL) it->forward();
ASSERT_HOST(it->word() == word_res);
return it;
}
}
}
return NULL;
}
示例5: ExtractBlobsFromSegmentation
void ExtractBlobsFromSegmentation(BLOCK_LIST* blocks,
C_BLOB_LIST* output_blob_list) {
C_BLOB_IT return_list_it(output_blob_list);
BLOCK_IT block_it(blocks);
for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
BLOCK* block = block_it.data();
ROW_IT row_it(block->row_list());
for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
ROW* row = row_it.data();
// Iterate over all werds in the row.
WERD_IT werd_it(row->word_list());
for (werd_it.mark_cycle_pt(); !werd_it.cycled_list(); werd_it.forward()) {
WERD* werd = werd_it.data();
return_list_it.move_to_last();
return_list_it.add_list_after(werd->cblob_list());
return_list_it.move_to_last();
return_list_it.add_list_after(werd->rej_cblob_list());
}
}
}
}
示例6: cleanup_nontext_block
// Fixes the block so it obeys all the rules:
// Must have at least one ROW.
// Must have at least one WERD.
// WERDs contain a fake blob.
void Textord::cleanup_nontext_block(BLOCK* block) {
// Non-text blocks must contain at least one row.
ROW_IT row_it(block->row_list());
if (row_it.empty()) {
const TBOX& box = block->pdblk.bounding_box();
float height = box.height();
int32_t xstarts[2] = {box.left(), box.right()};
double coeffs[3] = {0.0, 0.0, static_cast<double>(box.bottom())};
ROW* row = new ROW(1, xstarts, coeffs, height / 2.0f, height / 4.0f,
height / 4.0f, 0, 1);
row_it.add_after_then_move(row);
}
// Each row must contain at least one word.
for (row_it.mark_cycle_pt(); !row_it.cycled_list(); row_it.forward()) {
ROW* row = row_it.data();
WERD_IT w_it(row->word_list());
if (w_it.empty()) {
// Make a fake blob to put in the word.
TBOX box = block->row_list()->singleton() ? block->pdblk.bounding_box()
: row->bounding_box();
C_BLOB* blob = C_BLOB::FakeBlob(box);
C_BLOB_LIST blobs;
C_BLOB_IT blob_it(&blobs);
blob_it.add_after_then_move(blob);
WERD* word = new WERD(&blobs, 0, nullptr);
w_it.add_after_then_move(word);
}
// Each word must contain a fake blob.
for (w_it.mark_cycle_pt(); !w_it.cycled_list(); w_it.forward()) {
WERD* word = w_it.data();
// Just assert that this is true, as it would be useful to find
// out why it isn't.
ASSERT_HOST(!word->cblob_list()->empty());
}
row->recalc_bounding_box();
}
}
示例7: word_display
/**
* word_display() Word Processor
*
* Display a word according to its display modes
*/
BOOL8 Tesseract::word_display(BLOCK* block, ROW* row, WERD_RES* word_res) {
WERD* word = word_res->word;
TBOX word_bb; // word bounding box
int word_height; // ht of word BB
BOOL8 displayed_something = FALSE;
float shift; // from bot left
C_BLOB_IT c_it; // cblob iterator
if (color_mode != CM_RAINBOW && word_res->box_word != NULL) {
BoxWord* box_word = word_res->box_word;
int length = box_word->length();
if (word_res->fontinfo == NULL) return false;
const FontInfo& font_info = *word_res->fontinfo;
for (int i = 0; i < length; ++i) {
ScrollView::Color color = ScrollView::GREEN;
switch (color_mode) {
case CM_SUBSCRIPT:
if (box_word->BlobPosition(i) == SP_SUBSCRIPT)
color = ScrollView::RED;
break;
case CM_SUPERSCRIPT:
if (box_word->BlobPosition(i) == SP_SUPERSCRIPT)
color = ScrollView::RED;
break;
case CM_ITALIC:
if (font_info.is_italic())
color = ScrollView::RED;
break;
case CM_BOLD:
if (font_info.is_bold())
color = ScrollView::RED;
break;
case CM_FIXEDPITCH:
if (font_info.is_fixed_pitch())
color = ScrollView::RED;
break;
case CM_SERIF:
if (font_info.is_serif())
color = ScrollView::RED;
break;
case CM_SMALLCAPS:
if (word_res->small_caps)
color = ScrollView::RED;
break;
case CM_DROPCAPS:
if (box_word->BlobPosition(i) == SP_DROPCAP)
color = ScrollView::RED;
break;
// TODO(rays) underline is currently completely unsupported.
case CM_UNDERLINE:
default:
break;
}
image_win->Pen(color);
TBOX box = box_word->BlobBox(i);
image_win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
}
return true;
}
/*
Note the double coercions of(COLOUR)((inT32)editor_image_word_bb_color)
etc. are to keep the compiler happy.
*/
// display bounding box
if (word->display_flag(DF_BOX)) {
word->bounding_box().plot(image_win,
(ScrollView::Color)((inT32)
editor_image_word_bb_color),
(ScrollView::Color)((inT32)
editor_image_word_bb_color));
ScrollView::Color c = (ScrollView::Color)
((inT32) editor_image_blob_bb_color);
image_win->Pen(c);
c_it.set_to_list(word->cblob_list());
for (c_it.mark_cycle_pt(); !c_it.cycled_list(); c_it.forward())
c_it.data()->bounding_box().plot(image_win);
displayed_something = TRUE;
}
// display edge steps
if (word->display_flag(DF_EDGE_STEP)) { // edgesteps available
word->plot(image_win); // rainbow colors
displayed_something = TRUE;
}
// display poly approx
if (word->display_flag(DF_POLYGONAL)) {
// need to convert
TWERD* tword = TWERD::PolygonalCopy(word);
tword->plot(image_win);
delete tword;
displayed_something = TRUE;
}
//.........这里部分代码省略.........
示例8: clean_noise_from_words
void Textord::clean_noise_from_words( //remove empties
ROW *row //row to clean
) {
TBOX blob_box; //bounding box
C_BLOB *blob; //current blob
C_OUTLINE *outline; //current outline
WERD *word; //current word
int32_t blob_size; //biggest size
int32_t trans_count; //no of transitions
int32_t trans_threshold; //noise tolerance
int32_t dot_count; //small objects
int32_t norm_count; //normal objects
int32_t dud_words; //number discarded
int32_t ok_words; //number remaining
int32_t word_index; //current word
//words of row
WERD_IT word_it = row->word_list ();
C_BLOB_IT blob_it; //blob iterator
C_OUTLINE_IT out_it; //outline iterator
ok_words = word_it.length ();
if (ok_words == 0 || textord_no_rejects)
return;
// was it chucked
std::vector<int8_t> word_dud(ok_words);
dud_words = 0;
ok_words = 0;
word_index = 0;
for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
word = word_it.data (); //current word
dot_count = 0;
norm_count = 0;
//blobs in word
blob_it.set_to_list (word->cblob_list ());
for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
blob_it.forward ()) {
blob = blob_it.data ();
if (!word->flag (W_DONT_CHOP)) {
//get outlines
out_it.set_to_list (blob->out_list ());
for (out_it.mark_cycle_pt (); !out_it.cycled_list ();
out_it.forward ()) {
outline = out_it.data ();
blob_box = outline->bounding_box ();
blob_size =
blob_box.width () >
blob_box.height ()? blob_box.width () : blob_box.
height();
if (blob_size < textord_noise_sizelimit * row->x_height ())
dot_count++; //count smal outlines
if (!outline->child ()->empty ()
&& blob_box.height () <
(1 + textord_noise_syfract) * row->x_height ()
&& blob_box.height () >
(1 - textord_noise_syfract) * row->x_height ()
&& blob_box.width () <
(1 + textord_noise_sxfract) * row->x_height ()
&& blob_box.width () >
(1 - textord_noise_sxfract) * row->x_height ())
norm_count++; //count smal outlines
}
}
else
norm_count++;
blob_box = blob->bounding_box ();
blob_size =
blob_box.width () >
blob_box.height ()? blob_box.width () : blob_box.height ();
if (blob_size >= textord_noise_sizelimit * row->x_height ()
&& blob_size < row->x_height () * 2) {
trans_threshold = blob_size / textord_noise_sizefraction;
trans_count = blob->count_transitions (trans_threshold);
if (trans_count < textord_noise_translimit)
norm_count++;
}
else if (blob_box.height () > row->x_height () * 2
&& (!word_it.at_first () || !blob_it.at_first ()))
dot_count += 2;
}
if (dot_count > 2 && !word->flag(W_REP_CHAR)) {
if (dot_count > norm_count * textord_noise_normratio * 2)
word_dud[word_index] = 2;
else if (dot_count > norm_count * textord_noise_normratio)
word_dud[word_index] = 1;
else
word_dud[word_index] = 0;
} else {
word_dud[word_index] = 0;
}
if (word_dud[word_index] == 2)
dud_words++;
else
ok_words++;
word_index++;
}
word_index = 0;
for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
if (word_dud[word_index] == 2
|| (word_dud[word_index] == 1 && dud_words > ok_words)) {
//.........这里部分代码省略.........
示例9: clean_noise_from_row
bool Textord::clean_noise_from_row( //remove empties
ROW* row //row to clean
) {
bool testing_on;
TBOX blob_box; //bounding box
C_BLOB *blob; //current blob
C_OUTLINE *outline; //current outline
WERD *word; //current word
int32_t blob_size; //biggest size
int32_t trans_count = 0; //no of transitions
int32_t trans_threshold; //noise tolerance
int32_t dot_count; //small objects
int32_t norm_count; //normal objects
int32_t super_norm_count; //real char-like
//words of row
WERD_IT word_it = row->word_list ();
C_BLOB_IT blob_it; //blob iterator
C_OUTLINE_IT out_it; //outline iterator
testing_on = textord_test_y > row->base_line (textord_test_x)
&& textord_show_blobs
&& textord_test_y < row->base_line (textord_test_x) + row->x_height ();
dot_count = 0;
norm_count = 0;
super_norm_count = 0;
for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
word = word_it.data (); //current word
//blobs in word
blob_it.set_to_list (word->cblob_list ());
for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
blob_it.forward ()) {
blob = blob_it.data ();
if (!word->flag (W_DONT_CHOP)) {
//get outlines
out_it.set_to_list (blob->out_list ());
for (out_it.mark_cycle_pt (); !out_it.cycled_list ();
out_it.forward ()) {
outline = out_it.data ();
blob_box = outline->bounding_box ();
blob_size =
blob_box.width () >
blob_box.height ()? blob_box.width () : blob_box.
height();
if (blob_size < textord_noise_sizelimit * row->x_height ())
dot_count++; //count smal outlines
if (!outline->child ()->empty ()
&& blob_box.height () <
(1 + textord_noise_syfract) * row->x_height ()
&& blob_box.height () >
(1 - textord_noise_syfract) * row->x_height ()
&& blob_box.width () <
(1 + textord_noise_sxfract) * row->x_height ()
&& blob_box.width () >
(1 - textord_noise_sxfract) * row->x_height ())
super_norm_count++; //count smal outlines
}
}
else
super_norm_count++;
blob_box = blob->bounding_box ();
blob_size =
blob_box.width () >
blob_box.height ()? blob_box.width () : blob_box.height ();
if (blob_size >= textord_noise_sizelimit * row->x_height ()
&& blob_size < row->x_height () * 2) {
trans_threshold = blob_size / textord_noise_sizefraction;
trans_count = blob->count_transitions (trans_threshold);
if (trans_count < textord_noise_translimit)
norm_count++;
}
else if (blob_box.height () > row->x_height () * 2
&& (!word_it.at_first () || !blob_it.at_first ()))
dot_count += 2;
if (testing_on) {
tprintf
("Blob at (%d,%d) -> (%d,%d), ols=%d, tc=%d, bldiff=%g\n",
blob_box.left (), blob_box.bottom (), blob_box.right (),
blob_box.top (), blob->out_list ()->length (), trans_count,
blob_box.bottom () - row->base_line (blob_box.left ()));
}
}
}
if (textord_noise_debug) {
tprintf ("Row ending at (%d,%g):",
blob_box.right (), row->base_line (blob_box.right ()));
tprintf (" R=%g, dc=%d, nc=%d, %s\n",
norm_count > 0 ? (float) dot_count / norm_count : 9999,
dot_count, norm_count,
dot_count > norm_count * textord_noise_normratio
&& dot_count > 2 ? "REJECTED" : "ACCEPTED");
}
return super_norm_count < textord_noise_sncount
&& dot_count > norm_count * textord_noise_rowratio && dot_count > 2;
}
示例10: ResegmentWordBox
/// Consume all source blobs that strongly overlap the given box,
/// putting them into a new word, with the correct_text label.
/// Fights over which box owns which blobs are settled by
/// applying the blobs to box or next_box with the least non-overlap.
/// @return false if the box was in error, which can only be caused by
/// failing to find an overlapping blob for a box.
bool Tesseract::ResegmentWordBox(BLOCK_LIST *block_list,
const TBOX& box, const TBOX& next_box,
const char* correct_text) {
if (applybox_debug > 1) {
tprintf("\nAPPLY_BOX: in ResegmentWordBox() for %s\n", correct_text);
}
WERD* new_word = NULL;
BLOCK_IT b_it(block_list);
for (b_it.mark_cycle_pt(); !b_it.cycled_list(); b_it.forward()) {
BLOCK* block = b_it.data();
if (!box.major_overlap(block->bounding_box()))
continue;
ROW_IT r_it(block->row_list());
for (r_it.mark_cycle_pt(); !r_it.cycled_list(); r_it.forward()) {
ROW* row = r_it.data();
if (!box.major_overlap(row->bounding_box()))
continue;
WERD_IT w_it(row->word_list());
for (w_it.mark_cycle_pt(); !w_it.cycled_list(); w_it.forward()) {
WERD* word = w_it.data();
if (applybox_debug > 2) {
tprintf("Checking word:");
word->bounding_box().print();
}
if (word->text() != NULL && word->text()[0] != '\0')
continue; // Ignore words that are already done.
if (!box.major_overlap(word->bounding_box()))
continue;
C_BLOB_IT blob_it(word->cblob_list());
for (blob_it.mark_cycle_pt(); !blob_it.cycled_list();
blob_it.forward()) {
C_BLOB* blob = blob_it.data();
TBOX blob_box = blob->bounding_box();
if (!blob_box.major_overlap(box))
continue;
double current_box_miss_metric = BoxMissMetric(blob_box, box);
double next_box_miss_metric = BoxMissMetric(blob_box, next_box);
if (applybox_debug > 2) {
tprintf("Checking blob:");
blob_box.print();
tprintf("Current miss metric = %g, next = %g\n",
current_box_miss_metric, next_box_miss_metric);
}
if (current_box_miss_metric > next_box_miss_metric)
continue; // Blob is a better match for next box.
if (applybox_debug > 2) {
tprintf("Blob match: blob:");
blob_box.print();
tprintf("Matches box:");
box.print();
tprintf("With next box:");
next_box.print();
}
if (new_word == NULL) {
// Make a new word with a single blob.
new_word = word->shallow_copy();
new_word->set_text(correct_text);
w_it.add_to_end(new_word);
}
C_BLOB_IT new_blob_it(new_word->cblob_list());
new_blob_it.add_to_end(blob_it.extract());
}
}
}
}
if (new_word == NULL && applybox_debug > 0) tprintf("FAIL!\n");
return new_word != NULL;
}
示例11: tweak_row_baseline
void tweak_row_baseline(ROW *row,
double blshift_maxshift,
double blshift_xfraction) {
TBOX blob_box; //bounding box
C_BLOB *blob; //current blob
WERD *word; //current word
inT32 blob_count; //no of blobs
inT32 src_index; //source segment
inT32 dest_index; //destination segment
inT32 *xstarts; //spline segments
double *coeffs; //spline coeffs
float ydiff; //baseline error
float x_centre; //centre of blob
//words of row
WERD_IT word_it = row->word_list ();
C_BLOB_IT blob_it; //blob iterator
blob_count = 0;
for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
word = word_it.data (); //current word
//get total blobs
blob_count += word->cblob_list ()->length ();
}
if (blob_count == 0)
return;
xstarts =
(inT32 *) alloc_mem ((blob_count + row->baseline.segments + 1) *
sizeof (inT32));
coeffs =
(double *) alloc_mem ((blob_count + row->baseline.segments) * 3 *
sizeof (double));
src_index = 0;
dest_index = 0;
xstarts[0] = row->baseline.xcoords[0];
for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
word = word_it.data (); //current word
//blobs in word
blob_it.set_to_list (word->cblob_list ());
for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
blob_it.forward ()) {
blob = blob_it.data ();
blob_box = blob->bounding_box ();
x_centre = (blob_box.left () + blob_box.right ()) / 2.0;
ydiff = blob_box.bottom () - row->base_line (x_centre);
if (ydiff < 0)
ydiff = -ydiff / row->x_height ();
else
ydiff = ydiff / row->x_height ();
if (ydiff < blshift_maxshift
&& blob_box.height () / row->x_height () > blshift_xfraction) {
if (xstarts[dest_index] >= x_centre)
xstarts[dest_index] = blob_box.left ();
coeffs[dest_index * 3] = 0;
coeffs[dest_index * 3 + 1] = 0;
coeffs[dest_index * 3 + 2] = blob_box.bottom ();
//shift it
dest_index++;
xstarts[dest_index] = blob_box.right () + 1;
}
else {
if (xstarts[dest_index] <= x_centre) {
while (row->baseline.xcoords[src_index + 1] <= x_centre
&& src_index < row->baseline.segments - 1) {
if (row->baseline.xcoords[src_index + 1] >
xstarts[dest_index]) {
coeffs[dest_index * 3] =
row->baseline.quadratics[src_index].a;
coeffs[dest_index * 3 + 1] =
row->baseline.quadratics[src_index].b;
coeffs[dest_index * 3 + 2] =
row->baseline.quadratics[src_index].c;
dest_index++;
xstarts[dest_index] =
row->baseline.xcoords[src_index + 1];
}
src_index++;
}
coeffs[dest_index * 3] =
row->baseline.quadratics[src_index].a;
coeffs[dest_index * 3 + 1] =
row->baseline.quadratics[src_index].b;
coeffs[dest_index * 3 + 2] =
row->baseline.quadratics[src_index].c;
dest_index++;
xstarts[dest_index] = row->baseline.xcoords[src_index + 1];
}
}
}
}
while (src_index < row->baseline.segments
&& row->baseline.xcoords[src_index + 1] <= xstarts[dest_index])
src_index++;
while (src_index < row->baseline.segments) {
coeffs[dest_index * 3] = row->baseline.quadratics[src_index].a;
coeffs[dest_index * 3 + 1] = row->baseline.quadratics[src_index].b;
coeffs[dest_index * 3 + 2] = row->baseline.quadratics[src_index].c;
dest_index++;
src_index++;
xstarts[dest_index] = row->baseline.xcoords[src_index];
//.........这里部分代码省略.........
示例12: clean_noise_from_words
void Textord::clean_noise_from_words( //remove empties
ROW *row //row to clean
) {
TBOX blob_box; //bounding box
inT8 *word_dud; //was it chucked
C_BLOB *blob; //current blob
C_OUTLINE *outline; //current outline
WERD *word; //current word
inT32 blob_size; //biggest size
inT32 trans_count; //no of transitions
inT32 trans_threshold; //noise tolerance
inT32 dot_count; //small objects
inT32 norm_count; //normal objects
inT32 dud_words; //number discarded
inT32 ok_words; //number remaining
inT32 word_index; //current word
//words of row
WERD_IT word_it = row->word_list ();
C_BLOB_IT blob_it; //blob iterator
C_OUTLINE_IT out_it; //outline iterator
ok_words = word_it.length ();
if (ok_words == 0 || textord_no_rejects)
return;
word_dud = (inT8 *) alloc_mem (ok_words * sizeof (inT8));
dud_words = 0;
ok_words = 0;
word_index = 0;
for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
word = word_it.data (); //current word
dot_count = 0;
norm_count = 0;
//blobs in word
blob_it.set_to_list (word->cblob_list ());
for (blob_it.mark_cycle_pt (); !blob_it.cycled_list ();
blob_it.forward ()) {
blob = blob_it.data ();
if (!word->flag (W_DONT_CHOP)) {
//get outlines
out_it.set_to_list (blob->out_list ());
for (out_it.mark_cycle_pt (); !out_it.cycled_list ();
out_it.forward ()) {
outline = out_it.data ();
blob_box = outline->bounding_box ();
blob_size =
blob_box.width () >
blob_box.height ()? blob_box.width () : blob_box.
height();
if (blob_size < textord_noise_sizelimit * row->x_height ())
dot_count++; //count smal outlines
if (!outline->child ()->empty ()
&& blob_box.height () <
(1 + textord_noise_syfract) * row->x_height ()
&& blob_box.height () >
(1 - textord_noise_syfract) * row->x_height ()
&& blob_box.width () <
(1 + textord_noise_sxfract) * row->x_height ()
&& blob_box.width () >
(1 - textord_noise_sxfract) * row->x_height ())
norm_count++; //count smal outlines
}
}
else
norm_count++;
blob_box = blob->bounding_box ();
blob_size =
blob_box.width () >
blob_box.height ()? blob_box.width () : blob_box.height ();
if (blob_size >= textord_noise_sizelimit * row->x_height ()
&& blob_size < row->x_height () * 2) {
trans_threshold = blob_size / textord_noise_sizefraction;
trans_count = blob->count_transitions (trans_threshold);
if (trans_count < textord_noise_translimit)
norm_count++;
}
else if (blob_box.height () > row->x_height () * 2
&& (!word_it.at_first () || !blob_it.at_first ()))
dot_count += 2;
}
if (dot_count > 2) {
if (dot_count > norm_count * textord_noise_normratio * 2)
word_dud[word_index] = 2;
else if (dot_count > norm_count * textord_noise_normratio)
word_dud[word_index] = 1;
else
word_dud[word_index] = 0;
}
else
word_dud[word_index] = 0;
if (word_dud[word_index] == 2)
dud_words++;
else
ok_words++;
word_index++;
}
word_index = 0;
for (word_it.mark_cycle_pt (); !word_it.cycled_list (); word_it.forward ()) {
if (word_dud[word_index] == 2
|| (word_dud[word_index] == 1 && dud_words > ok_words)) {
//.........这里部分代码省略.........