/*! * recogaCreateFromPixaa() * * Input: paa (of labelled, 1 bpp images) * scalew (scale all widths to this; use 0 for no scaling) * scaleh (scale all heights to this; use 0 for no scaling) * templ_type (L_USE_AVERAGE or L_USE_ALL) * threshold (for binarization; typically ~128) * maxyshift (from nominal centroid alignment; typically 0 or 1) * Return: recoga, or null on error * * Notes: * (1) This is a convenience function for training from labelled data. * (2) Each pixa in the paa is a set of labelled data that is used * to train a recognizer (e.g., for a set of characters in a font). * Each image DC in the pixa is put into a class in its * recognizer, defined by its character label. All examples in * the same class should be similar. * (3) The pixaa can be written by recogaWritePixaa(), and must contain * the unscaled bitmaps used for training. */ L_RECOGA * recogaCreateFromPixaa(PIXAA *paa, l_int32 scalew, l_int32 scaleh, l_int32 templ_type, l_int32 threshold, l_int32 maxyshift) { l_int32 n, i, full; L_RECOG *recog; L_RECOGA *recoga; PIXA *pixa; PROCNAME("recogaCreateFromPixaa"); if (!paa) return (L_RECOGA *)ERROR_PTR("paa not defined", procName, NULL); if (pixaaVerifyDepth(paa, NULL) != 1) return (L_RECOGA *)ERROR_PTR("all pix not 1 bpp", procName, NULL); pixaaIsFull(paa, &full); if (!full) return (L_RECOGA *)ERROR_PTR("all pix not present", procName, NULL); n = pixaaGetCount(paa, NULL); recoga = recogaCreate(n); for (i = 0; i < n; i++) { pixa = pixaaGetPixa(paa, i, L_CLONE); recog = recogCreateFromPixa(pixa, scalew, scaleh, templ_type, threshold, maxyshift); recogaAddRecog(recoga, recog); pixaDestroy(&pixa); } return recoga; }
/*! * \brief recogCreateFromRecog() * * \param[in] recs source recog with arbitrary input parameters * \param[in] scalew scale all widths to this; use 0 otherwise * \param[in] scaleh scale all heights to this; use 0 otherwise * \param[in] linew width of normalized strokes; use 0 to skip * \param[in] threshold for binarization; typically ~128 * \param[in] maxyshift from nominal centroid alignment; default is 1 * \return recd, or NULL on error * * <pre> * Notes: * (1) This is a convenience function that generates a recog using * the unscaled training data in an existing recog. * (2) It is recommended to use %maxyshift = 1 (the default value) * (3) See recogCreate() for use of %scalew, %scaleh and %linew. * </pre> */ L_RECOG * recogCreateFromRecog(L_RECOG *recs, l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift) { L_RECOG *recd; PIXA *pixa; PROCNAME("recogCreateFromRecog"); if (!recs) return (L_RECOG *)ERROR_PTR("recs not defined", procName, NULL); pixa = recogExtractPixa(recs); recd = recogCreateFromPixa(pixa, scalew, scaleh, linew, threshold, maxyshift); pixaDestroy(&pixa); return recd; }
/*! * recogCreateFromRecog() * * Input: recs (source recog with arbitrary input parameters) * scalew (scale all widths to this; use 0 for no scaling) * scaleh (scale all heights to this; use 0 for no scaling) * templ_type (L_USE_AVERAGE or L_USE_ALL) * threshold (for binarization; typically ~128) * maxyshift (from nominal centroid alignment; typically 0 or 1) * Return: recd, or null on error * * Notes: * (1) This is a convenience function that generates a recog using * the unscaled training data in an existing recog. */ L_RECOG * recogCreateFromRecog(L_RECOG *recs, l_int32 scalew, l_int32 scaleh, l_int32 templ_type, l_int32 threshold, l_int32 maxyshift) { L_RECOG *recd; PIXA *pixa; PROCNAME("recogCreateFromRecog"); if (!recs) return (L_RECOG *)ERROR_PTR("recs not defined", procName, NULL); pixa = pixaaFlattenToPixa(recs->pixaa_u, NULL, L_CLONE); recd = recogCreateFromPixa(pixa, scalew, scaleh, templ_type, threshold, maxyshift); pixaDestroy(&pixa); return recd; }
l_int32 main(int argc, char **argv) { char *boxatxt; l_int32 i; BOXA *boxa1, *boxa2, *boxa3; BOXAA *baa, *baa1; NUMAA *naa1; PIX *pixdb, *pix1, *pix2, *pix3, *pix4; PIXA *pixa1, *pixa2, *pixa3, *pixat; L_RECOG *recog; L_RECOGA *recoga; SARRAY *sa1; /* ----- Example identifying samples using training data ----- */ #if 1 /* Read the training data */ pixat = pixaRead("recog/sets/train06.pa"); recog = recogCreateFromPixa(pixat, 0, 0, L_USE_ALL, 128, 1); recoga = recogaCreateFromRecog(recog); pixaDestroy(&pixat); /* Read the data from all samples */ pix1 = pixRead("recog/sets/samples06.png"); boxatxt = pixGetText(pix1); boxa1 = boxaReadMem((l_uint8 *)boxatxt, strlen(boxatxt)); pixa1 = pixaCreateFromBoxa(pix1, boxa1, NULL); pixDestroy(&pix1); /* destroys boxa1 */ /* Identify components in the sample data */ pixa2 = pixaCreate(0); pixa3 = pixaCreate(0); for (i = 0; i < 9; i++) { /* if (i != 4) continue; */ /* dots form separate boxa */ /* if (i != 8) continue; */ /* broken 2 in '24' */ pix1 = pixaGetPix(pixa1, i, L_CLONE); /* Show the 2d box data in the sample */ boxa2 = pixConnComp(pix1, NULL, 8); baa = boxaSort2d(boxa2, NULL, 6, 6, 5); pix2 = boxaaDisplay(baa, 3, 1, 0xff000000, 0x00ff0000, 0, 0); pixaAddPix(pixa3, pix2, L_INSERT); boxaaDestroy(&baa); boxaDestroy(&boxa2); /* Get the numbers in the sample */ recogaIdentifyMultiple(recoga, pix1, 0, 5, 3, &boxa3, NULL, &pixdb, 0); sa1 = recogaExtractNumbers(recoga, boxa3, 0.7, -1, &baa1, &naa1); sarrayWriteStream(stderr, sa1); boxaaWriteStream(stderr, baa1); numaaWriteStream(stderr, naa1); pixaAddPix(pixa2, pixdb, L_INSERT); /* pixaWrite("/tmp/pixa.pa", pixa2); */ pixDestroy(&pix1); boxaDestroy(&boxa3); boxaaDestroy(&baa1); numaaDestroy(&naa1); sarrayDestroy(&sa1); } pix3 = pixaDisplayLinearly(pixa2, L_VERT, 1.0, 0, 20, 1, NULL); pixWrite("/tmp/pix3.png", pix3, IFF_PNG); pix4 = pixaDisplayTiledInRows(pixa3, 32, 1500, 1.0, 0, 20, 2); pixDisplay(pix4, 500, 0); pixWrite("/tmp/pix4.png", pix4, IFF_PNG); pixaDestroy(&pixa2); pixaDestroy(&pixa3); pixDestroy(&pix1); pixDestroy(&pix3); pixDestroy(&pix4); pixaDestroy(&pixa1); boxaDestroy(&boxa1); recogaDestroy(&recoga); #endif return 0; }