📄 mfoutline.cpp
字号:
/****************************************************************************** ** Filename: mfoutline.c ** Purpose: Interface to outline struct used for extracting features ** Author: Dan Johnson ** History: Thu May 17 08:14:18 1990, DSJ, Created. ** ** (c) Copyright Hewlett-Packard Company, 1988. ** 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. ******************************************************************************//**---------------------------------------------------------------------------- Include Files and Type Defines----------------------------------------------------------------------------**/#include "clusttool.h" //If remove you get cought in a loop somewhere#include "emalloc.h"#include "mfoutline.h"#include "debug.h"#include "hideedge.h"#include "blobs.h"#include "const.h"#include "mfx.h"#include <math.h>#include <stdio.h>#define MIN_INERTIA (0.00001)/**---------------------------------------------------------------------------- Private Function Prototypes----------------------------------------------------------------------------**//*#if defined(__STDC__) || defined(__cplusplus)# define _ARGS(s) s#else# define _ARGS(s) ()#endif*//* /users/danj/wiseowl/src/danj/microfeatures/mfoutline.cvoid ChangeDirection _ARGS((MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction));void CharNormalizeOutline _ARGS((MFOUTLINE Outline, OUTLINE_STATS *OutlineStats));void ComputeDirection _ARGS((MFEDGEPT *Start, MFEDGEPT *Finish, FLOAT32 MinSlope, FLOAT32 MaxSlope));void FinishOutlineStats _ARGS((OUTLINE_STATS *OutlineStats));void InitOutlineStats _ARGS((OUTLINE_STATS *OutlineStats));MFOUTLINE NextDirectionChange _ARGS((MFOUTLINE EdgePoint));void UpdateOutlineStats _ARGS((OUTLINE_STATS *OutlineStats, FLOAT32 x1, FLOAT32 y1, FLOAT32 x2, FLOAT32 y2));#undef _ARGS*//**---------------------------------------------------------------------------- Global Data Definitions and Declarations----------------------------------------------------------------------------**//* center of current blob being processed - used when "unexpanding" expanded blobs */static TPOINT BlobCenter;/* control knobs used to control normalization of outlines */make_int_var (NormMethod, character, MakeNormMethod,15, 10, SetNormMethod, "Normalization Method ...")/* PREV DEFAULT "baseline" */make_float_var (CharNormRange, 0.2, MakeCharNormRange,15, 11, SetCharNormRange, "Character Normalization Range ...")make_float_var (MinNormScaleX, 0.0, MakeMinNormScaleX,15, 12, SetMinNormScaleX, "Min char x-norm scale ...")/* PREV DEFAULT 0.1 */make_float_var (MaxNormScaleX, 0.325, MakeMaxNormScaleX,15, 13, SetMaxNormScaleX, "Max char x-norm scale ...")/* PREV DEFAULT 0.3 */make_float_var (MinNormScaleY, 0.0, MakeMinNormScaleY,15, 14, SetMinNormScaleY, "Min char y-norm scale ...")/* PREV DEFAULT 0.1 */make_float_var (MaxNormScaleY, 0.325, MakeMaxNormScaleY,15, 15, SetMaxNormScaleY, "Max char y-norm scale ...")/* PREV DEFAULT 0.3 *//**---------------------------------------------------------------------------- Public Code----------------------------------------------------------------------------**//*---------------------------------------------------------------------------*/void ComputeBlobCenter(TBLOB *Blob, TPOINT *BlobCenter) { /* ** Parameters: ** Blob blob to compute centerpoint of ** BlobCenter data struct to place results in ** Globals: none ** Operation: ** This routine computes the center point of the specified ** blob using the bounding box of all top level outlines in the ** blob. The center point is computed in a coordinate system ** which is scaled up by VECSCALE from the page coordinate ** system. ** Return: none ** Exceptions: none ** History: Fri Sep 8 10:45:39 1989, DSJ, Created. */ TPOINT TopLeft; TPOINT BottomRight; blob_bounding_box(Blob, &TopLeft, &BottomRight); BlobCenter->x = ((TopLeft.x << VECSCALE) + (BottomRight.x << VECSCALE)) / 2; BlobCenter->y = ((TopLeft.y << VECSCALE) + (BottomRight.y << VECSCALE)) / 2;} /* ComputeBlobCenter *//*---------------------------------------------------------------------------*/LIST ConvertBlob(TBLOB *Blob) { /* ** Parameters: ** Blob blob to be converted ** Globals: none ** Operation: Convert Blob into a list of outlines. ** Return: List of outlines representing blob. ** Exceptions: none ** History: Thu Dec 13 15:40:17 1990, DSJ, Created. */ LIST ConvertedOutlines = NIL; if (Blob != NULL) { SettupBlobConversion(Blob); //ComputeBlobCenter (Blob, &BlobCenter); ConvertedOutlines = ConvertOutlines (Blob->outlines, ConvertedOutlines, outer); } return (ConvertedOutlines);} /* ConvertBlob *//*---------------------------------------------------------------------------*/MFOUTLINE ConvertOutline(TESSLINE *Outline) { /* ** Parameters: ** Outline outline to be converted ** Globals: ** BlobCenter pre-computed center of current blob ** Operation: ** This routine converts the specified outline into a special ** data structure which is used for extracting micro-features. ** If the outline has been pre-normalized by the splitter, ** then it is assumed to be in expanded form and all we must ** do is copy the points. Otherwise, ** if the outline is expanded, then the expanded form is used ** and the coordinates of the points are returned to page ** coordinates using the global variable BlobCenter and the ** scaling factor REALSCALE. If the outline is not expanded, ** then the compressed form is used. ** Return: Outline converted into special micro-features format. ** Exceptions: none ** History: 8/2/89, DSJ, Created. ** 9/8/89, DSJ, Added ability to convert expanded blobs. ** 1/11/90, DSJ, Changed to use REALSCALE instead of VECSCALE ** to eliminate round-off problems. ** 2/21/91, DSJ, Added ability to work with pre-normalized ** blobs. ** 4/30/91, DSJ, Added concept of "hidden" segments. */ register BYTEVEC *Vector; TPOINT Position; TPOINT StartPosition; MFEDGEPT *NewPoint; MFOUTLINE MFOutline = NIL; EDGEPT *EdgePoint; EDGEPT *StartPoint; EDGEPT *NextPoint; if (Outline == NULL || (Outline->compactloop == NULL && Outline->loop == NULL)) return (MFOutline); /* have outlines been prenormalized */ if (is_baseline_normalized ()) { StartPoint = Outline->loop; EdgePoint = StartPoint; do { NextPoint = EdgePoint->next; /* filter out duplicate points */ if (EdgePoint->pos.x != NextPoint->pos.x || EdgePoint->pos.y != NextPoint->pos.y) { NewPoint = NewEdgePoint (); ClearMark(NewPoint); IsHidden (NewPoint) = is_hidden_edge (EdgePoint) ? TRUE : FALSE; XPositionOf (NewPoint) = EdgePoint->pos.x; YPositionOf (NewPoint) = EdgePoint->pos.y; MFOutline = push (MFOutline, NewPoint); } EdgePoint = NextPoint; } while (EdgePoint != StartPoint); } /* use compressed version of outline */ else if (Outline->loop == NULL) { Xof (Position) = Xof (StartPosition) = Outline->start.x; Yof (Position) = Yof (StartPosition) = Outline->start.y; Vector = Outline->compactloop; do { if (Vector->dx != 0 || Vector->dy != 0) { NewPoint = NewEdgePoint (); ClearMark(NewPoint); /* all edges are visible */ IsHidden (NewPoint) = FALSE; CopyPoint (Position, PositionOf (NewPoint)); MFOutline = push (MFOutline, NewPoint); } Xof (Position) += Vector->dx; Yof (Position) += Vector->dy; Vector++; } while ((Xof (Position) != Xof (StartPosition)) || (Yof (Position) != Yof (StartPosition))); } else { /* use expanded version of outline */ StartPoint = Outline->loop; EdgePoint = StartPoint; do { NextPoint = EdgePoint->next; /* filter out duplicate points */ if (EdgePoint->pos.x != NextPoint->pos.x || EdgePoint->pos.y != NextPoint->pos.y) { NewPoint = NewEdgePoint (); ClearMark(NewPoint); IsHidden (NewPoint) = is_hidden_edge (EdgePoint) ? TRUE : FALSE; XPositionOf (NewPoint) = (EdgePoint->pos.x + BlobCenter.x) / REALSCALE; YPositionOf (NewPoint) = (EdgePoint->pos.y + BlobCenter.y) / REALSCALE; MFOutline = push (MFOutline, NewPoint); } EdgePoint = NextPoint; } while (EdgePoint != StartPoint); } MakeOutlineCircular(MFOutline); return (MFOutline);} /* ConvertOutline *//*---------------------------------------------------------------------------*/LIST ConvertOutlines(TESSLINE *Outline, LIST ConvertedOutlines, OUTLINETYPE OutlineType) {/* ** Parameters: ** Outline first outline to be converted ** ConvertedOutlines list to add converted outlines to ** OutlineType are the outlines outer or holes? ** Globals: none ** Operation: ** This routine converts all given outlines into a new format. ** of outlines. Outline points to a list of the top level ** outlines to be converted. The children of these outlines ** are also recursively converted. All converted outlines ** are added to ConvertedOutlines. This is a list of outlines, ** one for each outline that was converted. ** Return: Updated list of converted outlines. ** Exceptions: none ** History: Thu Dec 13 15:57:38 1990, DSJ, Created. */ MFOUTLINE MFOutline; while (Outline != NULL) { if (Outline->child != NULL) if (OutlineType == outer) ConvertedOutlines = ConvertOutlines (Outline->child, ConvertedOutlines, hole); else ConvertedOutlines = ConvertOutlines (Outline->child, ConvertedOutlines, outer); MFOutline = ConvertOutline (Outline); ConvertedOutlines = push (ConvertedOutlines, MFOutline); Outline = Outline->next; } return (ConvertedOutlines);} /* ConvertOutlines *//*---------------------------------------------------------------------------*/void ComputeOutlineStats(LIST Outlines, OUTLINE_STATS *OutlineStats) { /* ** Parameters: ** Outlines list of outlines to compute stats for ** OutlineStats place to put results ** Globals: none ** Operation: This routine computes several statistics about the outlines ** in Outlines. These statistics are usually used to perform ** anistropic normalization of all of the outlines. The ** statistics generated are: ** first moments about x and y axes ** total length of all outlines ** center of mass of all outlines ** second moments about center of mass axes ** radius of gyration about center of mass axes ** Return: none (results are returned in OutlineStats) ** Exceptions: none ** History: Fri Dec 14 08:32:03 1990, DSJ, Created. */ MFOUTLINE Outline; MFOUTLINE EdgePoint; MFEDGEPT *Current; MFEDGEPT *Last; InitOutlineStats(OutlineStats); iterate(Outlines) { Outline = (MFOUTLINE) first (Outlines); Last = PointAt (Outline); Outline = NextPointAfter (Outline); EdgePoint = Outline; do { Current = PointAt (EdgePoint); UpdateOutlineStats (OutlineStats, XPositionOf (Last), YPositionOf (Last), XPositionOf (Current), YPositionOf (Current)); Last = Current; EdgePoint = NextPointAfter (EdgePoint); } while (EdgePoint != Outline); } FinishOutlineStats(OutlineStats); } /* ComputeOutlineStats *//*---------------------------------------------------------------------------*/void FilterEdgeNoise(MFOUTLINE Outline, FLOAT32 NoiseSegmentLength) { /* ** Parameters: ** Outline outline to be filtered
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -