Tesseract  3.02
tesseract-ocr/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 "mfcpch.h"
00032 #include <ctype.h>
00033 #include <math.h>
00034 #include "errcode.h"
00035 #include "drawtord.h"
00036 #include "blkocc.h"
00037 #include "helpers.h"
00038 #include "notdll.h"
00039 
00040 double_VAR(textord_underline_threshold, 0.5, "Fraction of width occupied");
00041 
00042 // Forward declarations of static functions
00043 static void horizontal_cblob_projection(C_BLOB *blob,   // blob to project
00044                                         STATS *stats);  // output
00045 static void horizontal_coutline_projection(C_OUTLINE *outline,
00046                                            STATS *stats);        // output
00047 
00055 BOOL8 test_underline(                   //look for underlines
00056                      BOOL8 testing_on,  //< drawing blob
00057                      C_BLOB *blob,      //< blob to test
00058                      inT16 baseline,    //< coords of baseline
00059                      inT16 xheight      //< height of line
00060                     ) {
00061   inT16 occ;
00062   inT16 blob_width;              //width of blob
00063   TBOX blob_box;                  //bounding box
00064   inT32 desc_occ;
00065   inT32 x_occ;
00066   inT32 asc_occ;
00067   STATS projection;
00068 
00069   blob_box = blob->bounding_box ();
00070   blob_width = blob->bounding_box ().width ();
00071   projection.set_range (blob_box.bottom (), blob_box.top () + 1);
00072   if (testing_on) {
00073     //              blob->plot(to_win,GOLDENROD,GOLDENROD);
00074     //              line_color_index(to_win,GOLDENROD);
00075     //              move2d(to_win,blob_box.left(),baseline);
00076     //              draw2d(to_win,blob_box.right(),baseline);
00077     //              move2d(to_win,blob_box.left(),baseline+xheight);
00078     //              draw2d(to_win,blob_box.right(),baseline+xheight);
00079     tprintf
00080       ("Testing underline on blob at (%d,%d)->(%d,%d), base=%d\nOccs:",
00081       blob->bounding_box ().left (), blob->bounding_box ().bottom (),
00082       blob->bounding_box ().right (), blob->bounding_box ().top (),
00083       baseline);
00084   }
00085   horizontal_cblob_projection(blob, &projection);
00086   desc_occ = 0;
00087   for (occ = blob_box.bottom (); occ < baseline; occ++)
00088     if (occ <= blob_box.top () && projection.pile_count (occ) > desc_occ)
00089                                  //max in region
00090       desc_occ = projection.pile_count (occ);
00091   x_occ = 0;
00092   for (occ = baseline; occ <= baseline + xheight; occ++)
00093     if (occ >= blob_box.bottom () && occ <= blob_box.top ()
00094     && projection.pile_count (occ) > x_occ)
00095                                  //max in region
00096       x_occ = projection.pile_count (occ);
00097   asc_occ = 0;
00098   for (occ = baseline + xheight + 1; occ <= blob_box.top (); occ++)
00099     if (occ >= blob_box.bottom () && projection.pile_count (occ) > asc_occ)
00100       asc_occ = projection.pile_count (occ);
00101   if (testing_on) {
00102     tprintf ("%d %d %d\n", desc_occ, x_occ, asc_occ);
00103   }
00104   if (desc_occ == 0 && x_occ == 0 && asc_occ == 0) {
00105     tprintf ("Bottom=%d, top=%d, base=%d, x=%d\n",
00106       blob_box.bottom (), blob_box.top (), baseline, xheight);
00107     projection.print();
00108   }
00109   if (desc_occ > x_occ + x_occ
00110     && desc_occ > blob_width * textord_underline_threshold)
00111     return TRUE;                 //real underline
00112   if (asc_occ > x_occ + x_occ
00113     && asc_occ > blob_width * textord_underline_threshold)
00114     return TRUE;                 //overline
00115   return FALSE;                  //neither
00116 }
00117 
00118 
00126 static void horizontal_cblob_projection(               //project outlines
00127                                  C_BLOB *blob,  //< blob to project
00128                                  STATS *stats   //< output
00129                                 ) {
00130                                  //outlines of blob
00131   C_OUTLINE_IT out_it = blob->out_list ();
00132 
00133   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00134     horizontal_coutline_projection (out_it.data (), stats);
00135   }
00136 }
00137 
00138 
00146 static void horizontal_coutline_projection(                     //project outlines
00147                                     C_OUTLINE *outline,  //< outline to project
00148                                     STATS *stats         //< output
00149                                    ) {
00150   ICOORD pos;                    //current point
00151   ICOORD step;                   //edge step
00152   inT32 length;                  //of outline
00153   inT16 stepindex;               //current step
00154   C_OUTLINE_IT out_it = outline->child ();
00155 
00156   pos = outline->start_pos ();
00157   length = outline->pathlength ();
00158   for (stepindex = 0; stepindex < length; stepindex++) {
00159     step = outline->step (stepindex);
00160     if (step.y () > 0) {
00161       stats->add (pos.y (), pos.x ());
00162     }
00163     else if (step.y () < 0) {
00164       stats->add (pos.y () - 1, -pos.x ());
00165     }
00166     pos += step;
00167   }
00168 
00169   for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
00170     horizontal_coutline_projection (out_it.data (), stats);
00171   }
00172 }