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

📄 chop.cpp

📁 一OCR的相关资料。.希望对研究OCR的朋友有所帮助.
💻 CPP
字号:
/* -*-C-*- ******************************************************************************** * * File:        chop.c  (Formerly chop.c) * Description: * Author:       Mark Seaman, OCR Technology * Created:      Fri Oct 16 14:37:00 1987 * Modified:     Tue Jul 30 16:41:11 1991 (Mark Seaman) marks@hpgrlt * Language:     C * Package:      N/A * Status:       Reusable Software Component * * (c) Copyright 1987, 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 "chop.h"#include "debug.h"#include "outlines.h"#include "olutil.h"#include "tordvars.h"#include "callcpp.h"#include "plotedges.h"#include "const.h"#include <math.h>/*----------------------------------------------------------------------              V a r i a b l e s----------------------------------------------------------------------*/make_int_var (chop_debug, 0, make_chop_debug,3, 1, set_chop_debug, "Chop debug");make_int_var (chop_enable, 1, make_chop_enable,3, 2, set_chop_enable, "Chop enable");make_toggle_var (vertical_creep, 0, make_vertical_creep,3, 4, set_vertical_creep, "Vertical creep");make_int_var (split_length, 10000, make_split_length,3, 5, set_split_length, "Split Length");make_int_var (same_distance, 2, make_same_distance,3, 6, set_same_distance, "Same distance");make_int_var (min_outline_points, 6, make_min_points,3, 9, set_min_points, "Min Number of Points on Outline");make_int_var (inside_angle, -50, make_inside_angle,3, 12, set_inside_angle, "Min Inside Angle Bend");make_int_var (min_outline_area, 2000, make_outline_area,3, 13, set_outline_area, "Min Outline Area");/*----------------------------------------------------------------------              V a r i a b l e s (moved from gradechop)----------------------------------------------------------------------*/make_float_var (split_dist_knob, 0.5, make_split_dist,3, 17, set_split_dist, "Split length adjustment");make_float_var (overlap_knob, 0.9, make_overlap_knob,3, 18, set_overlap_knob, "Split overlap adjustment");make_float_var (center_knob, 0.15, make_center_knob,3, 19, set_center_knob, "Split center adjustment");make_float_var (sharpness_knob, 0.06, make_sharpness_knob,3, 20, set_sharpness_knob, "Split sharpness adjustment");make_float_var (width_change_knob, 5.0, make_width_change,3, 21, set_width_change_knob, "Width change adjustment");make_float_var (ok_split, 100.0, make_ok_split,3, 14, set_ok_split, "OK split limit");make_float_var (good_split, 50.0, make_good_split,3, 15, set_good_split, "Good split limit");make_int_var (x_y_weight, 3, make_x_y_weight,3, 16, set_x_y_weight, "X / Y  length weight");/*----------------------------------------------------------------------              M a c r o s----------------------------------------------------------------------*//********************************************************************** * length_product * * Compute the product of the length of two vectors.  The * vectors must be of type POINT.   This product is used in computing * angles. **********************************************************************/#define length_product(p1,p2)                                      \(sqrt ((((float) (p1).x * (p1).x + (float) (p1).y * (p1).y) *    \			((float) (p2).x * (p2).x + (float) (p2).y * (p2).y))))/*----------------------------------------------------------------------              F u n c t i o n s----------------------------------------------------------------------*//********************************************************************** * point_priority * * Assign a priority to and edge point that might be used as part of a * split. The argument should be of type EDGEPT. **********************************************************************/PRIORITY point_priority(EDGEPT *point) {  return ((PRIORITY) point_bend_angle (point));}/********************************************************************** * add_point_to_list * * Add an edge point to a POINT_GROUP containg a list of other points. **********************************************************************/void add_point_to_list(POINT_GROUP point_list, EDGEPT *point) {  HEAPENTRY data;  if (SizeOfHeap (point_list) < MAX_NUM_POINTS - 2) {    data.Data = (char *) point;    data.Key = point_priority (point);    HeapStore(point_list, &data);  }#ifndef GRAPHICS_DISABLED  if (chop_debug)    mark_outline(point);#endif}/********************************************************************** * angle_change * * Return the change in angle (degrees) of the line segments between * points one and two, and two and three. **********************************************************************/int angle_change(EDGEPT *point1, EDGEPT *point2, EDGEPT *point3) {  VECTOR vector1;  VECTOR vector2;  int angle;  float length;  /* Compute angle */  vector1.x = point2->pos.x - point1->pos.x;  vector1.y = point2->pos.y - point1->pos.y;  vector2.x = point3->pos.x - point2->pos.x;  vector2.y = point3->pos.y - point2->pos.y;  /* Use cross product */  length = length_product (vector1, vector2);  if ((int) length == 0)    return (0);  angle = (int) (asin (CROSS (vector1, vector2) / length) / PI * 180.0);  /* Use dot product */  if (SCALAR (vector1, vector2) < 0)    angle = 180 - angle;  /* Adjust angle */  if (angle > 180)    angle -= 360;  if (angle <= -180)    angle += 360;  return (angle);}/********************************************************************** * init_chop * * Create the required chopper variables. **********************************************************************/void init_chop() {  make_same_distance();  make_vertical_creep();  make_x_y_weight();  make_chop_enable();  make_chop_debug();  make_split_dist();  make_overlap_knob();  make_sharpness_knob();  make_width_change();  make_good_split();  make_ok_split();  make_center_knob();  make_split_length();  make_min_points();  make_inside_angle();  make_outline_area();}/********************************************************************** * is_little_chunk * * Return TRUE if one of the pieces resulting from this split would * less than some number of edge points. **********************************************************************/int is_little_chunk(EDGEPT *point1, EDGEPT *point2) {  EDGEPT *p = point1;            /* Iterator */  int counter = 0;  do {                                 /* Go from P1 to P2 */    if (is_same_edgept (point2, p)) {      if (is_small_area (point1, point2))        return (TRUE);      else        break;    }    p = p->next;  }  while ((p != point1) && (counter++ < min_outline_points));  /* Go from P2 to P1 */  p = point2;  counter = 0;  do {    if (is_same_edgept (point1, p)) {      return (is_small_area (point2, point1));    }    p = p->next;  }  while ((p != point2) && (counter++ < min_outline_points));  return (FALSE);}/********************************************************************** * is_small_area * * Test the area defined by a split accross this outline. **********************************************************************/int is_small_area(EDGEPT *point1, EDGEPT *point2) {  EDGEPT *p = point1->next;      /* Iterator */  int area = 0;  TPOINT origin;  do {                                 /* Go from P1 to P2 */    origin.x = p->pos.x - point1->pos.x;    origin.y = p->pos.y - point1->pos.y;    area += CROSS (origin, p->vec);    p = p->next;  }  while (!is_same_edgept (point2, p));  return (area < min_outline_area);}/********************************************************************** * pick_close_point * * Choose the edge point that is closest to the critical point.  This * point may not be exactly vertical from the critical point. **********************************************************************/EDGEPT *pick_close_point(EDGEPT *critical_point,                         EDGEPT *vertical_point,                         int *best_dist) {  EDGEPT *best_point = NULL;  int this_distance;  int found_better;  do {    found_better = FALSE;    this_distance = edgept_dist (critical_point, vertical_point);    if (this_distance <= *best_dist) {      if (!(same_point (critical_point->pos, vertical_point->pos) ||        same_point (critical_point->pos, vertical_point->next->pos)        || best_point != NULL        && same_point (best_point->pos, vertical_point->pos) ||      is_exterior_point (critical_point, vertical_point))) {        *best_dist = this_distance;        best_point = vertical_point;        if (vertical_creep)          found_better = TRUE;      }    }    vertical_point = vertical_point->next;  }  while (found_better == TRUE);  return (best_point);}/********************************************************************** * prioritize_points * * Find a list of edge points from the outer outline of this blob.  For * each of these points assign a priority.  Sort these points using a * heap structure so that they can be visited in order. **********************************************************************/void prioritize_points(TESSLINE *outline, POINT_GROUP points) {  EDGEPT *this_point;  EDGEPT *local_min = NULL;  EDGEPT *local_max = NULL;  this_point = outline->loop;  local_min = this_point;  local_max = this_point;  do {    if (debug_5)      cprintf ("(%3d,%3d)  min=%3d, max=%3d, dir=%2d, ang=%2.0f\n",        this_point->pos.x, this_point->pos.y,        (local_min ? local_min->pos.y : 999),      (local_max ? local_max->pos.y : 999),      direction (this_point), point_priority (this_point));    if (this_point->vec.y < 0) {                                 /* Look for minima */      if (local_max != NULL)        new_max_point(local_max, points);      else if (is_inside_angle (this_point))        add_point_to_list(points, this_point);      local_max = NULL;      local_min = this_point->next;    }    else if (this_point->vec.y > 0) {                                 /* Look for maxima */      if (local_min != NULL)        new_min_point(local_min, points);      else if (is_inside_angle (this_point))        add_point_to_list(points, this_point);      local_min = NULL;      local_max = this_point->next;    }    else {      /* Flat area */      if (local_max != NULL) {        if (local_max->prev->vec.y != 0) {          new_max_point(local_max, points);        }        local_max = this_point->next;        local_min = NULL;      }      else {        if (local_min->prev->vec.y != 0) {          new_min_point(local_min, points);        }        local_min = this_point->next;        local_max = NULL;      }    }                                 /* Next point */    this_point = this_point->next;  }  while (this_point != outline->loop);}/********************************************************************** * new_min_point * * Found a new minimum point try to decide whether to save it or not. * Return the new value for the local minimum.  If a point is saved then * the local minimum is reset to NULL. **********************************************************************/void new_min_point(EDGEPT *local_min, POINT_GROUP points) {  INT16 dir;  dir = direction (local_min);  if (dir < 0) {    add_point_to_list(points, local_min);    return;  }  if (dir == 0 && point_priority (local_min) < 0) {    add_point_to_list(points, local_min);    return;  }}/********************************************************************** * new_max_point * * Found a new minimum point try to decide whether to save it or not. * Return the new value for the local minimum.  If a point is saved then * the local minimum is reset to NULL. **********************************************************************/void new_max_point(EDGEPT *local_max, POINT_GROUP points) {  INT16 dir;  dir = direction (local_max);  if (dir > 0) {    add_point_to_list(points, local_max);    return;  }  if (dir == 0 && point_priority (local_max) < 0) {    add_point_to_list(points, local_max);    return;  }}/********************************************************************** * vertical_projection_point * * For one point on the outline, find the corresponding point on the * other side of the outline that is a likely projection for a split * point.  This is done by iterating through the edge points until the * X value of the point being looked at is greater than the X value of * the split point.  Ensure that the point being returned is not right * next to the split point.  Return the edge point as a result. **********************************************************************/void vertical_projection_point(EDGEPT *split_point, EDGEPT *target_point,                               EDGEPT** best_point) {  EDGEPT *p;                     /* Iterator */  EDGEPT *this_edgept;           /* Iterator */  int x = split_point->pos.x;    /* X value of vertical */  int best_dist = LARGE_DISTANCE;/* Best point found */  if (*best_point != NULL)    best_dist = edgept_dist(split_point, *best_point);  p = target_point;  /* Look at each edge point */  do {    if ((((p->pos.x <= x) && (x <= p->next->pos.x)) ||      ((p->next->pos.x <= x) && (x <= p->pos.x))) &&      !same_point (split_point->pos, p->pos) &&      !same_point (split_point->pos, p->next->pos)    && (*best_point == NULL || !same_point ((*best_point)->pos, p->pos))) {      this_edgept = near_point (split_point, p, p->next);      if (*best_point == NULL)        best_dist = edgept_dist (split_point, this_edgept);      this_edgept =        pick_close_point(split_point, this_edgept, &best_dist);      if (this_edgept)        *best_point = this_edgept;    }    p = p->next;  }  while (p != target_point);}

⌨️ 快捷键说明

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