C_BLOB::C_BLOB( //constructor C_OUTLINE_LIST *outline_list //in random order ) { C_OUTLINE *outline; //current outline C_OUTLINE_IT it = outline_list;//iterator while (!it.empty ()) { //grab the list outline = it.extract (); //get off the list //put it in place position_outline(outline, &outlines); if (!it.empty ()) it.forward (); } it.set_to_list (&outlines); for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { outline = it.data (); if (outline->turn_direction () < 0) { outline->reverse (); reverse_outline_list (outline->child ()); outline->set_flag (COUT_INVERSE, TRUE); } else { outline->set_flag (COUT_INVERSE, FALSE); } } }
inT32 C_OUTLINE::area() { //winding number int stepindex; //current step inT32 total_steps; //steps to do inT32 total; //total area ICOORD pos; //position of point ICOORD next_step; //step to next pix C_OUTLINE_IT it = child (); pos = start_pos (); total_steps = pathlength (); total = 0; for (stepindex = 0; stepindex < total_steps; stepindex++) { //all intersected next_step = step (stepindex); if (next_step.x () < 0) total += pos.y (); else if (next_step.x () > 0) total -= pos.y (); pos += next_step; } for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) total += it.data ()->area ();//add areas of children return total; }
/********************************************************************** * position_outline * * Position the outline in the given list at the relevant place * according to its nesting. **********************************************************************/ static void position_outline( //put in place C_OUTLINE *outline, //thing to place C_OUTLINE_LIST *destlist //desstination list ) { C_OUTLINE *dest_outline; //outline from dest list C_OUTLINE_IT it = destlist; //iterator //iterator on children C_OUTLINE_IT child_it = outline->child (); if (!it.empty ()) { do { dest_outline = it.data (); //get destination //encloses dest if (*dest_outline < *outline) { //take off list dest_outline = it.extract (); //put this in place it.add_after_then_move (outline); //make it a child child_it.add_to_end (dest_outline); while (!it.at_last ()) { it.forward (); //do rest of list //check for other children dest_outline = it.data (); if (*dest_outline < *outline) { //take off list dest_outline = it.extract (); child_it.add_to_end (dest_outline); //make it a child if (it.empty ()) break; } } return; //finished } //enclosed by dest else if (*outline < *dest_outline) { position_outline (outline, dest_outline->child ()); //place in child list return; //finished } it.forward (); } while (!it.at_first ()); } it.add_to_end (outline); //at outer level }
inT32 C_OUTLINE::perimeter() { inT32 total_steps; // Return value. C_OUTLINE_IT it = child(); total_steps = pathlength(); for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) total_steps += it.data()->pathlength(); // Add perimeters of children. return total_steps; }
TBOX C_BLOB::bounding_box() { //bounding box C_OUTLINE *outline; //current outline C_OUTLINE_IT it = &outlines; //outlines of blob TBOX box; //bounding box for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { outline = it.data (); box += outline->bounding_box (); } return box; }
inT32 C_BLOB::outer_area() { //area C_OUTLINE *outline; //current outline C_OUTLINE_IT it = &outlines; //outlines of blob inT32 total; //total area total = 0; for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { outline = it.data (); total += outline->outer_area (); } return total; }
inT32 C_BLOB::perimeter() { C_OUTLINE *outline; // current outline C_OUTLINE_IT it = &outlines; // outlines of blob inT32 total; // total perimeter total = 0; for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) { outline = it.data(); total += outline->perimeter(); } return total; }
static void reverse_outline_list( //reverse outlines C_OUTLINE_LIST *list //outline to reverse ) { C_OUTLINE *outline; //current outline C_OUTLINE_IT it = list; //iterator for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { outline = it.data (); outline->reverse (); //reverse it if (!outline->child ()->empty ()) reverse_outline_list (outline->child ()); } }
inT32 C_BLOB::count_transitions( //area inT32 threshold //on size ) { C_OUTLINE *outline; //current outline C_OUTLINE_IT it = &outlines; //outlines of blob inT32 total; //total area total = 0; for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { outline = it.data (); total += outline->count_transitions (threshold); } return total; }
static void plot_outline_list( //draw outlines C_OUTLINE_LIST *list, //outline to draw ScrollView* window, //window to draw in ScrollView::Color colour, //colour to use ScrollView::Color child_colour //colour of children ) { C_OUTLINE *outline; //current outline C_OUTLINE_IT it = list; //iterator for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { outline = it.data (); //draw it outline->plot (window, colour); if (!outline->child ()->empty ()) plot_outline_list (outline->child (), window, child_colour, child_colour); } }
int wpl = pixGetWpl(pix); l_uint32* data = pixGetData(pix); int length = outline->pathlength(); ICOORD pos = outline->start_pos(); for (int i = 0; i < length; ++i) { int grid_x = (pos.x() - bleft.x()) / gridsize - *left; int grid_y = (pos.y() - bleft.y()) / gridsize - *bottom; SET_DATA_BIT(data + grid_y * wpl, grid_x); pos += outline->step(i); } return pix; } #if 0 // Example code shows how to use TraceOutlineOnReducedPix. C_OUTLINE_IT ol_it(blob->cblob()->out_list()); int grid_left, grid_bottom; Pix* pix = TraceOutlineOnReducedPix(ol_it.data(), gridsize_, bleft_, &grid_left, &grid_bottom); grid->InsertPixPtBBox(grid_left, grid_bottom, pix, blob); pixDestroy(&pix); #endif // As TraceOutlineOnReducedPix above, but on a BLOCK instead of a C_OUTLINE. Pix* TraceBlockOnReducedPix(BLOCK* block, int gridsize, ICOORD bleft, int* left, int* bottom) { TBOX box = block->bounding_box(); Pix* pix = GridReducedPix(box, gridsize, bleft, left, bottom); int wpl = pixGetWpl(pix); l_uint32* data = pixGetData(pix); ICOORDELT_IT it(block->poly_block()->points()); for (it.mark_cycle_pt(); !it.cycled_list();) { ICOORD pos = *it.data();