📄 li_recognizer.c
字号:
li_recognizer_load_dictionary(recognizer rec,char* directory,char* name)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Dictionaries are not supported by the LI recognizer";
return(NULL);
}
static int
li_recognizer_save_dictionary(recognizer rec,
char* directory,
char* name,
wordset dict)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Dictionaries are not supported by the LI recognizer";
return(-1);
}
static int
li_recognizer_free_dictionary(recognizer rec,wordset dict)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Dictionaries are not supported by the LI recognizer";
return(-1);
}
static int
li_recognizer_add_to_dictionary(recognizer rec,letterset* word,wordset dict)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Dictionaries are not supported by the LI recognizer";
return(-1);
}
static int
li_recognizer_delete_from_dictionary(recognizer rec,
letterset* word,
wordset dict)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Dictionaries are not supported by the LI recognizer";
return(-1);
}
static char*
li_recognizer_error(recognizer rec)
{
char* ret = li_err_msg;
/*Check for LI recognizer.*/
if( !CHECK_LI_MAGIC(rec->recognizer_specific) ) {
li_err_msg = "Not a LI recognizer";
return(NULL);
}
li_err_msg = NULL;
return(ret);
}
static int
li_recognizer_clear(recognizer r,bool delete_points_p)
{
li_recognizer* rec;
rec = (li_recognizer*)r->recognizer_specific;
/*Check for LI recognizer.*/
if( !CHECK_LI_MAGIC(rec) ) {
li_err_msg = "Not a LI recognizer";
return(0);
}
return(0);
}
static int
li_recognizer_set_context(recognizer r,rc* rec_xt)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Contexts are not supported by the LI recognizer";
return(-1);
}
static rc*
li_recognizer_get_context(recognizer r)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Contexts are not supported by the LI recognizer";
return(NULL);
}
static int
li_recognizer_get_buffer(recognizer r, u_int* nstrokes,pen_stroke** strokes)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Buffer get/set are not supported by the LI recognizer";
return(-1);
}
static int
li_recognizer_set_buffer(recognizer r,u_int nstrokes,pen_stroke* strokes)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Buffer get/set are not supported by the LI recognizer";
return(-1);
}
static int
li_recognizer_translate(recognizer r,
u_int ncs,
pen_stroke* tps,
bool correlate_p,
int* nret,
rec_alternative** ret)
{
char* clss = NULL;
li_recognizer* rec;
int conf;
rClassifier* rc;
rec = (li_recognizer*)r->recognizer_specific;
*nret = 0;
*ret = NULL;
/*Check for LI recognizer.*/
if( !CHECK_LI_MAGIC(rec) ) {
li_err_msg = "Not a LI recognizer";
return(-1);
}
rc = &(rec->li_rc);
/*Check for valid parameters.*/
if (ncs < 1) {
li_err_msg = "Invalid parameters: ncs";
return(-1);
}
if( tps == NULL) {
li_err_msg = "Invalid parameters: tps";
return(-1);
}
if( nret == NULL) {
li_err_msg = "Invalid parameters: nret";
return(-1);
}
if( ret == NULL) {
li_err_msg = "Invalid parameters: ret";
return(-1);
}
/* if( ncs < 1 || tps == NULL || nret == NULL || ret == NULL) {
li_err_msg = "Invalid parameters";
return(-1);
}
*/
/*Check for null classifier. It must have at least one.*/
/*
if( rec->li_rc.sc == NULL ) {
li_err_msg = "No classifier";
return(-1);
}
*/
/*
* Go through the stroke array and recognize. Since this is a single
* stroke recognizer, each stroke is treated as a separate
* character or gesture. We allow only characters or gestures
* to be recognized at one time, since otherwise, handling
* the display of segmentation would be difficult.
*/
clss = recognize_internal(rc,tps,&conf);
if (clss == NULL) {
/*
li_err_msg = "unrecognized character";
return(-1);
*/
*nret = 1;
return(0);
}
/*Return values.*/
*nret = 1;
return(*clss);
}
static rec_fn*
li_recognizer_get_extension_functions(recognizer rec)
{
rec_fn* ret;
/*Check for LI recognizer.*/
if( !CHECK_LI_MAGIC(rec->recognizer_specific) ) {
li_err_msg = "Not a LI recognizer";
return(NULL);
}
ret = make_rec_fn_array(LI_NUM_EX_FNS);
/* ari -- clearState & getClasses are mine */
ret[LI_GET_CLASSES] = (rec_fn)recognizer_getClasses;
ret[LI_CLEAR] = (rec_fn)recognizer_clearState;
ret[LI_ISA_LI] = (rec_fn)isa_li;
ret[LI_TRAIN] = (rec_fn)recognizer_train;
return(ret);
}
static char**
li_recognizer_get_gesture_names(recognizer r)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Gestures are not supported by the LI recognizer";
return(NULL);
}
static xgesture
li_recognizer_set_gesture_action(recognizer r,
char* name,
xgesture fn,
void* wsinfo)
{
/*This operation isn't supported by the LI recognizer.*/
li_err_msg = "Gestures are not supported by the LI recognizer";
return(NULL);
}
/*
* Exported Functions
*/
/*RECOGNIZER_INITIALIZE-Initialize the recognizer.*/
/* note from ari: this expands via pre-processor to
*
* recognizer __recognizer_internal_initialize(rec_info* ri)
*/
RECOGNIZER_INITIALIZE(ri)
{
recognizer r;
li_recognizer* rec;
int i;
/*Check that locale matches.*/
if( strcmp(ri->ri_locale,LI_SUPPORTED_LOCALE) != 0 ) {
li_err_msg = "Not a supported locale";
fprintf(stderr, "Locale error.\n");
#if 0
return(NULL);
#endif
}
/*
* Check that character sets match. Note that this is only approximate,
* since the classifier file will have more information.
*/
if( ri->ri_subset != NULL ) {
for(i = 0; ri->ri_subset[i] != NULL; i++ ) {
if( strcmp(ri->ri_subset[i],UPPERCASE) != 0 &&
strcmp(ri->ri_subset[i],LOWERCASE) != 0 &&
strcmp(ri->ri_subset[i],DIGITS) != 0 &&
strcmp(ri->ri_subset[i],GESTURE) != 0 ) {
li_err_msg = "Not a supported character set";
fprintf(stderr, "charset error.\n");
return(NULL);
}
}
}
/* ari */
r = make_recognizer(ri);
/*fprintf(stderr, "past make_recognizer.\n");*/
if( r == NULL ) {
li_err_msg = "Can't allocate storage";
return(NULL);
}
/*Make a LI recognizer structure.*/
/* rec = (li_recognizer*)safe_malloc(sizeof(li_recognizer))) == NULL ); */
rec = allocate(1, li_recognizer);
r->recognizer_specific = rec;
rec->li_rc.file_name = NULL;
rec->li_rc.sc = NULL;
/*Initialize the recognizer struct.*/
r->recognizer_load_state = li_recognizer_load;
r->recognizer_save_state = li_recognizer_save;
r->recognizer_load_dictionary = li_recognizer_load_dictionary;
r->recognizer_save_dictionary = li_recognizer_save_dictionary;
r->recognizer_free_dictionary = li_recognizer_free_dictionary;
r->recognizer_add_to_dictionary = li_recognizer_add_to_dictionary;
r->recognizer_delete_from_dictionary = li_recognizer_delete_from_dictionary;
r->recognizer_error = li_recognizer_error;
r->recognizer_translate = li_recognizer_translate;
r->recognizer_get_context = li_recognizer_get_context;
r->recognizer_set_context = li_recognizer_set_context;
r->recognizer_get_buffer = li_recognizer_get_buffer;
r->recognizer_set_buffer = li_recognizer_set_buffer;
r->recognizer_clear = li_recognizer_clear;
r->recognizer_get_extension_functions =
li_recognizer_get_extension_functions;
r->recognizer_get_gesture_names = li_recognizer_get_gesture_names;
r->recognizer_set_gesture_action =
li_recognizer_set_gesture_action;
/*Initialize LI Magic Number.*/
rec->li_magic = LI_MAGIC;
/*Initialize rClassifier.*/
rec->li_rc.file_name = NULL;
for( i = 0; i < MAXSCLASSES; i++ ) {
rec->li_rc.ex[i] = NULL;
rec->li_rc.cnames[i] = NULL;
}
lialg_initialize(&rec->li_rc);
/*Get rid of error message. Not needed here.*/
li_err_msg = NULL;
return(r);
}
/*free_rClassifier-Free the rClassifier.*/
static void
free_rClassifier(rClassifier* rc)
{
int i;
if( rc->file_name != NULL) {
free(rc->file_name);
}
for( i = 0; rc->ex[i] != NULL; i++) {
delete_examples(rc->ex[i]);
free(rc->cnames[i]);
}
if(rc->sc != NULL ) {
sFreeClassifier(rc->sc);
}
}
/*RECOGNIZER_FINALIZE-Deallocate the recognizer, finalize.*/
RECOGNIZER_FINALIZE(r)
{
li_recognizer* rec = (li_recognizer*)r->recognizer_specific;
/*Make sure this is a li_recognizer first*/
if( !CHECK_LI_MAGIC(rec) ) {
li_err_msg = "Not a LI recognizer";
return(-1);
}
/*Deallocate rClassifier resources.*/
free_rClassifier(&(rec->li_rc));
/*Deallocate the li_recognizer struct.*/
free(rec);
/*Deallocate the recognizer*/
delete_recognizer(r);
return(0);
}
/* **************************************************
Implementation of the Li/Yeung recognition algorithm
************************************************** */
/*#include <assert.h>*/
#ifdef __ECOS
#define MAXINT 0x7FFFFFFF
#else
#include <values.h>
#endif
#include <sys/time.h>
#ifdef __ultrix
/* Ultrix doesn't have these declarations in math.h! */
extern double rint(double);
extern float expf(float);
#endif
#ifdef ELX
extern double rint (double);
extern float expf (float); /* N.B. exp() appears to be broken on ELX! */
#endif
#define WORST_SCORE MAXINT
/* Dynamic programming parameters */
#define DP_BAND 3
#define MIN_SIM 0
#define MAX_DIST MAXINT
#define SIM_THLD 60 /* x 100 */
#define DIST_THLD 3200 /* x 100 */
/* Low-pass filter parameters -- empirically derived */
#define LP_FILTER_WIDTH 6
#define LP_FILTER_ITERS 8
#define LP_FILTER_THLD 250 /* x 100 */
#define LP_FILTER_MIN 5
/* Pseudo-extrema parameters -- empirically derived */
#define PE_AL_THLD 1500 /* x 100 */
#define PE_ATCR_THLD 135 /* x 100 */
/* Contour-angle derivation parameters */
#define T_ONE 1
#define T_TWO 20
/* Pre-processing and canonicalization parameters */
#define CANONICAL_X 108
#define CANONICAL_Y 128
#define DIST_SQ_THRESHOLD (3*3) /* copied from fv.h */
#define NCANONICAL 50
/* Tap-handling parameters */
#define TAP_CHAR "."
#define TAP_TIME_THLD 150 /* msec */
#define TAP_DIST_THLD 75 /* dx * dx + dy * dy */
#define TAP_PATHLEN 1000 /* x 100 */
/* Overload the time field of the pen_point struct with the chain-code. */
#define chaincode time
/* region types */
#define RGN_CONVEX 0
#define RGN_CONCAVE 1
#define RGN_PLAIN 2
#define RGN_PSEUDO 3
typedef struct RegionList {
int start;
int end;
int type;
struct RegionList *next;
} region_list;
/* direction-code table; indexed by dx, dy */
static int lialg_dctbl[3][3] = {{1, 0, 7}, {2, 0x7FFFFFFF, 6}, {3, 4, 5}};
/* low-pass filter weights */
static int lialg_lpfwts[2 * LP_FILTER_WIDTH + 1];
static int lialg_lpfconst = -1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -