📄 mfoutline.cpp
字号:
NormalizeOutline (Outline, LineStats, 0.0); } *XScale = *YScale = ComputeScaleFactor (LineStats); break; }} /* NormalizeOutlines *//*---------------------------------------------------------------------------*/void SettupBlobConversion(TBLOB *Blob) { /* ** Parameters: ** Blob blob that is to be converted ** Globals: ** BlobCenter center of blob to be converted ** Operation: Compute the center of the blob's bounding box and save ** it in a global variable. This routine must be called before ** any calls to ConvertOutline. It must be called once per ** blob. ** Return: none ** Exceptions: none ** History: Thu May 17 11:06:17 1990, DSJ, Created. */ ComputeBlobCenter(Blob, &BlobCenter); } /* SettupBlobConversion *//*---------------------------------------------------------------------------*/void SmearExtremities(MFOUTLINE Outline, FLOAT32 XScale, FLOAT32 YScale) { /* ** Parameters: ** Outline outline whose extremities are to be smeared ** XScale factor used to normalize outline in x dir ** YScale factor used to normalize outline in y dir ** Globals: none ** Operation: ** This routine smears the extremities of the specified outline. ** It does this by adding a random number between ** -0.5 and 0.5 pixels (that is why X/YScale are needed) to ** the x and y position of the point. This is done so that ** the discrete nature of the original scanned image does not ** affect the statistical clustering used during training. ** Return: none ** Exceptions: none ** History: 1/11/90, DSJ, Created. */ MFEDGEPT *Current; MFOUTLINE EdgePoint; FLOAT32 MinXSmear; FLOAT32 MaxXSmear; FLOAT32 MinYSmear; FLOAT32 MaxYSmear; if (Outline != NIL) { MinXSmear = -0.5 * XScale; MaxXSmear = 0.5 * XScale; MinYSmear = -0.5 * YScale; MaxYSmear = 0.5 * YScale; EdgePoint = Outline; do { Current = PointAt (EdgePoint); if (IsExtremity (Current)) { XPositionOf (Current) += UniformRandomNumber(MinXSmear, MaxXSmear); YPositionOf (Current) += UniformRandomNumber(MinYSmear, MaxYSmear); } EdgePoint = NextPointAfter (EdgePoint); } while (EdgePoint != Outline); }} /* SmearExtremities *//**---------------------------------------------------------------------------- Private Code----------------------------------------------------------------------------**//*---------------------------------------------------------------------------*/void ChangeDirection(MFOUTLINE Start, MFOUTLINE End, DIRECTION Direction) { /* ** Parameters: ** Start, End defines segment of outline to be modified ** Direction new direction to assign to segment ** Globals: none ** Operation: Change the direction of every vector in the specified ** outline segment to Direction. The segment to be changed ** starts at Start and ends at End. Note that the previous ** direction of End must also be changed to reflect the ** change in direction of the point before it. ** Return: none ** Exceptions: none ** History: Fri May 4 10:42:04 1990, DSJ, Created. */ MFOUTLINE Current; for (Current = Start; Current != End; Current = NextPointAfter (Current)) DirectionOf (PointAt (Current)) = Direction; PreviousDirectionOf (PointAt (End)) = Direction;} /* ChangeDirection *//*---------------------------------------------------------------------------*/void CharNormalizeOutline(MFOUTLINE Outline, FLOAT32 XCenter, FLOAT32 YCenter, FLOAT32 XScale, FLOAT32 YScale) {/* ** Parameters: ** Outline outline to be character normalized ** XCenter, YCenter center point for normalization ** XScale, YScale scale factors for normalization ** Globals: none ** Operation: This routine normalizes each point in Outline by ** translating it to the specified center and scaling it ** anisotropically according to the given scale factors. ** Return: none ** Exceptions: none ** History: Fri Dec 14 10:27:11 1990, DSJ, Created. */ MFOUTLINE First, Current; MFEDGEPT *CurrentPoint; if (Outline == NIL) return; First = Outline; Current = First; do { CurrentPoint = PointAt (Current); XPositionOf (CurrentPoint) = (XPositionOf (CurrentPoint) - XCenter) * XScale; YPositionOf (CurrentPoint) = (YPositionOf (CurrentPoint) - YCenter) * YScale; Current = NextPointAfter (Current); } while (Current != First);} /* CharNormalizeOutline *//*---------------------------------------------------------------------------*/void ComputeDirection(MFEDGEPT *Start, MFEDGEPT *Finish, FLOAT32 MinSlope, FLOAT32 MaxSlope) {/* ** Parameters: ** Start starting point to compute direction from ** Finish finishing point to compute direction to ** MinSlope slope below which lines are horizontal ** MaxSlope slope above which lines are vertical ** Globals: none ** Operation: ** This routine computes the slope from Start to Finish and ** and then computes the approximate direction of the line ** segment from Start to Finish. The direction is quantized ** into 8 buckets: ** N, S, E, W, NE, NW, SE, SW ** Both the slope and the direction are then stored into ** the appropriate fields of the Start edge point. The ** direction is also stored into the PreviousDirection field ** of the Finish edge point. ** Return: none ** Exceptions: none ** History: 7/25/89, DSJ, Created. */ FVECTOR Delta; Delta.x = Finish->Point.x - Start->Point.x; Delta.y = Finish->Point.y - Start->Point.y; if (Delta.x == 0) if (Delta.y < 0) { Start->Slope = -MAX_FLOAT32; Start->Direction = south; } else { Start->Slope = MAX_FLOAT32; Start->Direction = north; } else { Start->Slope = Delta.y / Delta.x; if (Delta.x > 0) if (Delta.y > 0) if (Start->Slope > MinSlope) if (Start->Slope < MaxSlope) Start->Direction = northeast; else Start->Direction = north; else Start->Direction = east; else if (Start->Slope < -MinSlope) if (Start->Slope > -MaxSlope) Start->Direction = southeast; else Start->Direction = south; else Start->Direction = east; else if (Delta.y > 0) if (Start->Slope < -MinSlope) if (Start->Slope > -MaxSlope) Start->Direction = northwest; else Start->Direction = north; else Start->Direction = west; else if (Start->Slope > MinSlope) if (Start->Slope < MaxSlope) Start->Direction = southwest; else Start->Direction = south; else Start->Direction = west; } Finish->PreviousDirection = Start->Direction;} /* ComputeDirection *//*---------------------------------------------------------------------------*/void FinishOutlineStats(register OUTLINE_STATS *OutlineStats) { /* ** Parameters: ** OutlineStats statistics about a set of outlines ** Globals: none ** Operation: Use the preliminary statistics accumulated in OutlineStats ** to compute the final statistics. ** (see Dan Johnson's Tesseract lab ** notebook #2, pgs. 74-78). ** Return: none ** Exceptions: none ** History: Fri Dec 14 10:13:36 1990, DSJ, Created. */ OutlineStats->x = 0.5 * OutlineStats->My / OutlineStats->L; OutlineStats->y = 0.5 * OutlineStats->Mx / OutlineStats->L; OutlineStats->Ix = (OutlineStats->Ix / 3.0 - OutlineStats->y * OutlineStats->Mx + OutlineStats->y * OutlineStats->y * OutlineStats->L); OutlineStats->Iy = (OutlineStats->Iy / 3.0 - OutlineStats->x * OutlineStats->My + OutlineStats->x * OutlineStats->x * OutlineStats->L); /* Ix and/or Iy could possibly be negative due to roundoff error */ if (OutlineStats->Ix < 0.0) OutlineStats->Ix = MIN_INERTIA; if (OutlineStats->Iy < 0.0) OutlineStats->Iy = MIN_INERTIA; OutlineStats->Rx = sqrt (OutlineStats->Ix / OutlineStats->L); OutlineStats->Ry = sqrt (OutlineStats->Iy / OutlineStats->L); OutlineStats->Mx *= 0.5; OutlineStats->My *= 0.5;} /* FinishOutlineStats *//*---------------------------------------------------------------------------*/void InitOutlineStats(OUTLINE_STATS *OutlineStats) { /* ** Parameters: ** OutlineStats stats data structure to be initialized ** Globals: none ** Operation: Initialize the outline statistics data structure so ** that it is ready to start accumulating statistics. ** Return: none ** Exceptions: none ** History: Fri Dec 14 08:55:22 1990, DSJ, Created. */ OutlineStats->Mx = 0.0; OutlineStats->My = 0.0; OutlineStats->L = 0.0; OutlineStats->x = 0.0; OutlineStats->y = 0.0; OutlineStats->Ix = 0.0; OutlineStats->Iy = 0.0; OutlineStats->Rx = 0.0; OutlineStats->Ry = 0.0;} /* InitOutlineStats *//*---------------------------------------------------------------------------*/MFOUTLINE NextDirectionChange(MFOUTLINE EdgePoint) { /* ** Parameters: ** EdgePoint start search from this point ** Globals: none ** Operation: ** This routine returns the next point in the micro-feature ** outline that has a direction different than EdgePoint. The ** routine assumes that the outline being searched is not a ** degenerate outline (i.e. it must have 2 or more edge points). ** Return: Point of next direction change in micro-feature outline. ** Exceptions: none ** History: 7/25/89, DSJ, Created. */ DIRECTION InitialDirection; InitialDirection = DirectionOf (PointAt (EdgePoint)); do EdgePoint = NextPointAfter (EdgePoint); while (DirectionOf (PointAt (EdgePoint)) == InitialDirection); return (EdgePoint);} /* NextDirectionChange *//*---------------------------------------------------------------------------*/void UpdateOutlineStats(register OUTLINE_STATS *OutlineStats, register FLOAT32 x1, register FLOAT32 x2, register FLOAT32 y1, register FLOAT32 y2) {/* ** Parameters: ** OutlineStats statistics to add this segment to ** x1, y1, x2, y2 segment to be added to statistics ** Globals: none ** Operation: This routine adds the statistics for the specified ** line segment to OutlineStats. The statistics that are ** kept are: ** sum of length of all segments ** sum of 2*Mx for all segments ** sum of 2*My for all segments ** sum of 2*Mx*(y1+y2) - L*y1*y2 for all segments ** sum of 2*My*(x1+x2) - L*x1*x2 for all segments ** These numbers, once collected can later be used to easily ** compute the center of mass, first and second moments, ** and radii of gyration. (see Dan Johnson's Tesseract lab ** notebook #2, pgs. 74-78). ** Return: none ** Exceptions: none ** History: Fri Dec 14 08:59:17 1990, DSJ, Created. */ register FLOAT64 L; register FLOAT64 Mx2; register FLOAT64 My2; /* compute length of segment */ L = sqrt ((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)); OutlineStats->L += L; /* compute 2Mx and 2My components */ Mx2 = L * (y1 + y2); My2 = L * (x1 + x2); OutlineStats->Mx += Mx2; OutlineStats->My += My2; /* compute second moment component */ OutlineStats->Ix += Mx2 * (y1 + y2) - L * y1 * y2; OutlineStats->Iy += My2 * (x1 + x2) - L * x1 * x2;} /* UpdateOutlineStats */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -