📄 blobbox.cpp
字号:
return new C_BLOB (&out_list);}/********************************************************************** * box_next * * Compute the bounding box of this blob with merging of x overlaps * but no pre-chopping. * Then move the iterator on to the start of the next blob. **********************************************************************/BOX box_next( //get bounding box BLOBNBOX_IT *it //iterator to blobds ) { BLOBNBOX *blob; //current blob BOX result; //total box blob = it->data (); result = blob->bounding_box (); do { it->forward (); blob = it->data (); if (blob->blob () == NULL && blob->cblob () == NULL) //was pre-chopped result += blob->bounding_box (); } //until next real blob while (blob->blob () == NULL && blob->cblob () == NULL || blob->joined_to_prev ()); return result;}/********************************************************************** * box_next_pre_chopped * * Compute the bounding box of this blob with merging of x overlaps * but WITH pre-chopping. * Then move the iterator on to the start of the next pre-chopped blob. **********************************************************************/BOX box_next_pre_chopped( //get bounding box BLOBNBOX_IT *it //iterator to blobds ) { BLOBNBOX *blob; //current blob BOX result; //total box blob = it->data (); result = blob->bounding_box (); do { it->forward (); blob = it->data (); } //until next real blob while (blob->joined_to_prev ()); return result;}/********************************************************************** * TO_ROW::TO_ROW * * Constructor to make a row from a blob. **********************************************************************/TO_ROW::TO_ROW ( //constructorBLOBNBOX * blob, //first blobfloat top, //corrected topfloat bottom, //of rowfloat row_size //ideal):y_min (bottom), y_max (top), initial_y_min (bottom) { float diff; //in size BLOBNBOX_IT it = &blobs; //list of blobs it.add_to_end (blob); diff = top - bottom - row_size; if (diff > 0) { y_max -= diff / 2; y_min += diff / 2; } //very small object else if ((top - bottom) * 3 < row_size) { diff = row_size / 3 + bottom - top; y_max += diff / 2; y_min -= diff / 2; }}/********************************************************************** * TO_ROW:add_blob * * Add the blob to the end of the row. **********************************************************************/void TO_ROW::add_blob( //constructor BLOBNBOX *blob, //first blob float top, //corrected top float bottom, //of row float row_size //ideal ) { float allowed; //allowed expansion float available; //expansion BLOBNBOX_IT it = &blobs; //list of blobs it.add_to_end (blob); allowed = row_size + y_min - y_max; if (allowed > 0) { available = top > y_max ? top - y_max : 0; if (bottom < y_min) //total available available += y_min - bottom; if (available > 0) { available += available; //do it gradually if (available < allowed) available = allowed; if (bottom < y_min) y_min -= (y_min - bottom) * allowed / available; if (top > y_max) y_max += (top - y_max) * allowed / available; } }}/********************************************************************** * TO_ROW:insert_blob * * Add the blob to the row in the correct position. **********************************************************************/void TO_ROW::insert_blob( //constructor BLOBNBOX *blob //first blob ) { BLOBNBOX_IT it = &blobs; //list of blobs if (it.empty ()) it.add_before_then_move (blob); else { it.mark_cycle_pt (); while (!it.cycled_list () && it.data ()->bounding_box ().left () <= blob->bounding_box ().left ()) it.forward (); if (it.cycled_list ()) it.add_to_end (blob); else it.add_before_stay_put (blob); }}/********************************************************************** * TO_ROW::compute_vertical_projection * * Compute the vertical projection of a TO_ROW from its blobs. **********************************************************************/void TO_ROW::compute_vertical_projection() { //project whole row BOX row_box; //bound of row BLOBNBOX *blob; //current blob BOX blob_box; //bounding box BLOBNBOX_IT blob_it = blob_list (); if (blob_it.empty ()) return; row_box = blob_it.data ()->bounding_box (); for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) row_box += blob_it.data ()->bounding_box (); projection.set_range (row_box.left () - PROJECTION_MARGIN, row_box.right () + PROJECTION_MARGIN); projection_left = row_box.left () - PROJECTION_MARGIN; projection_right = row_box.right () + PROJECTION_MARGIN; for (blob_it.mark_cycle_pt (); !blob_it.cycled_list (); blob_it.forward ()) { blob = blob_it.data (); if (blob->blob () != NULL) vertical_blob_projection (blob->blob (), &projection); else if (blob->cblob () != NULL) vertical_cblob_projection (blob->cblob (), &projection); }}/********************************************************************** * vertical_blob_projection * * Compute the vertical projection of a blob from its outlines * and add to the given STATS. **********************************************************************/void vertical_blob_projection( //project outlines PBLOB *blob, //blob to project STATS *stats //output ) { //outlines of blob OUTLINE_IT out_it = blob->out_list (); for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { vertical_outline_projection (out_it.data (), stats); }}/********************************************************************** * vertical_outline_projection * * Compute the vertical projection of a outline from its outlines * and add to the given STATS. **********************************************************************/void vertical_outline_projection( //project outlines OUTLINE *outline, //outline to project STATS *stats //output ) { POLYPT *polypt; //current point INT32 xcoord; //current pixel coord float end_x; //end of vec POLYPT_IT poly_it = outline->polypts (); OUTLINE_IT out_it = outline->child (); float ymean; //amount to add float width; //amount of x for (poly_it.mark_cycle_pt (); !poly_it.cycled_list (); poly_it.forward ()) { polypt = poly_it.data (); end_x = polypt->pos.x () + polypt->vec.x (); if (polypt->vec.x () > 0) { for (xcoord = (INT32) floor (polypt->pos.x ()); xcoord < end_x; xcoord++) { if (polypt->pos.x () < xcoord) { width = (float) xcoord; ymean = polypt->vec.y () * (xcoord - polypt->pos.x ()) / polypt->vec.x () + polypt->pos.y (); } else { width = polypt->pos.x (); ymean = polypt->pos.y (); } if (end_x > xcoord + 1) { width -= xcoord + 1; ymean += polypt->vec.y () * (xcoord + 1 - polypt->pos.x ()) / polypt->vec.x () + polypt->pos.y (); } else { width -= end_x; ymean += polypt->pos.y () + polypt->vec.y (); } ymean = ymean * width / 2; stats->add (xcoord, (INT32) floor (ymean + 0.5)); } } else if (polypt->vec.x () < 0) { for (xcoord = (INT32) floor (end_x); xcoord < polypt->pos.x (); xcoord++) { if (polypt->pos.x () > xcoord + 1) { width = xcoord + 1.0f; ymean = polypt->vec.y () * (xcoord + 1 - polypt->pos.x ()) / polypt->vec.x () + polypt->pos.y (); } else { width = polypt->pos.x (); ymean = polypt->pos.y (); } if (end_x < xcoord) { width -= xcoord; ymean += polypt->vec.y () * (xcoord - polypt->pos.x ()) / polypt->vec.x () + polypt->pos.y (); } else { width -= end_x; ymean += polypt->pos.y () + polypt->vec.y (); } ymean = ymean * width / 2; stats->add (xcoord, (INT32) floor (ymean + 0.5)); } } } for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { vertical_outline_projection (out_it.data (), stats); }}/********************************************************************** * vertical_cblob_projection * * Compute the vertical projection of a cblob from its outlines * and add to the given STATS. **********************************************************************/void vertical_cblob_projection( //project outlines C_BLOB *blob, //blob to project STATS *stats //output ) { //outlines of blob C_OUTLINE_IT out_it = blob->out_list (); for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { vertical_coutline_projection (out_it.data (), stats); }}/********************************************************************** * vertical_coutline_projection * * Compute the vertical projection of a outline from its outlines * and add to the given STATS. **********************************************************************/void vertical_coutline_projection( //project outlines C_OUTLINE *outline, //outline to project STATS *stats //output ) { ICOORD pos; //current point ICOORD step; //edge step INT32 length; //of outline INT16 stepindex; //current step C_OUTLINE_IT out_it = outline->child (); pos = outline->start_pos (); length = outline->pathlength (); for (stepindex = 0; stepindex < length; stepindex++) { step = outline->step (stepindex); if (step.x () > 0) { if (pitsync_projection_fix) stats->add (pos.x (), -pos.y ()); else stats->add (pos.x (), pos.y ()); } else if (step.x () < 0) { if (pitsync_projection_fix) stats->add (pos.x () - 1, pos.y ()); else stats->add (pos.x () - 1, -pos.y ()); } pos += step; } for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { vertical_coutline_projection (out_it.data (), stats); }}/********************************************************************** * TO_BLOCK::TO_BLOCK * * Constructor to make a TO_BLOCK from a real block. **********************************************************************/TO_BLOCK::TO_BLOCK( //make a block BLOCK *src_block //real block ) { block = src_block;}static void clear_blobnboxes(BLOBNBOX_LIST* boxes) { BLOBNBOX_IT it = boxes; // A BLOBNBOX generally doesn't own its blobs, so if they do, you // have to delete them explicitly. for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) { BLOBNBOX* box = it.data(); if (box->blob() != NULL) delete box->blob(); if (box->cblob() != NULL) delete box->cblob(); }}TO_BLOCK::~TO_BLOCK() { // Any residual BLOBNBOXes at this stage own their blobs, so delete them. clear_blobnboxes(&blobs); clear_blobnboxes(&underlines); clear_blobnboxes(&noise_blobs); clear_blobnboxes(&small_blobs); clear_blobnboxes(&large_blobs);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -