textord/scanedg.h File Reference

#include "varable.h"
#include "grphics.h"
#include "img.h"
#include "pdblock.h"
#include "crakedge.h"

Go to the source code of this file.

Functions


Function Documentation

DLLSYM void block_edges ( IMAGE t_image,
PDBLK block,
ICOORD  page_tr 
)

Extract edges from a PDBLK.

Parameters:
t_image Threshold image
block Block in image
page_tr Corner of page
Returns:
none (block modified)
Note:
Changed for v1.03

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 }

CRACKEDGE* h_edge ( INT16  x,
INT16  y,
INT8  sign,
CRACKEDGE join 
)

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 }

void join_edges ( CRACKEDGE edge1,
CRACKEDGE edge2 
)

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.

Parameters:
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
Scan a line for edges and update prevline (edges in progress). When edges close into loops, send them for approximation.

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 }

CRACKEDGE* v_edge ( INT16  x,
INT16  y,
INT8  sign,
CRACKEDGE join 
)

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 }

void whiteout_block ( IMAGE t_image,
PDBLK block 
)

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 }


Generated on Wed Feb 28 19:49:25 2007 for Tesseract by  doxygen 1.5.1