📄 edgblob.cpp
字号:
BOX olbox; C_OUTLINE_IT child_it; //search iterator olbox = outline->bounding_box (); xmin = (olbox.left () - bl.x ()) / BUCKETSIZE; xmax = (olbox.right () - bl.x ()) / BUCKETSIZE; ymin = (olbox.bottom () - bl.y ()) / BUCKETSIZE; ymax = (olbox.top () - bl.y ()) / BUCKETSIZE; for (yindex = ymin; yindex <= ymax; yindex++) { for (xindex = xmin; xindex <= xmax; xindex++) { child_it.set_to_list (&buckets[yindex * bxdim + xindex]); for (child_it.mark_cycle_pt (); !child_it.cycled_list (); child_it.forward ()) { if (*child_it.data () < *outline) { it->add_after_then_move (child_it.extract ()); } } } }}/********************************************************************** * extract_edges * * Run the edge detector over the block and return a list of blobs. **********************************************************************/void extract_edges( //find blobs#ifndef GRAPHICS_DISABLED WINDOW window, //window for output#endif IMAGE *image, //image to scan IMAGE *t_image, //thresholded image ICOORD page_tr, //corner of page BLOCK *block //block to scan ) { ICOORD bleft; //block box ICOORD tright; C_OUTLINE_LIST outlines; //outlines in block //iterator C_OUTLINE_IT out_it = &outlines;#ifndef GRAPHICS_DISABLED get_outlines (window, image, t_image, page_tr, (PDBLK *) block, &out_it);#else get_outlines (image, t_image, page_tr, (PDBLK *) block, &out_it);#endif //block box block->bounding_box (bleft, tright); //make blobs outlines_to_blobs(block, bleft, tright, &outlines); }/********************************************************************** * outlines_to_blobs * * Gather together outlines into blobs using the usual bucket sort. **********************************************************************/void outlines_to_blobs( //find blobs BLOCK *block, //block to scan ICOORD bleft, //block box //outlines in block ICOORD tright, C_OUTLINE_LIST *outlines) { //make buckets OL_BUCKETS buckets(bleft, tright); fill_buckets(outlines, &buckets); empty_buckets(block, &buckets); }/********************************************************************** * fill_buckets * * Run the edge detector over the block and return a list of blobs. **********************************************************************/void fill_buckets( //find blobs C_OUTLINE_LIST *outlines, //outlines in block OL_BUCKETS *buckets //output buckets ) { BOX ol_box; //outline box C_OUTLINE_IT out_it = outlines;//iterator C_OUTLINE_IT bucket_it; //iterator in bucket C_OUTLINE *outline; //current outline for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) { outline = out_it.extract (); //take off list //get box ol_box = outline->bounding_box (); bucket_it.set_to_list ((*buckets) (ol_box.left (), ol_box.bottom ())); bucket_it.add_to_end (outline); }}/********************************************************************** * empty_buckets * * Run the edge detector over the block and return a list of blobs. **********************************************************************/void empty_buckets( //find blobs BLOCK *block, //block to scan OL_BUCKETS *buckets //output buckets ) { BOOL8 good_blob; //healthy blob C_OUTLINE_LIST outlines; //outlines in block //iterator C_OUTLINE_IT out_it = &outlines; C_OUTLINE_IT bucket_it = buckets->start_scan (); C_OUTLINE_IT parent_it; //parent outline C_BLOB *blob; //new blob C_BLOB_IT good_blobs = block->blob_list (); C_BLOB_IT junk_blobs = block->reject_blobs (); while (!bucket_it.empty ()) { out_it.set_to_list (&outlines); do { parent_it = bucket_it; //find outermost do bucket_it.forward (); while (!bucket_it.at_first () && !(*parent_it.data () < *bucket_it.data ())); } while (!bucket_it.at_first ()); //move to new list out_it.add_after_then_move (parent_it.extract ()); good_blob = capture_children (buckets, &junk_blobs, &out_it); blob = new C_BLOB (&outlines); if (good_blob) good_blobs.add_after_then_move (blob); else junk_blobs.add_after_then_move (blob); bucket_it.set_to_list (buckets->scan_next ()); }}/********************************************************************** * capture_children * * Find all neighbouring outlines that are children of this outline * and either move them to the output list or declare this outline * illegal and return FALSE. **********************************************************************/BOOL8 capture_children( //find children OL_BUCKETS *buckets, //bucket sort clanss C_BLOB_IT *reject_it, //dead grandchildren C_OUTLINE_IT *blob_it //output outlines ) { BOOL8 anydone; //anything canned C_OUTLINE *outline; //master outline C_OUTLINE *child; //child under test C_OUTLINE_IT test_it; //for grandchildren INT32 child_count; //no of children C_BLOB *blob; //reject C_OUTLINE_LIST r_list; //rejects C_OUTLINE_IT r_it; //iterator outline = blob_it->data (); child_count = buckets->count_children (outline, edges_children_count_limit); if (child_count > edges_children_count_limit) return FALSE; if (child_count == 0) return TRUE; //get single level buckets->extract_children (outline, blob_it); if (child_count == 1) return TRUE; do { anydone = FALSE; blob_it->move_to_first (); for (blob_it->mark_cycle_pt (); !blob_it->cycled_list (); blob_it->forward ()) { child = blob_it->data (); if (child != outline) { for (test_it = *blob_it, test_it.mark_cycle_pt (); !test_it.cycled_list (); test_it.forward ()) { if (test_it.data () != child && *test_it.data () < *child) { r_it.set_to_list (&r_list); r_it.add_after_then_move (test_it.extract ()); //turn to blob blob = new C_BLOB (&r_list); reject_it->add_after_then_move (blob); anydone = TRUE; } } if (anydone) break; //got to reatart } } } while (anydone); //got to restart return TRUE;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -