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

📄 mergenf.cpp

📁 一OCR的相关资料。.希望对研究OCR的朋友有所帮助.
💻 CPP
字号:
/********************************************************************************	Filename:    MergeNF.c**	Purpose:     Program for merging similar nano-feature protos**	Author:      Dan Johnson**	History:     Wed Nov 21 09:55:23 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 "mergenf.h"#include "general.h"#include "efio.h"#include "clusttool.h"#include "cluster.h"#include "oldlist.h"#include "protos.h"#include "minmax.h"#include "ocrfeatures.h"#include "debug.h"#include "const.h"#include "featdefs.h"#include "intproto.h"#include <stdio.h>#include <string.h>#include <math.h>/**----------------------------------------------------------------------------					Variables-----------------------------------------------------------------------------**//*-------------------once in subfeat---------------------------------*/make_float_var (AngleMatchScale, 1.0, MakeAngleMatchScale,                7, 2, SetAngleMatchScale,  "Angle Match Scale ...")make_float_var (SimilarityMidpoint, 0.0075, MakeSimilarityMidpoint,                7, 3, SetSimilarityMidpoint,  "Similarity Midpoint ...")make_float_var (SimilarityCurl, 2.0, MakeSimilarityCurl,                7, 4, SetSimilarityCurl,  "Similarity Curl ...")/*-----------------------------once in fasttrain----------------------------------*/make_float_var (TangentBBoxPad, 0.5, MakeTangentBBoxPad,                15, 3, SetTangentBBoxPad,  "Tangent bounding box pad ...")make_float_var (OrthogonalBBoxPad, 2.5, MakeOrthogonalBBoxPad,                15, 4, SetOrthogonalBBoxPad,  "Orthogonal bounding box pad ...")make_float_var (AnglePad, 45.0, MakeAnglePad,                15, 5, SetAnglePad,  "Angle pad ...")/**----------------------------------------------------------------------------		  		Global Data Definitions and Declarations----------------------------------------------------------------------------**///int row_number;			/* kludge due to linking problems *//**----------------------------------------------------------------------------							Public Code----------------------------------------------------------------------------**//*---------------------------------------------------------------------------*/FLOAT32 CompareProtos (     PROTO	p1,	 PROTO	p2)/***	Parameters:**		p1, p2		protos to be compared**	Globals: none**	Operation: Compare protos p1 and p2 and return an estimate of the**		worst evidence rating that will result for any part of p1**		that is compared to p2.  In other words, if p1 were broken**		into pico-features and each pico-feature was matched to p2,**		what is the worst evidence rating that will be achieved for**		any pico-feature.**	Return: Worst possible result when matching p1 to p2.**	Exceptions: none**	History: Mon Nov 26 08:27:53 1990, DSJ, Created.*/{	FEATURE	Feature;	FLOAT32	WorstEvidence = WORST_EVIDENCE;	FLOAT32	Evidence;	FLOAT32	Angle, Length;	/* if p1 and p2 are not close in length, don't let them match */	Length = fabs (ProtoLength (p1) - ProtoLength (p2));	if (Length > MAX_LENGTH_MISMATCH)		return (0.0);	/* create a dummy pico-feature to be used for comparisons */	Feature = NewFeature (&PicoFeatDesc);	ParamOf (Feature, PicoFeatDir) = ProtoAngle (p1);	/* convert angle to radians */	Angle = ProtoAngle (p1) * 2.0 * PI;	/* find distance from center of p1 to 1/2 picofeat from end */	Length = ProtoLength (p1) / 2.0 - GetPicoFeatureLength () / 2.0;	if (Length < 0) Length = 0;	/* set the dummy pico-feature at one end of p1 and match it to p2 */	ParamOf (Feature, PicoFeatX) = ProtoX (p1) + cos (Angle) * Length;	ParamOf (Feature, PicoFeatY) = ProtoY (p1) + sin (Angle) * Length;	if (DummyFastMatch (Feature, p2))    {		Evidence = SubfeatureEvidence (Feature, p2);		if (Evidence < WorstEvidence)			WorstEvidence = Evidence;    }	else    {		FreeFeature (Feature);		return (0.0);    }	/* set the dummy pico-feature at the other end of p1 and match it to p2 */	ParamOf (Feature, PicoFeatX) = ProtoX (p1) - cos (Angle) * Length;	ParamOf (Feature, PicoFeatY) = ProtoY (p1) - sin (Angle) * Length;	if (DummyFastMatch (Feature, p2))    {		Evidence = SubfeatureEvidence (Feature, p2);		if (Evidence < WorstEvidence)			WorstEvidence = Evidence;    }	else    {		FreeFeature (Feature);		return (0.0);    }	FreeFeature (Feature);	return (WorstEvidence);}	/* CompareProtos *//*---------------------------------------------------------------------------*/void ComputeMergedProto (     PROTO	p1,	 PROTO	p2,     FLOAT32	w1,	 FLOAT32	w2,     PROTO	MergedProto)/***	Parameters:**		p1, p2		protos to be merged**		w1, w2		weight of each proto**		MergedProto	place to put resulting merged proto**	Globals: none**	Operation: This routine computes a proto which is the weighted**		average of protos p1 and p2.  The new proto is returned**		in MergedProto.**	Return: none (results are returned in MergedProto)**	Exceptions: none**	History: Mon Nov 26 08:15:08 1990, DSJ, Created.*/{	FLOAT32	TotalWeight;	TotalWeight = w1 + w2;	w1 /= TotalWeight;	w2 /= TotalWeight;	ProtoX      (MergedProto) = ProtoX      (p1) * w1 + ProtoX      (p2) * w2;	ProtoY      (MergedProto) = ProtoY      (p1) * w1 + ProtoY      (p2) * w2;	ProtoLength (MergedProto) = ProtoLength (p1) * w1 + ProtoLength (p2) * w2;	ProtoAngle  (MergedProto) = ProtoAngle  (p1) * w1 + ProtoAngle  (p2) * w2;	FillABC     (MergedProto);}	/* ComputeMergedProto *//*---------------------------------------------------------------------------*/int FindClosestExistingProto (     CLASS_TYPE	Class,     int       	NumMerged[],     PROTOTYPE	*Prototype)/***	Parameters:**		Class		class to search for matching old proto in**		NumMerged[]	# of protos merged into each proto of Class**		Prototype	new proto to find match for**	Globals: none**	Operation: This routine searches thru all of the prototypes in**		Class and returns the id of the proto which would provide**		the best approximation of Prototype.  If no close**		approximation can be found, NO_PROTO is returned.**	Return: Id of closest proto in Class or NO_PROTO.**	Exceptions: none**	History: Sat Nov 24 11:42:58 1990, DSJ, Created.*/{	PROTO_STRUCT	NewProto;	PROTO_STRUCT	MergedProto;	int		Pid;	PROTO		Proto;	int		BestProto;	FLOAT32	BestMatch;	FLOAT32	Match, OldMatch, NewMatch;	MakeNewFromOld (&NewProto, Prototype);	BestProto = NO_PROTO;	BestMatch = WORST_MATCH_ALLOWED;	for (Pid = 0; Pid < NumProtosIn (Class); Pid++)    {		Proto  = ProtoIn (Class, Pid);		ComputeMergedProto (Proto, &NewProto,			(FLOAT32) NumMerged[Pid], 1.0, &MergedProto);		OldMatch = CompareProtos (Proto, &MergedProto);		NewMatch = CompareProtos (&NewProto, &MergedProto);		Match = MIN (OldMatch, NewMatch);		if (Match > BestMatch)		{			BestProto = Pid;			BestMatch = Match;		}    }	return (BestProto);}	/* FindClosestExistingProto *//*---------------------------------------------------------------------------*/void MakeNewFromOld (     PROTO	New,     PROTOTYPE	*Old)/***	Parameters:**		New	new proto to be filled in**		Old	old proto to be converted**	Globals: none**	Operation: This fills in the fields of the New proto based on the**		fields of the Old proto.**	Return: none**	Exceptions: none**	History: Mon Nov 26 09:45:39 1990, DSJ, Created.*/{	ProtoX      (New) = CenterX       (Old->Mean);	ProtoY      (New) = CenterY       (Old->Mean);	ProtoLength (New) = LengthOf      (Old->Mean);	ProtoAngle  (New) = OrientationOf (Old->Mean);	FillABC     (New);}	/* MakeNewFromOld *//*-------------------once in subfeat---------------------------------*//*********************************************************************** InitSubfeatureVars** Create and set up all menus and variables needed for this file.**********************************************************************/void InitSubfeatureVars (){	MakeAngleMatchScale     ();	MakeSimilarityCurl      ();	MakeSimilarityMidpoint  ();}/*********************************************************************** SubfeatureEvidence** Compare a feature to a prototype. Print the result.**********************************************************************/FLOAT32 SubfeatureEvidence (   FEATURE     Feature,   PROTO       Proto){	float       Distance;	float       Dangle;	Dangle   = ProtoAngle (Proto) - ParamOf(Feature, PicoFeatDir);	if (Dangle < -0.5) Dangle += 1.0;	if (Dangle >  0.5) Dangle -= 1.0;	Dangle   *= AngleMatchScale;	Distance = CoefficientA (Proto) * ParamOf(Feature, PicoFeatX) +		CoefficientB (Proto) * ParamOf(Feature, PicoFeatY) +		CoefficientC (Proto);	return (EvidenceOf (Distance * Distance + Dangle * Dangle));}/*********************************************************************** EvidenceOf** Return the new type of evidence number corresponding to this* distance value.  This number is no longer based on the chi squared* approximation.  The equation that represents the transform is:*       1 / (1 + (sim / midpoint) ^ curl)**********************************************************************/FLOAT32 EvidenceOf (  register FLOAT32   Similarity){	Similarity /= SimilarityMidpoint;	if (SimilarityCurl == 3)		Similarity = Similarity * Similarity * Similarity;	else if (SimilarityCurl == 2)		Similarity = Similarity * Similarity;	else		Similarity = pow (Similarity, SimilarityCurl);	return (1.0 / (1.0 + Similarity));}/*-----------------------------once in fasttrain----------------------------------*/void InitFastTrainerVars ()/***	Parameters: none**	Globals: none**	Operation: This routine initializes all of the control variables**		for the fast trainer.**	Return: none**	Exceptions: none**	History: Mon Nov 12 13:27:35 1990, DSJ, Created.*/{	MakeTangentBBoxPad ();	MakeOrthogonalBBoxPad ();	MakeAnglePad ();}	/* InitFastTrainerVars *//*---------------------------------------------------------------------------*/BOOL8 DummyFastMatch (     FEATURE	Feature,     PROTO	Proto)/***	Parameters:**		Feature		feature to be "fast matched" to proto**		Proto		proto being "fast matched" against**	Globals:**		TangentBBoxPad		bounding box pad tangent to proto**		OrthogonalBBoxPad	bounding box pad orthogonal to proto**	Operation: This routine returns TRUE if Feature would be matched**		by a fast match table built from Proto.**	Return: TRUE if feature could match Proto.**	Exceptions: none**	History: Wed Nov 14 17:19:58 1990, DSJ, Created.*/{	FRECT		BoundingBox;	FLOAT32	MaxAngleError;	FLOAT32	AngleError;	MaxAngleError = AnglePad / 360.0;	AngleError = fabs (ProtoAngle (Proto) - ParamOf (Feature, PicoFeatDir));	if (AngleError > 0.5)		AngleError = 1.0 - AngleError;	if (AngleError > MaxAngleError)		return (FALSE);	ComputePaddedBoundingBox (Proto,		TangentBBoxPad * GetPicoFeatureLength (),		OrthogonalBBoxPad * GetPicoFeatureLength (),		&BoundingBox);	return (PointInside (&BoundingBox,		ParamOf (Feature, PicoFeatX),		ParamOf (Feature, PicoFeatY)));}	/* DummyFastMatch *//*----------------------------------------------------------------------------*/void ComputePaddedBoundingBox (     PROTO	Proto,     FLOAT32	TangentPad,	 FLOAT32	OrthogonalPad,     FRECT	*BoundingBox)/***	Parameters:**		Proto		proto to compute bounding box for**		TangentPad	amount of pad to add in direction of segment**		OrthogonalPad	amount of pad to add orthogonal to segment**		BoundingBox	place to put results**	Globals: none**	Operation: This routine computes a bounding box that encloses the**		specified proto along with some padding.  The**		amount of padding is specified as separate distances**		in the tangential and orthogonal directions.**	Return: none (results are returned in BoundingBox)**	Exceptions: none**	History: Wed Nov 14 14:55:30 1990, DSJ, Created.*/{	FLOAT32	Pad, Length, Angle;	FLOAT32	CosOfAngle, SinOfAngle;	Length     = ProtoLength (Proto) / 2.0 + TangentPad;	Angle      = ProtoAngle (Proto) * 2.0 * PI;	CosOfAngle = fabs (cos (Angle));	SinOfAngle = fabs (sin (Angle));	Pad = MAX (CosOfAngle * Length, SinOfAngle * OrthogonalPad);	BoundingBox->MinX = ProtoX (Proto) - Pad;	BoundingBox->MaxX = ProtoX (Proto) + Pad;	Pad = MAX (SinOfAngle * Length, CosOfAngle * OrthogonalPad);	BoundingBox->MinY = ProtoY (Proto) - Pad;	BoundingBox->MaxY = ProtoY (Proto) + Pad;}	/* ComputePaddedBoundingBox *//*--------------------------------------------------------------------------*/BOOL8 PointInside (     FRECT	*Rectangle,     FLOAT32	X,	 FLOAT32	Y)/***	Parameters:**	Globals: none**	Operation: Return TRUE if point (X,Y) is inside of Rectangle.**	Return:  Return TRUE if point (X,Y) is inside of Rectangle.**	Exceptions: none**	History: Wed Nov 14 17:26:35 1990, DSJ, Created.*/{	if (X < Rectangle->MinX) return (FALSE);	if (X > Rectangle->MaxX) return (FALSE);	if (Y < Rectangle->MinY) return (FALSE);	if (Y > Rectangle->MaxY) return (FALSE);	return (TRUE);}	/* PointInside */

⌨️ 快捷键说明

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