WERD *make_ed_word( //construct word TWERD *tessword, //word to convert WERD *clone //clone this one ) { WERD *word; //converted word TBLOB *tblob; //current blob PBLOB *blob; //new blob PBLOB_LIST blobs; //list of blobs PBLOB_IT blob_it = &blobs; //iterator for (tblob = tessword->blobs; tblob != NULL; tblob = tblob->next) { blob = make_ed_blob (tblob); if (blob == NULL && tblob->outlines != NULL) { // Make a fake blob using the bounding box rectangle of the 1st outline. blob = MakeRectBlob(tblob->outlines); } if (blob != NULL) { blob_it.add_after_then_move (blob); } } if (!blobs.empty ()) word = new WERD (&blobs, clone); else word = NULL; return word; }
LIST call_matcher( //call a matcher TBLOB *ptblob, //previous TBLOB *tessblob, //blob to match TBLOB *ntblob, //next void *, //unused parameter TEXTROW * //always null anyway ) { PBLOB *pblob; //converted blob PBLOB *blob; //converted blob PBLOB *nblob; //converted blob LIST result; //tess output BLOB_CHOICE *choice; //current choice BLOB_CHOICE_LIST ratings; //matcher result BLOB_CHOICE_IT it; //iterator char choice_lengths[2] = {0, 0}; blob = make_ed_blob (tessblob);//convert blob if (blob == NULL) { // Since it is actually possible to get a NULL blob here, due to invalid // segmentations, fake a really bad classification. choice_lengths[0] = strlen(unicharset.id_to_unichar(1)); return append_choice(NULL, unicharset.id_to_unichar(1), choice_lengths, static_cast<float>(MAX_NUM_INT_FEATURES), static_cast<float>(kReallyBadCertainty), 0); } pblob = ptblob != NULL ? make_ed_blob (ptblob) : NULL; nblob = ntblob != NULL ? make_ed_blob (ntblob) : NULL; (*tess_matcher) (pblob, blob, nblob, tess_word, tess_denorm, ratings); //match it delete blob; //don't need that now if (pblob != NULL) delete pblob; if (nblob != NULL) delete nblob; it.set_to_list (&ratings); //get list result = NULL; for (it.mark_cycle_pt (); !it.cycled_list (); it.forward ()) { choice = it.data (); choice_lengths[0] = strlen(choice->unichar ()); result = append_choice (result, choice->unichar (), choice_lengths, choice->rating (), choice->certainty (), choice->config ()); } return result; //converted list }
/** * @name call_matcher * * Called from Tess with a blob in tess form. * Convert the blob to editor form. * Call the matcher setup by the segmenter in tess_matcher. * Convert the output choices back to tess form. */ BLOB_CHOICE_LIST *Wordrec::call_matcher(TBLOB *ptblob, //< previous blob TBLOB *tessblob, //< blob to match TBLOB *ntblob, //< next blob void *, //< unused parameter TEXTROW * //< always null anyway ) { PBLOB *pblob; //converted blob PBLOB *blob; //converted blob PBLOB *nblob; //converted blob BLOB_CHOICE_LIST *ratings = new BLOB_CHOICE_LIST(); // matcher result blob = make_ed_blob (tessblob);//convert blob if (blob == NULL) { // Since it is actually possible to get a NULL blob here, due to invalid // segmentations, fake a really bad classification. BLOB_CHOICE *choice = new BLOB_CHOICE(0, static_cast<float>(MAX_NUM_INT_FEATURES), static_cast<float>(-MAX_FLOAT32), 0, NULL); BLOB_CHOICE_IT temp_it; temp_it.set_to_list(ratings); temp_it.add_after_stay_put(choice); return ratings; } pblob = ptblob != NULL ? make_ed_blob (ptblob) : NULL; nblob = ntblob != NULL ? make_ed_blob (ntblob) : NULL; // Because of the typedef for tess_matcher, the object on which it is called // must be of type Tesseract*. With a Wordrec type it seems it doesn't work. (reinterpret_cast<Tesseract* const>(this)->*tess_matcher) (pblob, blob, nblob, tess_word, tess_denorm, ratings, NULL); //match it delete blob; //don't need that now if (pblob != NULL) delete pblob; if (nblob != NULL) delete nblob; return ratings; }
void call_train_tester( //call a tester TBLOB *tessblob, //blob to test BOOL8 correct_blob, //true if good char *text, //source text inT32 count, //chars in text LIST result //output of matcher ) { PBLOB *blob; //converted blob BLOB_CHOICE_LIST ratings; //matcher result blob = make_ed_blob (tessblob);//convert blob if (blob == NULL) return; //make it right type convert_choice_list(result, ratings); if (tess_trainer != NULL) (*tess_trainer) (blob, tess_denorm, correct_blob, text, count, &ratings); delete blob; //don't need that now }