#include "varable.h"
#include "grphics.h"
#include "img.h"
#include "pdblock.h"
#include "crakedge.h"
Go to the source code of this file.
Extract edges from a PDBLK.
t_image | Threshold image | |
block | Block in image | |
page_tr | Corner of page |
Definition at line 55 of file scanedg.cpp.
References free_crackedges(), free_cracks, IMAGE::get_line(), IMAGE::get_xsize(), IMAGELINE::init(), line_edges(), make_margins(), MAXIMAGEWIDTH, NULL, IMAGELINE::pixels, WHITE, and ICOORD::y().
Referenced by get_outlines().
00059 { 00060 UINT8 margin; //margin colour 00061 INT16 x; //line coords 00062 INT16 y; //current line 00063 ICOORD bleft; //bounding box 00064 ICOORD tright; 00065 ICOORD block_bleft; //bounding box 00066 ICOORD block_tright; 00067 int xindex; //index to pixel 00068 BLOCK_LINE_IT line_it = block; //line iterator 00069 IMAGELINE bwline; //thresholded line 00070 //lines in progress 00071 CRACKEDGE *ptrlinemem[MAXIMAGEWIDTH]; 00072 CRACKEDGE **ptrline = ptrlinemem; 00073 00074 if (t_image->get_xsize()+1 > MAXIMAGEWIDTH) { 00075 ptrline = new CRACKEDGE*[t_image->get_xsize()+1]; 00076 } 00077 00078 //block box 00079 block->bounding_box (bleft, tright); 00080 block_bleft = bleft; 00081 block_tright = tright; 00082 for (x = tright.x () - bleft.x (); x >= 0; x--) 00083 ptrline[x] = NULL; //no lines in progress 00084 00085 bwline.init (t_image->get_xsize()); 00086 00087 margin = WHITE; 00088 00089 for (y = tright.y () - 1; y >= bleft.y () - 1; y--) { 00090 if (y >= block_bleft.y () && y < block_tright.y ()) { 00091 t_image->get_line (bleft.x (), y, tright.x () - bleft.x (), &bwline, 00092 0); 00093 make_margins (block, &line_it, bwline.pixels, margin, bleft.x (), 00094 tright.x (), y); 00095 } 00096 else { 00097 x = tright.x () - bleft.x (); 00098 for (xindex = 0; xindex < x; xindex++) 00099 bwline.pixels[xindex] = margin; 00100 } 00101 line_edges (bleft.x (), y, tright.x () - bleft.x (), 00102 margin, bwline.pixels, ptrline); 00103 } 00104 00105 free_crackedges(free_cracks); //really free them 00106 free_cracks = NULL; 00107 if (ptrline != ptrlinemem) { 00108 delete [] ptrline; 00109 } 00110 }
void free_crackedges | ( | CRACKEDGE * | start | ) |
Really free them.
Really free the CRACKEDGEs by giving them back to delete.
Definition at line 554 of file scanedg.cpp.
References CRACKEDGE::next, and NULL.
Referenced by block_edges().
00556 { 00557 CRACKEDGE *current; //current edge to free 00558 CRACKEDGE *next; //next one to free 00559 00560 for (current = start; current != NULL; current = next) { 00561 next = current->next; 00562 delete current; //delete them all 00563 } 00564 }
Horizontal edge.
Create a new horizontal CRACKEDGE and join it to the given edge.
Definition at line 351 of file scanedg.cpp.
References cprintf(), free_cracks, join(), list_rec::next, CRACKEDGE::next, NULL, CRACKEDGE::pos, CRACKEDGE::prev, ICOORD::set_x(), ICOORD::set_y(), CRACKEDGE::stepdir, CRACKEDGE::stepx, CRACKEDGE::stepy, and ICOORD::y().
Referenced by line_edges().
00356 { 00357 CRACKEDGE *newpt; //return value 00358 00359 // check_mem("h_edge",JUSTCHECKS); 00360 if (free_cracks != NULL) { 00361 newpt = free_cracks; 00362 free_cracks = newpt->next; //get one fast 00363 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC) 00364 cprintf("a"); // check under 'e' in ccmain/tessvars.h 00365 #endif 00366 } 00367 else { 00368 newpt = new CRACKEDGE; 00369 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC) 00370 cprintf("b"); // check under 'e' in ccmain/tessvars.h 00371 #endif 00372 } 00373 newpt->pos.set_y (y + 1); //coords of pt 00374 newpt->stepy = 0; //edge is horizontal 00375 00376 if (sign > 0) { 00377 newpt->pos.set_x (x + 1); //start location 00378 newpt->stepx = -1; 00379 newpt->stepdir = 0; 00380 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC) 00381 cprintf("c"); // check under 'e' in ccmain/tessvars.h 00382 #endif 00383 } 00384 else { 00385 newpt->pos.set_x (x); //start location 00386 newpt->stepx = 1; 00387 newpt->stepdir = 2; 00388 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC) 00389 cprintf("d"); // check under 'e' in ccmain/tessvars.h 00390 #endif 00391 } 00392 00393 if (join == NULL) { 00394 newpt->next = newpt; //ptrs to other ends 00395 newpt->prev = newpt; 00396 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC) 00397 cprintf("f"); // check under 'e' in ccmain/tessvars.h 00398 #endif 00399 } 00400 else { 00401 if (newpt->pos.x () + newpt->stepx == join->pos.x () 00402 && newpt->pos.y () == join->pos.y ()) { 00403 newpt->prev = join->prev; //update other ends 00404 newpt->prev->next = newpt; 00405 newpt->next = join; //join up 00406 join->prev = newpt; 00407 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC) 00408 cprintf("g"); // check under 'e' in ccmain/tessvars.h 00409 #endif 00410 } 00411 else { 00412 newpt->next = join->next; //update other ends 00413 newpt->next->prev = newpt; 00414 newpt->prev = join; //join up 00415 join->next = newpt; 00416 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSC) 00417 cprintf("h"); // check under 'e' in ccmain/tessvars.h 00418 #endif 00419 } 00420 } 00421 return newpt; 00422 }
Join edge fragments.
Join two edges together & send the outline for approximation when a closed loop is formed.
Definition at line 510 of file scanedg.cpp.
References complete_edge(), cprintf(), free_cracks, CRACKEDGE::next, CRACKEDGE::pos, CRACKEDGE::prev, CRACKEDGE::stepx, CRACKEDGE::stepy, and ICOORD::y().
Referenced by line_edges().
00513 { 00514 CRACKEDGE *tempedge; //for exchanging 00515 00516 if (edge1->pos.x () + edge1->stepx != edge2->pos.x () 00517 || edge1->pos.y () + edge1->stepy != edge2->pos.y ()) { 00518 tempedge = edge1; 00519 edge1 = edge2; //swap around 00520 edge2 = tempedge; 00521 } 00522 00523 // tprintf("Joining %x=(%d,%d)+(%d,%d)->%x<-%x ", 00524 // edge1,edge1->pos.x(),edge1->pos.y(),edge1->stepx,edge1->stepy, 00525 // edge1->next,edge1->prev); 00526 // tprintf("to %x=(%d,%d)+(%d,%d)->%x<-%x\n", 00527 // edge2,edge2->pos.x(),edge2->pos.y(),edge2->stepx,edge2->stepy, 00528 // edge2->next,edge2->prev); 00529 if (edge1->next == edge2) { 00530 #if defined(TEXT_VERBOSE) && !defined(TV_FOCUSE) 00531 cprintf("c"); // gets a 'e', see ccmain/tessvars.h 00532 #endif 00533 //already closed 00534 complete_edge(edge1); //approximate it 00535 //attach freelist to end 00536 edge1->prev->next = free_cracks; 00537 free_cracks = edge1; //and free list 00538 } 00539 else { 00540 //update opposite ends 00541 edge2->prev->next = edge1->next; 00542 edge1->next->prev = edge2->prev; 00543 edge1->next = edge2; //make joins 00544 edge2->prev = edge1; 00545 } 00546 }
void line_edges | ( | INT16 | x, | |
INT16 | y, | |||
INT16 | xext, | |||
UINT8 | uppercolour, | |||
UINT8 * | bwpos, | |||
CRACKEDGE ** | prevline | |||
) |
Scan for edges.
x | Coord of line start | |
y | Coord of line start | |
xext | Width of line | |
uppercolour | Start of previous line | |
bwpos | Thresholded line | |
prevline | Edges in progress | |
prevline | Edges in progress |
See the glossary under Edge Detection for all the gory details (that used to be here!)
Definition at line 218 of file scanedg.cpp.
References cprintf(), FLIP_COLOUR, h_edge(), join_edges(), NULL, v_edge(), and WHITE_PIX.
Referenced by block_edges().
00225 { 00226 int xpos; //current x coord 00227 int xmax; //max x coord 00228 int colour; //of current pixel 00229 int prevcolour; //of previous pixel 00230 CRACKEDGE *current; //current h edge 00231 CRACKEDGE *newcurrent; //new h edge 00232 00233 #if defined(TEXT_VERBOSE) 00234 #if defined(TV_FOCUSE) 00235 cprintf("\n"); // breaks up copious output into rows 00236 #endif 00237 cprintf("e"); // gets a 'e', see ccmain/tessvars.h 00238 #endif 00239 xmax = x + xext; //max allowable coord 00240 prevcolour = uppercolour; //forced plain margin 00241 current = NULL; //nothing yet 00242 00243 //do each pixel 00244 for (xpos = x; xpos < xmax; xpos++, prevline++) { 00245 colour = *bwpos++; //current pixel 00246 if (*prevline != NULL) { 00247 //changed above 00248 //change colour 00249 uppercolour = FLIP_COLOUR (uppercolour); 00250 if (colour == prevcolour) { 00251 if (colour == uppercolour) { 00252 //finish a line 00253 join_edges(current, *prevline); 00254 current = NULL; //no edge now 00255 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00256 cprintf("C"); // check under 'e' in ccmain/tessvars.h 00257 #endif 00258 } 00259 else { 00260 //new horiz edge 00261 current = h_edge (xpos, y, uppercolour - colour, *prevline); 00262 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00263 cprintf("L"); // check under 'e' in ccmain/tessvars.h 00264 #endif 00265 } 00266 *prevline = NULL; //no change this time 00267 } 00268 else { 00269 if (colour == uppercolour) { 00270 *prevline = v_edge (xpos, y, colour - prevcolour, *prevline); 00271 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00272 cprintf("K"); // check under 'e' in ccmain/tessvars.h 00273 #endif 00274 } 00275 //8 vs 4 connection 00276 else if (colour == WHITE_PIX) { 00277 join_edges(current, *prevline); 00278 current = h_edge (xpos, y, uppercolour - colour, NULL); 00279 *prevline = v_edge (xpos, y, colour - prevcolour, current); 00280 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00281 cprintf("J"); // check under 'e' in ccmain/tessvars.h 00282 #endif 00283 } 00284 else { 00285 newcurrent = h_edge (xpos, y, uppercolour - colour, *prevline); 00286 *prevline = v_edge (xpos, y, colour - prevcolour, current); 00287 current = newcurrent; //right going h edge 00288 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00289 cprintf("H"); // check under 'e' in ccmain/tessvars.h 00290 #endif 00291 } 00292 prevcolour = colour; //remember new colour 00293 } 00294 } 00295 else { 00296 if (colour != prevcolour) { 00297 *prevline = current = 00298 v_edge (xpos, y, colour - prevcolour, current); 00299 prevcolour = colour; 00300 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00301 cprintf("D"); // check under 'e' in ccmain/tessvars.h 00302 #endif 00303 } 00304 if (colour != uppercolour) { 00305 current = h_edge (xpos, y, uppercolour - colour, current); 00306 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00307 cprintf("E"); // check under 'e' in ccmain/tessvars.h 00308 #endif 00309 } 00310 else { 00311 current = NULL; //no edge now 00312 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00313 cprintf("="); // check under 'e' in ccmain/tessvars.h 00314 #endif 00315 } 00316 } 00317 }//for xpos 00318 if (current != NULL) { 00319 //out of block 00320 if (*prevline != NULL) { //got one to join to? 00321 join_edges(current, *prevline); 00322 *prevline = NULL; //tidy now 00323 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00324 cprintf("M"); // check under 'e' in ccmain/tessvars.h 00325 #endif 00326 } 00327 else { 00328 //fake vertical 00329 *prevline = v_edge (xpos, y, FLIP_COLOUR(prevcolour)-prevcolour, current); 00330 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00331 cprintf("N"); // check under 'e' in ccmain/tessvars.h 00332 #endif 00333 } 00334 } 00335 else if (*prevline != NULL) { 00336 //continue fake 00337 *prevline = v_edge (xpos, y, FLIP_COLOUR(prevcolour)-prevcolour, *prevline); 00338 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSE) 00339 cprintf("O"); // check under 'e' in ccmain/tessvars.h 00340 #endif 00341 } 00342 }
void make_margins | ( | PDBLK * | block, | |
BLOCK_LINE_IT * | line_it, | |||
UINT8 * | pixels, | |||
UINT8 | margin, | |||
INT16 | left, | |||
INT16 | right, | |||
INT16 | y | |||
) |
Get a line.
Get an image line and set to margin non-text pixels.
Definition at line 118 of file scanedg.cpp.
References BLOCK_LINE_IT::get_line(), PB_LINE_IT::get_line(), and NULL.
Referenced by block_edges().
00126 { 00127 PB_LINE_IT *lines; 00128 ICOORDELT_LIST *segments; //bits of a line 00129 ICOORDELT_IT seg_it; 00130 INT32 start; //of segment 00131 INT16 xext; //of segment 00132 int xindex; //index to pixel 00133 00134 if (block->poly_block () != NULL) { 00135 lines = new PB_LINE_IT (block->poly_block ()); 00136 segments = lines->get_line (y); 00137 if (!segments->empty ()) { 00138 seg_it.set_to_list (segments); 00139 seg_it.mark_cycle_pt (); 00140 start = seg_it.data ()->x (); 00141 xext = seg_it.data ()->y (); 00142 for (xindex = left; xindex < right; xindex++) { 00143 if (xindex >= start && !seg_it.cycled_list ()) { 00144 xindex = start + xext - 1; 00145 seg_it.forward (); 00146 start = seg_it.data ()->x (); 00147 xext = seg_it.data ()->y (); 00148 } 00149 else 00150 pixels[xindex - left] = margin; 00151 } 00152 } 00153 else { 00154 for (xindex = left; xindex < right; xindex++) 00155 pixels[xindex - left] = margin; 00156 } 00157 delete segments; 00158 delete lines; 00159 } 00160 else { 00161 start = line_it->get_line (y, xext); 00162 for (xindex = left; xindex < start; xindex++) 00163 pixels[xindex - left] = margin; 00164 for (xindex = start + xext; xindex < right; xindex++) 00165 pixels[xindex - left] = margin; 00166 } 00167 }
Vertical edge.
Create a new vertical CRACKEDGE and join it to the given edge.
Definition at line 431 of file scanedg.cpp.
References cprintf(), free_cracks, join(), list_rec::next, CRACKEDGE::next, NULL, CRACKEDGE::pos, CRACKEDGE::prev, ICOORD::set_x(), ICOORD::set_y(), CRACKEDGE::stepdir, CRACKEDGE::stepx, CRACKEDGE::stepy, and ICOORD::y().
Referenced by line_edges().
00436 { 00437 CRACKEDGE *newpt; //return value 00438 00439 if (free_cracks != NULL) { 00440 newpt = free_cracks; 00441 free_cracks = newpt->next; //get one fast 00442 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD) 00443 cprintf("j"); // check under 'e' in ccmain/tessvars.h 00444 #endif 00445 } 00446 else { 00447 newpt = new CRACKEDGE; 00448 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD) 00449 cprintf("k"); // check under 'e' in ccmain/tessvars.h 00450 #endif 00451 } 00452 newpt->pos.set_x (x); //coords of pt 00453 newpt->stepx = 0; //edge is vertical 00454 00455 if (sign > 0) { 00456 newpt->pos.set_y (y); //start location 00457 newpt->stepy = 1; 00458 newpt->stepdir = 3; 00459 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD) 00460 cprintf("l"); // check under 'e' in ccmain/tessvars.h 00461 #endif 00462 } 00463 else { 00464 newpt->pos.set_y (y + 1); //start location 00465 newpt->stepy = -1; 00466 newpt->stepdir = 1; 00467 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD) 00468 cprintf("m"); // check under 'e' in ccmain/tessvars.h 00469 #endif 00470 } 00471 00472 if (join == NULL) { 00473 newpt->next = newpt; //ptrs to other ends 00474 newpt->prev = newpt; 00475 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD) 00476 cprintf("n"); // check under 'e' in ccmain/tessvars.h 00477 #endif 00478 } 00479 else { 00480 if (newpt->pos.x () == join->pos.x () 00481 && newpt->pos.y () + newpt->stepy == join->pos.y ()) { 00482 newpt->prev = join->prev; //update other ends 00483 newpt->prev->next = newpt; 00484 newpt->next = join; //join up 00485 join->prev = newpt; 00486 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD) 00487 cprintf("o"); // check under 'e' in ccmain/tessvars.h 00488 #endif 00489 } 00490 else { 00491 newpt->next = join->next; //update other ends 00492 newpt->next->prev = newpt; 00493 newpt->prev = join; //join up 00494 join->next = newpt; 00495 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSD) 00496 cprintf("p"); // check under 'e' in ccmain/tessvars.h 00497 #endif 00498 } 00499 } 00500 return newpt; 00501 }
Clean it.
Extract edges from a PDBLK.
Definition at line 175 of file scanedg.cpp.
References BOX::bottom(), IMAGE::get_line(), BLOCK_LINE_IT::get_line(), IMAGELINE::pixels, IMAGE::put_line(), and BOX::top().
00178 { 00179 INT16 x; //line coords 00180 INT16 y; //current line 00181 INT16 xext; //line width 00182 int xindex; //index to pixel 00183 UINT8 *dest; //destination pixel 00184 BOX block_box; //bounding box 00185 BLOCK_LINE_IT line_it = block; //line iterator 00186 IMAGELINE bwline; //thresholded line 00187 00188 block_box = block->bounding_box (); 00189 for (y = block_box.bottom (); y < block_box.top (); y++) { 00190 //find line limits 00191 x = line_it.get_line (y, xext); 00192 t_image->get_line (x, y, xext, &bwline, 0); 00193 dest = bwline.pixels; //destination pixel 00194 for (xindex = 0; xindex < xext; xindex++) 00195 *dest++ = 1; 00196 t_image->put_line (x, y, xext, &bwline, 0); 00197 } 00198 }