/*! * \brief recogCreateDid() * * \param[in] recog * \param[in] pixs of 1 bpp image to match * \return 0 if OK, 1 on error */ l_int32 recogCreateDid(L_RECOG *recog, PIX *pixs) { l_int32 i; PIX *pixt; L_RDID *did; PROCNAME("recogCreateDid"); if (!recog) return ERROR_INT("recog not defined", procName, 1); if (!pixs) return ERROR_INT("pixs not defined", procName, 1); recogDestroyDid(recog); did = (L_RDID *)LEPT_CALLOC(1, sizeof(L_RDID)); recog->did = did; did->pixs = pixClone(pixs); did->narray = recog->setsize; did->size = pixGetWidth(pixs); did->natempl = numaCreate(5); did->naxloc = numaCreate(5); did->nadely = numaCreate(5); did->nawidth = numaCreate(5); did->nascore = numaCreate(5); did->natempl_r = numaCreate(5); did->naxloc_r = numaCreate(5); did->nadely_r = numaCreate(5); did->nawidth_r = numaCreate(5); did->nascore_r = numaCreate(5); /* Make the arrays */ did->setwidth = (l_int32 *)LEPT_CALLOC(did->narray, sizeof(l_int32)); did->counta = (l_int32 **)LEPT_CALLOC(did->narray, sizeof(l_int32 *)); did->delya = (l_int32 **)LEPT_CALLOC(did->narray, sizeof(l_int32 *)); did->beta = (l_float32 *)LEPT_CALLOC(5, sizeof(l_float32)); did->gamma = (l_float32 *)LEPT_CALLOC(5, sizeof(l_float32)); did->trellisscore = (l_float32 *)LEPT_CALLOC(did->size, sizeof(l_float32)); did->trellistempl = (l_int32 *)LEPT_CALLOC(did->size, sizeof(l_int32)); for (i = 0; i < did->narray; i++) { did->counta[i] = (l_int32 *)LEPT_CALLOC(did->size, sizeof(l_int32)); did->delya[i] = (l_int32 *)LEPT_CALLOC(did->size, sizeof(l_int32)); } /* Populate the setwidth array */ for (i = 0; i < did->narray; i++) { pixt = pixaGetPix(recog->pixa_u, i, L_CLONE); did->setwidth[i] = (l_int32)(SetwidthFraction * pixGetWidth(pixt)); pixDestroy(&pixt); } return 0; }
/*! * recogDestroy() * * Input: &recog (<will be set to null before returning>) * Return: void * * Notes: * (1) If a recog has a parent, the parent owns it. A recogDestroy() * will fail if there is a parent. */ void recogDestroy(L_RECOG **precog) { L_RECOG *recog; PROCNAME("recogDestroy"); if (!precog) { L_WARNING("ptr address is null\n", procName); return; } if ((recog = *precog) == NULL) return; if (recogGetParent(recog) != NULL) { L_ERROR("recog has parent; can't be destroyed\n", procName); return; } FREE(recog->bootdir); FREE(recog->bootpattern); FREE(recog->bootpath); FREE(recog->centtab); FREE(recog->sumtab); FREE(recog->fname); sarrayDestroy(&recog->sa_text); l_dnaDestroy(&recog->dna_tochar); pixaaDestroy(&recog->pixaa_u); pixaDestroy(&recog->pixa_u); ptaaDestroy(&recog->ptaa_u); ptaDestroy(&recog->pta_u); numaDestroy(&recog->nasum_u); numaaDestroy(&recog->naasum_u); pixaaDestroy(&recog->pixaa); pixaDestroy(&recog->pixa); ptaaDestroy(&recog->ptaa); ptaDestroy(&recog->pta); numaDestroy(&recog->nasum); numaaDestroy(&recog->naasum); pixaDestroy(&recog->pixa_tr); pixaDestroy(&recog->pixadb_ave); pixaDestroy(&recog->pixa_id); pixDestroy(&recog->pixdb_ave); pixDestroy(&recog->pixdb_range); pixaDestroy(&recog->pixadb_boot); pixaDestroy(&recog->pixadb_split); FREE(recog->fontdir); bmfDestroy(&recog->bmf); rchDestroy(&recog->rch); rchaDestroy(&recog->rcha); recogDestroyDid(recog); FREE(recog); *precog = NULL; return; }
/*! * \brief recogDestroy() * * \param[in,out] precog will be set to null before returning * \return void */ void recogDestroy(L_RECOG **precog) { L_RECOG *recog; PROCNAME("recogDestroy"); if (!precog) { L_WARNING("ptr address is null\n", procName); return; } if ((recog = *precog) == NULL) return; LEPT_FREE(recog->centtab); LEPT_FREE(recog->sumtab); sarrayDestroy(&recog->sa_text); l_dnaDestroy(&recog->dna_tochar); pixaaDestroy(&recog->pixaa_u); pixaDestroy(&recog->pixa_u); ptaaDestroy(&recog->ptaa_u); ptaDestroy(&recog->pta_u); numaDestroy(&recog->nasum_u); numaaDestroy(&recog->naasum_u); pixaaDestroy(&recog->pixaa); pixaDestroy(&recog->pixa); ptaaDestroy(&recog->ptaa); ptaDestroy(&recog->pta); numaDestroy(&recog->nasum); numaaDestroy(&recog->naasum); pixaDestroy(&recog->pixa_tr); pixaDestroy(&recog->pixadb_ave); pixaDestroy(&recog->pixa_id); pixDestroy(&recog->pixdb_ave); pixDestroy(&recog->pixdb_range); pixaDestroy(&recog->pixadb_boot); pixaDestroy(&recog->pixadb_split); bmfDestroy(&recog->bmf); rchDestroy(&recog->rch); rchaDestroy(&recog->rcha); recogDestroyDid(recog); LEPT_FREE(recog); *precog = NULL; return; }
/*! * \brief recogMakeDecodingArrays() * * \param[in] recog with LUT's pre-computed * \param[in] pixs typically of multiple touching characters, 1 bpp * \param[in] debug 1 for debug output; 0 otherwise * \return 0 if OK, 1 on error * * <pre> * Notes: * (1) Generates the bit-and sum arrays for each character template * along pixs. These are used in the dynamic programming step. * (2) Previous arrays are destroyed and the new arrays are allocated. * (3) The values are saved in the scoring arrays at the left edge * of the template. They are used in the viterbi process * at the setwidth position (which is near the RHS of the template * as it is positioned on pixs) in the generated trellis. * </pre> */ l_int32 recogMakeDecodingArrays(L_RECOG *recog, PIX *pixs, l_int32 debug) { l_int32 i; PIX *pix1; L_RDID *did; PROCNAME("recogMakeDecodingArrays"); if (!recog) return ERROR_INT("recog not defined", procName, 1); if (!pixs || pixGetDepth(pixs) != 1) return ERROR_INT("pixs not defined or not 1 bpp", procName, 1); if (!recog->train_done) return ERROR_INT("training not finished", procName, 1); /* Binarize and crop to foreground if necessary */ if ((pix1 = recogProcessToIdentify(recog, pixs, 0)) == NULL) return ERROR_INT("pix1 not made", procName, 1); /* Remove any existing RecogDID and set up a new one */ recogDestroyDid(recog); if (recogCreateDid(recog, pix1)) { pixDestroy(&pix1); return ERROR_INT("decoder not made", procName, 1); } /* Compute vertical sum and first moment arrays */ did = recogGetDid(recog); /* owned by recog */ did->nasum = pixCountPixelsByColumn(pix1); did->namoment = pixGetMomentByColumn(pix1, 1); /* Generate the arrays */ for (i = 0; i < recog->did->narray; i++) recogMakeDecodingArray(recog, i, debug); pixDestroy(&pix1); return 0; }