📄 li_recognizer.c
字号:
return(NULL);}static intli_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 intli_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 intli_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 intli_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 intli_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 xgestureli_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 voidfree_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 ELXextern 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 3typedef 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;static int lialg_preprocess_stroke(point_list *);static point_list *lialg_compute_dominant_points(point_list *);static point_list *lialg_interpolate_points(point_list *);static void lialg_bresline(pen_point *, pen_point *, point_list *, int *);static void lialg_compute_chain_code(point_list *);static void lialg_compute_unit_chain_code(point_list *);static region_list *lialg_compute_regions(point_list *);static point_list *lialg_compute_dompts(point_list *, region_list *);static int *lialg_compute_contour_angle_set(point_list *, region_list *);static void lialg_score_stroke(point_list *, point_list *, int *, int *);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -