⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 blkocc.cpp

📁 一OCR的相关资料。.希望对研究OCR的朋友有所帮助.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * * File:        blkocc.cpp  (Formerly blockocc.c) * Description:  Block Occupancy routines * Author:       Chris Newton * Created:      Fri Nov 8 * Modified: * Language:     C++ * Package:      N/A * Status:       Experimental (Do Not Distribute) * * (c) Copyright 1991, Hewlett-Packard Company. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * ******************************************************************************//*----------------------------------------------------------------------              I n c l u d e s----------------------------------------------------------------------*/#include "mfcpch.h"#include          <ctype.h>#include          <math.h>#include          "errcode.h"#include          "grphics.h"#include          "drawtord.h"#include          "blkocc.h"#include          "notdll.h"const ERRCODE BLOCKOCC = "BlockOcc";ELISTIZE (REGION_OCC)#define EXTERNEXTERN BOOL_VAR (blockocc_show_result, FALSE,"Show intermediate results");/* The values given here should reflect the values of bln_x_height and * bln_baseline_offset. These are defined as part of the word class * definition                                                             */EXTERN INT_VAR (blockocc_desc_height, 0,"Descender height after normalisation");EXTERN INT_VAR (blockocc_asc_height, 255,"Ascender height after normalisation");EXTERN INT_VAR (blockocc_band_count, 4, "Number of bands used");EXTERN double_VAR (textord_underline_threshold, 0.5,"Fraction of width occupied");/* ********************************************************************A note on transitions.We want to record occupancy in various bands. In general we need to consider7 situations:(1)     (2)  (3)             (4)\       /   \           /   \           /__\_____/_____\_________/_____\_________/______ Upper Limit  \   /       \       /       \       /  /   \        \-->--/         \--<--/     /-----\v     ^                                  /       \(7)\      \                                 \       /  \      \      /--<--\      /-->--\       \-----/____\______\____/_______\____/_______\_________ Lower Limit  \      \  /         \  /         \          (5)          (6)We know that following "next" pointers around an outline keeps the black areaon the LEFT. We only need be concerned with situations 1,2,3,5 and 7.4 and 6 can be ignored as they represent small incursions into a large blackregion which will be recorded elsewhere.  Situations 3 and 5 define encloseedareas bounded by the upper and lower limits respectively.  Situation 1 is opento the right, awaiting a closure by a situation 2 which is open to the right.Situation 7 is entirely enclosed within the band.The situations are refered to as region types and are determined byfind_region_type.An empty region type is used to denote entry to an adjacent band and returnto the original band at the same x location.***********************************************************************/#define REGION_TYPE_EMPTY 0#define REGION_TYPE_OPEN_RIGHT 1#define REGION_TYPE_OPEN_LEFT 2#define REGION_TYPE_UPPER_BOUND 3#define REGION_TYPE_UPPER_UNBOUND 4#define REGION_TYPE_LOWER_BOUND 5#define REGION_TYPE_LOWER_UNBOUND 6#define REGION_TYPE_ENCLOSED 7BAND bands[MAX_NUM_BANDS + 1];   // band defns/********************************************************************** * test_underline * * Check to see if the blob is an underline. * Return TRUE if it is. **********************************************************************/BOOL8 test_underline(                   //look for underlines                     BOOL8 testing_on,  //drawing blob                     PBLOB *blob,       //blob to test                     float baseline,    //coords of baseline                     float xheight      //height of line                    ) {  INT16 occ;  INT16 blob_width;              //width of blob  BOX blob_box;                  //bounding box  float occs[MAX_NUM_BANDS + 1]; //total occupancy  blob_box = blob->bounding_box ();  set_bands(baseline, xheight);  //setup block occ  blob_width = blob->bounding_box ().width ();  if (testing_on) {    //              blob->plot(to_win,GOLDENROD,GOLDENROD);    //              line_color_index(to_win,GOLDENROD);    //              move2d(to_win,blob_box.left(),baseline);    //              draw2d(to_win,blob_box.right(),baseline);    //              move2d(to_win,blob_box.left(),baseline+xheight);    //              draw2d(to_win,blob_box.right(),baseline+xheight);    tprintf      ("Testing underline on blob at (%d,%d)->(%d,%d), base=%g\nOccs:",      blob->bounding_box ().left (), blob->bounding_box ().bottom (),      blob->bounding_box ().right (), blob->bounding_box ().top (),      baseline);  }  block_occ(blob, occs);   if (testing_on) {    for (occ = 0; occ <= MAX_NUM_BANDS; occ++)      tprintf ("%g ", occs[occ]);    tprintf ("\n");  }  if (occs[1] > occs[2] + occs[2] && occs[1] > occs[3] + occs[3]    && occs[1] > blob_width * textord_underline_threshold)    return TRUE;                 //real underline  if (occs[4] > occs[2] + occs[2]    && occs[4] > blob_width * textord_underline_threshold)    return TRUE;                 //overline  return FALSE;                  //neither}/********************************************************************** * test_underline * * Check to see if the blob is an underline. * Return TRUE if it is. **********************************************************************/BOOL8 test_underline(                   //look for underlines                     BOOL8 testing_on,  //drawing blob                     C_BLOB *blob,      //blob to test                     INT16 baseline,    //coords of baseline                     INT16 xheight      //height of line                    ) {  INT16 occ;  INT16 blob_width;              //width of blob  BOX blob_box;                  //bounding box  INT32 desc_occ;  INT32 x_occ;  INT32 asc_occ;  STATS projection;  blob_box = blob->bounding_box ();  blob_width = blob->bounding_box ().width ();  projection.set_range (blob_box.bottom (), blob_box.top () + 1);  if (testing_on) {    //              blob->plot(to_win,GOLDENROD,GOLDENROD);    //              line_color_index(to_win,GOLDENROD);    //              move2d(to_win,blob_box.left(),baseline);    //              draw2d(to_win,blob_box.right(),baseline);    //              move2d(to_win,blob_box.left(),baseline+xheight);    //              draw2d(to_win,blob_box.right(),baseline+xheight);    tprintf      ("Testing underline on blob at (%d,%d)->(%d,%d), base=%d\nOccs:",      blob->bounding_box ().left (), blob->bounding_box ().bottom (),      blob->bounding_box ().right (), blob->bounding_box ().top (),      baseline);  }  horizontal_cblob_projection(blob, &projection);   desc_occ = 0;  for (occ = blob_box.bottom (); occ < baseline; occ++)    if (occ <= blob_box.top () && projection.pile_count (occ) > desc_occ)                                 //max in region      desc_occ = projection.pile_count (occ);  x_occ = 0;  for (occ = baseline; occ <= baseline + xheight; occ++)    if (occ >= blob_box.bottom () && occ <= blob_box.top ()    && projection.pile_count (occ) > x_occ)                                 //max in region      x_occ = projection.pile_count (occ);  asc_occ = 0;  for (occ = baseline + xheight + 1; occ <= blob_box.top (); occ++)    if (occ >= blob_box.bottom () && projection.pile_count (occ) > asc_occ)      asc_occ = projection.pile_count (occ);  if (testing_on) {    tprintf ("%d %d %d\n", desc_occ, x_occ, asc_occ);  }  if (desc_occ == 0 && x_occ == 0 && asc_occ == 0) {    tprintf ("Bottom=%d, top=%d, base=%d, x=%d\n",      blob_box.bottom (), blob_box.top (), baseline, xheight);    projection.print (stdout, TRUE);  }  if (desc_occ > x_occ + x_occ    && desc_occ > blob_width * textord_underline_threshold)    return TRUE;                 //real underline  if (asc_occ > x_occ + x_occ    && asc_occ > blob_width * textord_underline_threshold)    return TRUE;                 //overline  return FALSE;                  //neither}/********************************************************************** * horizontal_cblob_projection * * Compute the horizontal projection of a cblob from its outlines * and add to the given STATS. **********************************************************************/void horizontal_cblob_projection(               //project outlines                                 C_BLOB *blob,  //blob to project                                 STATS *stats   //output                                ) {                                 //outlines of blob  C_OUTLINE_IT out_it = blob->out_list ();  for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {    horizontal_coutline_projection (out_it.data (), stats);  }}/********************************************************************** * horizontal_coutline_projection * * Compute the horizontal projection of a outline from its outlines * and add to the given STATS. **********************************************************************/void horizontal_coutline_projection(                     //project outlines                                    C_OUTLINE *outline,  //outline to project                                    STATS *stats         //output                                   ) {  ICOORD pos;                    //current point  ICOORD step;                   //edge step  INT32 length;                  //of outline  INT16 stepindex;               //current step  C_OUTLINE_IT out_it = outline->child ();  pos = outline->start_pos ();  length = outline->pathlength ();  for (stepindex = 0; stepindex < length; stepindex++) {    step = outline->step (stepindex);    if (step.y () > 0) {      stats->add (pos.y (), pos.x ());    }    else if (step.y () < 0) {      stats->add (pos.y () - 1, -pos.x ());    }    pos += step;  }  for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {    horizontal_coutline_projection (out_it.data (), stats);  }}void set_bands(                 //init from varibles               float baseline,  //top of bottom band               float xheight    //height of split band              ) {  INT16 int_bl, int_xh;          //for band.set  bands[DOT_BAND].set (0, 0, 0, 0, 0, 0);  int_bl = (INT16) baseline;  int_xh = (INT16) xheight;  bands[1].set (int_bl, int_bl, int_bl,    NO_LOWER_LIMIT, NO_LOWER_LIMIT, NO_LOWER_LIMIT);  bands[2].set (int_bl + int_xh / 2, int_bl + int_xh / 2, int_bl + int_xh / 2,    int_bl, int_bl, int_bl);  bands[3].set (int_bl + int_xh, int_bl + int_xh, int_bl + int_xh,    int_bl + int_xh / 2, int_bl + int_xh / 2,    int_bl + int_xh / 2);  bands[4].set (NO_UPPER_LIMIT, NO_UPPER_LIMIT, NO_UPPER_LIMIT,    int_bl + int_xh, int_bl + int_xh, int_bl + int_xh);}voidblock_occ (PBLOB * blob,         //blob to dofloat occs[]                     //output histogram) {  int band_index;                //current band  REGION_OCC *region;            //current segment  REGION_OCC_LIST region_occ_list[MAX_NUM_BANDS + 1];  REGION_OCC_IT region_it;       //region iterator  find_transitions(blob, region_occ_list);   compress_region_list(region_occ_list);   for (band_index = 0; band_index <= MAX_NUM_BANDS; band_index++) {    occs[band_index] = 0.0f;    region_it.set_to_list (&region_occ_list[band_index]);    for (region_it.mark_cycle_pt (); !region_it.cycled_list ();    region_it.forward ()) {      region = region_it.data ();      occs[band_index] += region->max_x - region->min_x;    }  }}void find_transitions(PBLOB *blob,  //blob to do                      REGION_OCC_LIST *region_occ_list) {  OUTLINE_IT outline_it;  BOX box;  POLYPT_IT pt_it;  FCOORD point1;  FCOORD point2;  FCOORD *entry_pt = &point1;  FCOORD *exit_pt = &point2;  FCOORD *temp_pt;  INT16 increment;  INT16 prev_band;  INT16 band;  INT16 next_band;  float min_x;  float max_x;  float min_y;  float max_y;  BOOL8 doubly_contained;  outline_it = blob->out_list ();  for (outline_it.mark_cycle_pt (); !outline_it.cycled_list ();  outline_it.forward ()) {    find_fbox(&outline_it, &min_x, &min_y, &max_x, &max_y);     if (bands[DOT_BAND].range_in_nominal (max_y, min_y)) {      record_region(DOT_BAND,                    min_x,                    max_x,                    REGION_TYPE_ENCLOSED,                    region_occ_list);    }    else {      band = find_containing_maximal_band (max_y, min_y,        &doubly_contained);      if (band != UNDEFINED_BAND) {                                 //No transitions        if (!doubly_contained)          record_region(band,                        min_x,                        max_x,                        REGION_TYPE_ENCLOSED,                        region_occ_list);        else {          //                                      if (wordocc_debug_on && blockocc_show_result)          //                                      {          //                                              fprintf( db_win,          //                                                "Ignoring doubly contained outline (%d, %d) (%d, %d)\n",          //                                                box.left(), box.top(),          //                                                box.right(), box.bottom());          //                                              fprintf( db_win, "\tContained in bands %d and %d\n",          //                                                                      band, band + 1 );          //                                      }        }      }      else {                                 //There are transitns        /*        Determining a good start point for recognising transitions between bands        is complicated by error limits on bands.  We need to find a line which        significantly occupies a band.        Having found such a point, we need to find a significant transition out of        its band and start the walk around the outline from there.        Note that we are relying on having recognised and dealt with elsewhere,        outlines which do not significantly occupy more than one region. A        particularly nasty case of this are outlines which do not significantly        occupy ANY band. I.e. they lie entirely within the error limits.        Given this condition, all remaining outlines must contain at least one        significant line.  */        pt_it = outline_it.data ()->polypts ();        find_significant_line(pt_it, &band);         *entry_pt = pt_it.data ()->pos;        next_region(&pt_it,                    band,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -