tesseract  3.03
/usr/local/google/home/jbreiden/tesseract-ocr-read-only/textord/blkocc.cpp
Go to the documentation of this file.
00001 /*****************************************************************************
00002  *
00003  * File:        blkocc.cpp  (Formerly blockocc.c)
00004  * Description:  Block Occupancy routines
00005  * Author:       Chris Newton
00006  * Created:      Fri Nov 8
00007  * Modified:
00008  * Language:     C++
00009  * Package:      N/A
00010  * Status:       Experimental (Do Not Distribute)
00011  *
00012  * (c) Copyright 1991, Hewlett-Packard Company.
00013  ** Licensed under the Apache License, Version 2.0 (the "License");
00014  ** you may not use this file except in compliance with the License.
00015  ** You may obtain a copy of the License at
00016  ** http://www.apache.org/licenses/LICENSE-2.0
00017  ** Unless required by applicable law or agreed to in writing, software
00018  ** distributed under the License is distributed on an "AS IS" BASIS,
00019  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020  ** See the License for the specific language governing permissions and
00021  ** limitations under the License.
00022  *
00023  ******************************************************************************/
00024 
00025 /*
00026 ----------------------------------------------------------------------
00027               I n c l u d e s
00028 ----------------------------------------------------------------------
00029 */
00030 
00031 #include <ctype.h>
00032 #include <math.h>
00033 #include "errcode.h"
00034 #include "drawtord.h"
00035 #include "blkocc.h"
00036 #include "helpers.h"
00037 
00038 double_VAR(textord_underline_threshold, 0.5, "Fraction of width occupied");
00039 
00040 // Forward declarations of static functions
00041 static void horizontal_cblob_projection(C_BLOB *blob,   // blob to project
00042                                         STATS *stats);  // output
00043 static void horizontal_coutline_projection(C_OUTLINE *outline,
00044                                            STATS *stats);        // output
00045 
00053 BOOL8 test_underline(                   //look for underlines
00054                      BOOL8 testing_on,  //< drawing blob
00055                      C_BLOB *blob,      //< blob to test
00056                      inT16 baseline,    //< coords of baseline
00057                      inT16 xheight      //< height of line
00058                     ) {
00059   inT16 occ;
00060   inT16 blob_width;              //width of blob
00061   TBOX blob_box;                  //bounding box
00062   inT32 desc_occ;
00063   inT32 x_occ;
00064   inT32 asc_occ;
00065   STATS projection;
00066 
00067   blob_box = blob->bounding_box ();
00068   blob_width = blob->bounding_box ().width ();
00069   projection.set_range (blob_box.bottom (), blob_box.top () + 1);
00070   if (testing_on) {
00071     //              blob->plot(to_win,GOLDENROD,GOLDENROD);
00072     //              line_color_index(to_win,GOLDENROD);
00073     //              move2d(to_win,blob_box.left(),baseline);
00074     //              draw2d(to_win,blob_box.right(),baseline);
00075     //              move2d(to_win,blob_box.left(),baseline+xheight);
00076     //              draw2d(to_win,blob_box.right(),baseline+xheight);
00077     tprintf
00078       ("Testing underline on blob at (%d,%d)->(%d,%d), base=%d\nOccs:",
00079       blob->bounding_box ().left (), blob->bounding_box ().bottom (),
00080       blob->bounding_box ().right (), blob->bounding_box ().top (),
00081       baseline);
00082   }
00083   horizontal_cblob_projection(blob, &projection);
00084   desc_occ = 0;
00085   for (occ = blob_box.bottom (); occ < baseline; occ++)
00086     if (occ <= blob_box.top () && projection.pile_count (occ) > desc_occ)
00087                                  //max in region
00088       desc_occ = projection.pile_count (occ);
00089   x_occ = 0;
00090   for (occ = baseline; occ <= baseline + xheight; occ++)
00091     if (occ >= blob_box.bottom () && occ <= blob_box.top ()
00092     && projection.pile_count (occ) > x_occ)
00093                                  //max in region
00094       x_occ = projection.pile_count (occ);
00095   asc_occ = 0;
00096   for (occ = baseline + xheight + 1; occ <= blob_box.top (); occ++)
00097     if (occ >= blob_box.bottom () && projection.pile_count (occ) > asc_occ)
00098       asc_occ = projection.pile_count (occ);
00099   if (testing_on) {
00100     tprintf ("%d %d %d\n", desc_occ, x_occ, asc_occ);
00101   }
00102   if (desc_occ == 0 && x_occ == 0 && asc_occ == 0) {
00103     tprintf ("Bottom=%d, top=%d, base=%d, x=%d\n",
00104       blob_box.bottom (), blob_box.top (), baseline, xheight);
00105     projection.print();
00106   }
00107   if (desc_occ > x_occ + x_occ
00108     && desc_occ > blob_width * textord_underline_threshold)
00109     return TRUE;                 //real underline
00110   if (asc_occ > x_occ + x_occ
00111     && asc_occ > blob_width * textord_underline_threshold)
00112     return TRUE;                 //overline
00113   return FALSE;                  //neither
00114 }
00115 
00116 
00124 static void horizontal_cblob_projection(               //project outlines
00125                                  C_BLOB *blob,  //< blob to project
00126                                  STATS *stats   //< output
00127                                 ) {
00128                                  //outlines of blob
00129   C_OUTLINE_IT out_it = blob->out_list ();
00130 
00131   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00132     horizontal_coutline_projection (out_it.data (), stats);
00133   }
00134 }
00135 
00136 
00144 static void horizontal_coutline_projection(                     //project outlines
00145                                     C_OUTLINE *outline,  //< outline to project
00146                                     STATS *stats         //< output
00147                                    ) {
00148   ICOORD pos;                    //current point
00149   ICOORD step;                   //edge step
00150   inT32 length;                  //of outline
00151   inT16 stepindex;               //current step
00152   C_OUTLINE_IT out_it = outline->child ();
00153 
00154   pos = outline->start_pos ();
00155   length = outline->pathlength ();
00156   for (stepindex = 0; stepindex < length; stepindex++) {
00157     step = outline->step (stepindex);
00158     if (step.y () > 0) {
00159       stats->add (pos.y (), pos.x ());
00160     }
00161     else if (step.y () < 0) {
00162       stats->add (pos.y () - 1, -pos.x ());
00163     }
00164     pos += step;
00165   }
00166 
00167   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00168     horizontal_coutline_projection (out_it.data (), stats);
00169   }
00170 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines