ccstruct/polyblob.cpp

Go to the documentation of this file.
00001 
00020 #include "mfcpch.h"
00021 #include          "varable.h"
00022 #include          "ocrrow.h"
00023 #include          "polyblob.h"
00024 //#include                                                      "lapoly.h"
00025 #include          "polyaprx.h"
00026 
00027 #define EXTERN
00028 
00031 EXTERN BOOL_VAR (polygon_tess_approximation, TRUE,
00032 "Do tess poly instead of greyscale");
00035 ELISTIZE_S (PBLOB)
00036 
00037 
00043 static void position_outline(                        //put in place
00044                              OUTLINE *outline,       //thing to place
00045                              OUTLINE_LIST *destlist  //desstination list
00046                             ) {
00047   OUTLINE *dest_outline;         //outline from dest list
00048   OUTLINE_IT it = destlist;      //iterator
00049                                  //iterator on children
00050   OUTLINE_IT child_it = outline->child ();
00051 
00052   if (!it.empty ()) {
00053     do {
00054       dest_outline = it.data (); //get destination
00055                                  //encloses dest
00056       if (*dest_outline < *outline) {
00057                                  //take off list
00058         dest_outline = it.extract ();
00059                                  //put this in place
00060         it.add_after_then_move (outline);
00061                                  //make it a child
00062         child_it.add_to_end (dest_outline);
00063         while (!it.at_last ()) {
00064           it.forward ();         //do rest of list
00065                                  //check for other children
00066           dest_outline = it.data ();
00067           if (*dest_outline < *outline) {
00068                                  //take off list
00069             dest_outline = it.extract ();
00070             child_it.add_to_end (dest_outline);
00071             //make it a child
00072             if (it.empty ())
00073               break;
00074           }
00075         }
00076         return;                  //finished
00077       }
00078                                  //enclosed by dest
00079       else if (*outline < *dest_outline) {
00080         position_outline (outline, dest_outline->child ());
00081         //place in child list
00082         return;                  //finished
00083       }
00084       it.forward ();
00085     }
00086     while (!it.at_first ());
00087   }
00088   it.add_to_end (outline);       //at outer level
00089 }
00090 
00091 
00098 #ifndef GRAPHICS_DISABLED
00099 static void plot_outline_list(                     //draw outlines
00100                               OUTLINE_LIST *list,  //outline to draw
00101                               WINDOW window,       //window to draw in
00102                               COLOUR colour,       //colour to use
00103                               COLOUR child_colour  //colour of children
00104                              ) {
00105   OUTLINE *outline;              //current outline
00106   OUTLINE_IT it = list;          //iterator
00107 
00108   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00109     outline = it.data ();
00110                                  //draw it
00111     outline->plot (window, colour);
00112     if (!outline->child ()->empty ())
00113       plot_outline_list (outline->child (), window,
00114         child_colour, child_colour);
00115   }
00116 }
00117 #endif
00118 
00119 
00126 PBLOB::PBLOB(                            //constructor
00127              OUTLINE_LIST *outline_list  //in random order
00128             ) {
00129   OUTLINE *outline;              //current outline
00130   OUTLINE_IT it = outline_list;  //iterator
00131 
00132   while (!it.empty ()) {         //grab the list
00133     outline = it.extract ();     //get off the list
00134                                  //put it in place
00135     position_outline(outline, &outlines); 
00136     if (!it.empty ())
00137       it.forward ();
00138   }
00139 }
00140 
00141 
00147 static void approximate_outline_list(                          //do list of outlines
00148                                      C_OUTLINE_LIST *srclist,  //list to convert
00149                                      OUTLINE_LIST *destlist,   //desstination list
00150                                      float xheight             //height of line
00151                                     ) {
00152   C_OUTLINE *src_outline;        //outline from src list
00153   OUTLINE *dest_outline;         //result
00154   C_OUTLINE_IT src_it = srclist; //source iterator
00155   OUTLINE_IT dest_it = destlist; //iterator
00156 
00157   do {
00158     src_outline = src_it.data ();
00159     //              if (polygon_tess_approximation)
00160     dest_outline = tesspoly_outline (src_outline, xheight);
00161     //              else
00162     //                      dest_outline=greypoly_outline(src_outline,xheight);
00163     if (dest_outline != NULL) {
00164       dest_it.add_after_then_move (dest_outline);
00165       if (!src_outline->child ()->empty ())
00166                                  //do child list
00167         approximate_outline_list (src_outline->child (), dest_outline->child (), xheight);
00168     }
00169     src_it.forward ();
00170   }
00171   while (!src_it.at_first ());
00172 }
00173 
00174 
00180 PBLOB::PBLOB(                //constructor
00181              C_BLOB *cblob,  //compact blob
00182              float xheight   //height of line
00183             ) {
00184   BOX bbox;                      //bounding box
00185 
00186   if (!cblob->out_list ()->empty ()) {
00187                                  //get bounding box
00188     bbox = cblob->bounding_box ();
00189     if (bbox.height () > xheight)
00190       xheight = bbox.height ();  //max of line and blob
00191                                  //copy it
00192     approximate_outline_list (cblob->out_list (), &outlines, xheight);
00193   }
00194 }
00195 
00196 
00202 BOX PBLOB::bounding_box() {  //bounding box
00203   OUTLINE *outline;              //current outline
00204   OUTLINE_IT it = &outlines;     //outlines of blob
00205   BOX box;                       //bounding box
00206 
00207   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00208     outline = it.data ();
00209     box += outline->bounding_box ();
00210   }
00211   return box;
00212 }
00213 
00214 
00220 float PBLOB::area() {  //area
00221   OUTLINE *outline;              //current outline
00222   OUTLINE_IT it = &outlines;     //outlines of blob
00223   float total;                   //total area
00224 
00225   total = 0.0f;
00226   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) {
00227     outline = it.data ();
00228     total += outline->area ();
00229   }
00230   return total;
00231 }
00232 
00233 
00239 PBLOB *PBLOB::baseline_normalise(                //normalize blob
00240                                  ROW *row,       //row it came from
00241                                  DENORM *denorm  //inverse mapping
00242                                 ) {
00243   BOX blob_box = bounding_box ();
00244   float x_centre = (blob_box.left () + blob_box.right ()) / 2.0;
00245   PBLOB *bn_blob;                //copied blob
00246 
00247   *denorm = DENORM (x_centre, bln_x_height / row->x_height (), row);
00248   bn_blob = new PBLOB;           //get one
00249   *bn_blob = *this;              //deep copy
00250   bn_blob->move (FCOORD (-denorm->origin (), -row->base_line (x_centre)));
00251   bn_blob->scale (denorm->scale ());
00252   bn_blob->move (FCOORD (0.0, bln_baseline_offset));
00253   return bn_blob;
00254 }
00255 
00256 
00262 void PBLOB::baseline_denormalise(                      // Tess style BL Norm
00263                                  const DENORM *denorm  //antidote
00264                                 ) {
00265   float blob_x_left;           // Left edge of blob.
00266   BOX blob_box;                  //blob bounding box
00267 
00268   move(FCOORD (0.0f, 0.0f - bln_baseline_offset));
00269   blob_box = bounding_box ();
00270   blob_x_left = blob_box.left ();
00271   scale (1.0 / denorm->scale_at_x (blob_x_left));
00272   move (FCOORD (denorm->origin (),
00273     denorm->yshift_at_x (blob_x_left)));
00274 }
00275 
00276 
00282 void PBLOB::move(                  // reposition blob
00283                  const FCOORD vec  // by vector
00284                 ) {
00285   OUTLINE_IT it(&outlines);  // iterator
00286 
00287   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00288     it.data ()->move (vec);      // move each outline
00289 }
00290 
00291 
00297 void PBLOB::scale(               // scale blob
00298                   const float f  // by multiplier
00299                  ) {
00300   OUTLINE_IT it(&outlines);  // iterator
00301 
00302   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00303     it.data ()->scale (f);       // scale each outline
00304 }
00305 
00306 
00312 void PBLOB::scale(                  // scale blob
00313                   const FCOORD vec  // by multiplier
00314                  ) {
00315   OUTLINE_IT it(&outlines);  // iterator
00316 
00317   for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ())
00318     it.data ()->scale (vec);     // scale each outline
00319 }
00320 
00321 
00327 #ifndef GRAPHICS_DISABLED
00328 void PBLOB::plot(                     //draw it
00329                  WINDOW window,       //window to draw in
00330                  COLOUR blob_colour,  //main colour
00331                  COLOUR child_colour  //for holes
00332                 ) {
00333   plot_outline_list(&outlines, window, blob_colour, child_colour); 
00334 }
00335 #endif

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