textord/edgloop.cpp

Go to the documentation of this file.
00001 
00020 #include "mfcpch.h"
00021 #include          "scanedg.h"
00022 #include          "drawedg.h"
00023 #include          "edgloop.h"
00024 
00025 #ifdef TEXT_VERBOSE
00026 #include           "../cutil/callcpp.h"
00027 #endif
00028 
00030 #define MINEDGELENGTH   8
00031 
00032 #define EXTERN
00033 
00036 EXTERN double_VAR (edges_threshold_greyfraction, 0.07,
00037 "Min edge diff for grad vector");
00038 EXTERN BOOL_VAR (edges_show_paths, FALSE, "Draw raw outlines");
00039 EXTERN BOOL_VAR (edges_show_needles, FALSE, "Draw edge needles");
00040 EXTERN INT_VAR (edges_maxedgelength, 16000, "Max steps in any outline");
00043 #ifndef GRAPHICS_DISABLED
00045 static WINDOW edge_win;
00046 #endif
00048 static C_OUTLINE_IT *outline_it;
00050 static int short_edges;
00052 static int long_edges;
00053 
00068 DLLSYM void get_outlines(                      //edge detect
00069 #ifndef GRAPHICS_DISABLED
00070                          WINDOW window,        //window for output
00071 #endif
00072                          IMAGE *image,         //image to scan
00073                          IMAGE *t_image,       //thresholded image
00074                          ICOORD page_tr,       //corner of page
00075                          PDBLK *block,         //block to scan
00076                          C_OUTLINE_IT *out_it  //output iterator
00077                         ) {
00078 #ifndef GRAPHICS_DISABLED
00079   edge_win = window;             //set statics
00080 #endif
00081   outline_it = out_it;
00082   block_edges(t_image, block, page_tr);
00083   out_it->move_to_first ();      // reset iterator to first outline
00084 #ifndef GRAPHICS_DISABLED
00085   if (window != NO_WINDOW)
00086     overlap_picture_ops(TRUE);  //update window
00087 #endif
00088 }
00089 
00090 
00099 void complete_edge(                  //clean and approximate
00100                    CRACKEDGE *start  //start of loop
00101                   ) {
00102   COLOUR colour;                 //colour to draw in
00103   INT16 looplength;              //steps in loop
00104   ICOORD botleft;                //bounding box
00105   ICOORD topright;
00106   C_OUTLINE *outline;            //new outline
00107 
00108                                  //check length etc.
00109   colour = check_path_legal (start);
00110 #ifndef GRAPHICS_DISABLED
00111   if (edges_show_paths) {
00112                                  //in red
00113     draw_raw_edge(edge_win, start, colour);
00114   }
00115 #endif
00116 
00117   if (colour == RED || colour == BLUE) {
00118     looplength = loop_bounding_box (start, botleft, topright);
00119     outline = new C_OUTLINE (start, botleft, topright, looplength);
00120                                  //add to list
00121     outline_it->add_after_then_move (outline);
00122 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00123   cprintf("Z"); // , see ccmain/tessvars.h
00124 #endif
00125   }
00126 }
00127 
00128 
00197 COLOUR check_path_legal(                  //certify outline
00198                         CRACKEDGE *start  //start of loop
00199                        ) {
00200   int lastchain;              //last chain code
00201   int chaindiff;               //chain code diff
00202   INT32 length;                  //length of loop
00203   INT32 chainsum;                //sum of chain diffs
00204   CRACKEDGE *edgept;             //current point
00205   const ERRCODE ED_ILLEGAL_SUM = "Illegal sum of chain codes";
00206 
00207   length = 0;
00208   chainsum = 0;                  //sum of chain codes
00209   edgept = start;
00210   lastchain = edgept->prev->stepdir; //previous chain code
00211 
00212   int c = 0;
00213   do {
00214     length++;
00215     if (edgept->stepdir != lastchain) {
00216                                  //chain code difference
00217       chaindiff = edgept->stepdir - lastchain;
00218 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00219   cprintf("1(%d,%d,%d)",edgept->stepdir,lastchain,chaindiff); // , see ccmain/tessvars.h
00220 #endif
00221       if (chaindiff > 2)
00222         chaindiff -= 4;
00223       else if (chaindiff < -2)
00224         chaindiff += 4;
00225       chainsum += chaindiff;     //sum differences
00226       lastchain = edgept->stepdir;
00227     }
00228     edgept = edgept->next;
00229    c++;
00230   }
00231   while (edgept != start && length < edges_maxedgelength);
00232 
00233   if (chainsum != 4 && chainsum != -4
00234   || edgept != start || length < MINEDGELENGTH) {
00235     if (edgept != start) {
00236 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00237   cprintf("\n2(Y:%d,%d,iter=%d)",length,chainsum,c); // , see ccmain/tessvars.h
00238 #endif
00239       long_edges++;
00240       return YELLOW;
00241     }
00242     else if (length < MINEDGELENGTH) {
00243 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00244   cprintf("3(M:%d,%d,iter=%d)",length,chainsum,c); // , see ccmain/tessvars.h
00245 #endif
00246       short_edges++;
00247       return MAGENTA;
00248     }
00249     else {
00250       ED_ILLEGAL_SUM.error ("check_path_legal", LOG, "chainsum=%d",
00251         chainsum);
00252       return GREEN;
00253     }
00254   }
00255 #if defined(TEXT_VERBOSE) && defined(TV_FOCUSF)
00256   cprintf("4(%s:%d,%d,iter=%d)",(chainsum < 0 ? "B" : "R"),
00257    length,chainsum,c); // , see ccmain/tessvars.h
00258 #endif
00259                                  //colour on inside
00260   return chainsum < 0 ? BLUE : RED;
00261 }
00262 
00274 INT16 loop_bounding_box(                    //get bounding box
00275                         CRACKEDGE *&start,  //edge loop
00276                         ICOORD &botleft,    //bounding box
00277                         ICOORD &topright) {
00278   INT16 length;                  //length of loop
00279   INT16 leftmost;                //on top row
00280   CRACKEDGE *edgept;             //current point
00281   CRACKEDGE *realstart;          //topleft start
00282 
00283   edgept = start;
00284   realstart = start;
00285   botleft = topright = ICOORD (edgept->pos.x (), edgept->pos.y ());
00286   leftmost = edgept->pos.x ();
00287   length = 0;                    //coutn length
00288   do {
00289     edgept = edgept->next;
00290     if (edgept->pos.x () < botleft.x ())
00291                                  //get bounding box
00292       botleft.set_x (edgept->pos.x ());
00293     else if (edgept->pos.x () > topright.x ())
00294       topright.set_x (edgept->pos.x ());
00295     if (edgept->pos.y () < botleft.y ())
00296                                  //get bounding box
00297       botleft.set_y (edgept->pos.y ());
00298     else if (edgept->pos.y () > topright.y ()) {
00299       realstart = edgept;
00300       leftmost = edgept->pos.x ();
00301       topright.set_y (edgept->pos.y ());
00302     }
00303     else if (edgept->pos.y () == topright.y ()
00304     && edgept->pos.x () < leftmost) {
00305                                  //leftmost on line
00306       leftmost = edgept->pos.x ();
00307       realstart = edgept;
00308     }
00309     length++;                    //count elements
00310   }
00311   while (edgept != start);
00312   start = realstart;             //shift it to topleft
00313   return length;
00314 }

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