Leptonica 1.83.1
Image processing and image analysis suite
Loading...
Searching...
No Matches
recogbasic.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
188
189#ifdef HAVE_CONFIG_H
190#include <config_auto.h>
191#endif /* HAVE_CONFIG_H */
192
193#include <string.h>
194#include "allheaders.h"
195
196static const l_int32 MaxExamplesInClass = 256;
197
198 /* Default recog parameters that can be changed */
199static const l_int32 DefaultCharsetType = L_ARABIC_NUMERALS;
200static const l_int32 DefaultMinNopad = 1;
201static const l_float32 DefaultMaxWHRatio = 3.0; /* max allowed w/h
202 ratio for a component to be split */
203static const l_float32 DefaultMaxHTRatio = 2.6; /* max allowed ratio of
204 max/min unscaled averaged template heights */
205static const l_int32 DefaultThreshold = 150; /* for binarization */
206static const l_int32 DefaultMaxYShift = 1; /* for identification */
207
208 /* Static functions */
209static l_int32 recogGetCharsetSize(l_int32 type);
210static l_int32 recogAddCharstrLabels(L_RECOG *recog);
211static l_int32 recogAddAllSamples(L_RECOG **precog, PIXAA *paa, l_int32 debug);
212
213
214/*------------------------------------------------------------------------*
215 * Recog: initialization and destruction *
216 *------------------------------------------------------------------------*/
236L_RECOG *
238 l_int32 scalew,
239 l_int32 scaleh,
240 l_int32 linew,
241 l_int32 threshold,
242 l_int32 maxyshift)
243{
244L_RECOG *recd;
245PIXA *pixa;
246
247 if (!recs)
248 return (L_RECOG *)ERROR_PTR("recs not defined", __func__, NULL);
249
250 pixa = recogExtractPixa(recs);
251 recd = recogCreateFromPixa(pixa, scalew, scaleh, linew, threshold,
252 maxyshift);
253 pixaDestroy(&pixa);
254 return recd;
255}
256
257
281L_RECOG *
283 l_int32 scalew,
284 l_int32 scaleh,
285 l_int32 linew,
286 l_int32 threshold,
287 l_int32 maxyshift)
288{
289L_RECOG *recog;
290
291 if (!pixa)
292 return (L_RECOG *)ERROR_PTR("pixa not defined", __func__, NULL);
293
294 recog = recogCreateFromPixaNoFinish(pixa, scalew, scaleh, linew,
295 threshold, maxyshift);
296 if (!recog)
297 return (L_RECOG *)ERROR_PTR("recog not made", __func__, NULL);
298
299 recogTrainingFinished(&recog, 1, -1, -1.0);
300 if (!recog)
301 return (L_RECOG *)ERROR_PTR("bad templates", __func__, NULL);
302 return recog;
303}
304
305
325L_RECOG *
327 l_int32 scalew,
328 l_int32 scaleh,
329 l_int32 linew,
330 l_int32 threshold,
331 l_int32 maxyshift)
332{
333char *text;
334l_int32 full, n, i, ntext, same, maxd;
335PIX *pix;
336L_RECOG *recog;
337
338 if (!pixa)
339 return (L_RECOG *)ERROR_PTR("pixa not defined", __func__, NULL);
340 pixaVerifyDepth(pixa, &same, &maxd);
341 if (maxd > 1)
342 return (L_RECOG *)ERROR_PTR("not all pix are 1 bpp", __func__, NULL);
343
344 pixaIsFull(pixa, &full, NULL);
345 if (!full)
346 return (L_RECOG *)ERROR_PTR("not all pix are present", __func__, NULL);
347
348 n = pixaGetCount(pixa);
349 pixaCountText(pixa, &ntext);
350 if (ntext == 0)
351 return (L_RECOG *)ERROR_PTR("no pix have text strings", __func__, NULL);
352 if (ntext < n)
353 L_ERROR("%d text strings < %d pix\n", __func__, ntext, n);
354
355 recog = recogCreate(scalew, scaleh, linew, threshold, maxyshift);
356 if (!recog)
357 return (L_RECOG *)ERROR_PTR("recog not made", __func__, NULL);
358 for (i = 0; i < n; i++) {
359 pix = pixaGetPix(pixa, i, L_CLONE);
360 text = pixGetText(pix);
361 if (!text || strlen(text) == 0) {
362 L_ERROR("pix[%d] has no text\n", __func__, i);
363 pixDestroy(&pix);
364 continue;
365 }
366 recogTrainLabeled(recog, pix, NULL, text, 0);
367 pixDestroy(&pix);
368 }
369
370 return recog;
371}
372
373
404L_RECOG *
405recogCreate(l_int32 scalew,
406 l_int32 scaleh,
407 l_int32 linew,
408 l_int32 threshold,
409 l_int32 maxyshift)
410{
411L_RECOG *recog;
412
413 if (scalew < 0 || scaleh < 0)
414 return (L_RECOG *)ERROR_PTR("invalid scalew or scaleh", __func__, NULL);
415 if (linew > 10)
416 return (L_RECOG *)ERROR_PTR("invalid linew > 10", __func__, NULL);
417 if (threshold == 0) threshold = DefaultThreshold;
418 if (threshold < 0 || threshold > 255) {
419 L_WARNING("invalid threshold; using default\n", __func__);
420 threshold = DefaultThreshold;
421 }
422 if (maxyshift < 0 || maxyshift > 2) {
423 L_WARNING("invalid maxyshift; using default value\n", __func__);
424 maxyshift = DefaultMaxYShift;
425 } else if (maxyshift == 0) {
426 L_WARNING("Using maxyshift = 0; faster, worse correlation results\n",
427 __func__);
428 } else if (maxyshift == 2) {
429 L_WARNING("Using maxyshift = 2; slower\n", __func__);
430 }
431
432 recog = (L_RECOG *)LEPT_CALLOC(1, sizeof(L_RECOG));
433 recog->templ_use = L_USE_ALL_TEMPLATES; /* default */
434 recog->threshold = threshold;
435 recog->scalew = scalew;
436 recog->scaleh = scaleh;
437 recog->linew = linew;
438 recog->maxyshift = maxyshift;
439 recogSetParams(recog, 1, -1, -1.0, -1.0);
440 recog->bmf = bmfCreate(NULL, 6);
441 recog->bmf_size = 6;
442 recog->maxarraysize = MaxExamplesInClass;
443
444 /* Generate the LUTs */
445 recog->centtab = makePixelCentroidTab8();
446 recog->sumtab = makePixelSumTab8();
447 recog->sa_text = sarrayCreate(0);
448 recog->dna_tochar = l_dnaCreate(0);
449
450 /* Input default values for min component size for splitting.
451 * These are overwritten when pixTrainingFinished() is called. */
452 recog->min_splitw = 6;
453 recog->max_splith = 60;
454
455 /* Allocate the paa for the unscaled training bitmaps */
456 recog->pixaa_u = pixaaCreate(recog->maxarraysize);
457
458 /* Generate the storage for debugging */
459 recog->pixadb_boot = pixaCreate(2);
460 recog->pixadb_split = pixaCreate(2);
461 return recog;
462}
463
464
471void
472recogDestroy(L_RECOG **precog)
473{
474L_RECOG *recog;
475
476 if (!precog) {
477 L_WARNING("ptr address is null\n", __func__);
478 return;
479 }
480
481 if ((recog = *precog) == NULL) return;
482
483 LEPT_FREE(recog->centtab);
484 LEPT_FREE(recog->sumtab);
485 sarrayDestroy(&recog->sa_text);
486 l_dnaDestroy(&recog->dna_tochar);
487 pixaaDestroy(&recog->pixaa_u);
488 pixaDestroy(&recog->pixa_u);
489 ptaaDestroy(&recog->ptaa_u);
490 ptaDestroy(&recog->pta_u);
491 numaDestroy(&recog->nasum_u);
492 numaaDestroy(&recog->naasum_u);
493 pixaaDestroy(&recog->pixaa);
494 pixaDestroy(&recog->pixa);
495 ptaaDestroy(&recog->ptaa);
496 ptaDestroy(&recog->pta);
497 numaDestroy(&recog->nasum);
498 numaaDestroy(&recog->naasum);
499 pixaDestroy(&recog->pixa_tr);
500 pixaDestroy(&recog->pixadb_ave);
501 pixaDestroy(&recog->pixa_id);
502 pixDestroy(&recog->pixdb_ave);
503 pixDestroy(&recog->pixdb_range);
504 pixaDestroy(&recog->pixadb_boot);
505 pixaDestroy(&recog->pixadb_split);
506 bmfDestroy(&recog->bmf);
507 rchDestroy(&recog->rch);
508 rchaDestroy(&recog->rcha);
509 recogDestroyDid(recog);
510 LEPT_FREE(recog);
511 *precog = NULL;
512}
513
514
515/*------------------------------------------------------------------------*
516 * Recog accessors *
517 *------------------------------------------------------------------------*/
524l_int32
525recogGetCount(L_RECOG *recog)
526{
527 if (!recog)
528 return ERROR_INT("recog not defined", __func__, 0);
529 return recog->setsize;
530}
531
532
560l_ok
561recogSetParams(L_RECOG *recog,
562 l_int32 type,
563 l_int32 min_nopad,
564 l_float32 max_wh_ratio,
565 l_float32 max_ht_ratio)
566{
567 if (!recog)
568 return ERROR_INT("recog not defined", __func__, 1);
569
570 recog->charset_type = (type >= 0) ? type : DefaultCharsetType;
572 recog->min_nopad = (min_nopad >= 0) ? min_nopad : DefaultMinNopad;
573 recog->max_wh_ratio = (max_wh_ratio > 0.0) ? max_wh_ratio :
574 DefaultMaxWHRatio;
575 recog->max_ht_ratio = (max_ht_ratio > 1.0) ? max_ht_ratio :
576 DefaultMaxHTRatio;
577 return 0;
578}
579
580
587static l_int32
589{
590 switch (type) {
591 case L_UNKNOWN:
592 return 0;
594 return 10;
596 return 7;
598 return 7;
599 case L_LC_ALPHA:
600 return 26;
601 case L_UC_ALPHA:
602 return 26;
603 default:
604 L_ERROR("invalid charset_type %d\n", __func__, type);
605 return 0;
606 }
607 return 0; /* shouldn't happen */
608}
609
610
611/*------------------------------------------------------------------------*
612 * Character/index lookup *
613 *------------------------------------------------------------------------*/
638l_int32
639recogGetClassIndex(L_RECOG *recog,
640 l_int32 val,
641 char *text,
642 l_int32 *pindex)
643{
644l_int32 i, n, ival;
645
646 if (!pindex)
647 return ERROR_INT("&index not defined", __func__, 2);
648 *pindex = -1;
649 if (!recog)
650 return ERROR_INT("recog not defined", __func__, 2);
651 if (!text)
652 return ERROR_INT("text not defined", __func__, 2);
653
654 /* Search existing characters */
655 n = l_dnaGetCount(recog->dna_tochar);
656 for (i = 0; i < n; i++) {
657 l_dnaGetIValue(recog->dna_tochar, i, &ival);
658 if (val == ival) { /* found */
659 *pindex = i;
660 return 0;
661 }
662 }
663
664 /* If not found... */
665 l_dnaAddNumber(recog->dna_tochar, val);
666 sarrayAddString(recog->sa_text, text, L_COPY);
667 recog->setsize++;
668 *pindex = n;
669 return 1;
670}
671
672
681l_ok
682recogStringToIndex(L_RECOG *recog,
683 char *text,
684 l_int32 *pindex)
685{
686char *charstr;
687l_int32 i, n, diff;
688
689 if (!pindex)
690 return ERROR_INT("&index not defined", __func__, 1);
691 *pindex = -1;
692 if (!recog)
693 return ERROR_INT("recog not defined", __func__, 1);
694 if (!text)
695 return ERROR_INT("text not defined", __func__, 1);
696
697 /* Search existing characters */
698 n = recog->setsize;
699 for (i = 0; i < n; i++) {
700 recogGetClassString(recog, i, &charstr);
701 if (!charstr) {
702 L_ERROR("string not found for index %d\n", __func__, i);
703 continue;
704 }
705 diff = strcmp(text, charstr);
706 LEPT_FREE(charstr);
707 if (diff) continue;
708 *pindex = i;
709 return 0;
710 }
711
712 return 1; /* not found */
713}
714
715
732l_int32
733recogGetClassString(L_RECOG *recog,
734 l_int32 index,
735 char **pcharstr)
736{
737 if (!pcharstr)
738 return ERROR_INT("&charstr not defined", __func__, 1);
739 *pcharstr = stringNew("");
740 if (!recog)
741 return ERROR_INT("recog not defined", __func__, 2);
742
743 if (index < 0 || index >= recog->setsize)
744 return ERROR_INT("invalid index", __func__, 1);
745 LEPT_FREE(*pcharstr);
746 *pcharstr = sarrayGetString(recog->sa_text, index, L_COPY);
747 return 0;
748}
749
750
760l_ok
761l_convertCharstrToInt(const char *str,
762 l_int32 *pval)
763{
764l_int32 size;
765l_uint32 val;
766
767 if (!pval)
768 return ERROR_INT("&val not defined", __func__, 1);
769 *pval = 0;
770 if (!str)
771 return ERROR_INT("str not defined", __func__, 1);
772 size = strlen(str);
773 if (size == 0)
774 return ERROR_INT("empty string", __func__, 1);
775 if (size > 4)
776 return ERROR_INT("invalid string: > 4 bytes", __func__, 1);
777
778 val = (l_uint8)str[0];
779 if (size > 1)
780 val = (val << 8) + (l_uint8)str[1];
781 if (size > 2)
782 val = (val << 8) + (l_uint8)str[2];
783 if (size > 3)
784 val = (val << 8) + (l_uint8)str[3];
785 *pval = (l_int32)(val & 0x7fffffff);
786 return 0;
787}
788
789
790/*------------------------------------------------------------------------*
791 * Serialization *
792 *------------------------------------------------------------------------*/
818L_RECOG *
819recogRead(const char *filename)
820{
821FILE *fp;
822L_RECOG *recog;
823
824 if (!filename)
825 return (L_RECOG *)ERROR_PTR("filename not defined", __func__, NULL);
826 if ((fp = fopenReadStream(filename)) == NULL)
827 return (L_RECOG *)ERROR_PTR("stream not opened", __func__, NULL);
828
829 if ((recog = recogReadStream(fp)) == NULL) {
830 fclose(fp);
831 return (L_RECOG *)ERROR_PTR("recog not read", __func__, NULL);
832 }
833
834 fclose(fp);
835 return recog;
836}
837
838
845L_RECOG *
847{
848l_int32 version, setsize, threshold, scalew, scaleh, linew;
849l_int32 maxyshift, nc;
850L_DNA *dna_tochar;
851PIXAA *paa;
852L_RECOG *recog;
853SARRAY *sa_text;
854
855 if (!fp)
856 return (L_RECOG *)ERROR_PTR("stream not defined", __func__, NULL);
857
858 if (fscanf(fp, "\nRecog Version %d\n", &version) != 1)
859 return (L_RECOG *)ERROR_PTR("not a recog file", __func__, NULL);
860 if (version != RECOG_VERSION_NUMBER)
861 return (L_RECOG *)ERROR_PTR("invalid recog version", __func__, NULL);
862 if (fscanf(fp, "Size of character set = %d\n", &setsize) != 1)
863 return (L_RECOG *)ERROR_PTR("setsize not read", __func__, NULL);
864 if (fscanf(fp, "Binarization threshold = %d\n", &threshold) != 1)
865 return (L_RECOG *)ERROR_PTR("binary thresh not read", __func__, NULL);
866 if (fscanf(fp, "Maxyshift = %d\n", &maxyshift) != 1)
867 return (L_RECOG *)ERROR_PTR("maxyshift not read", __func__, NULL);
868 if (fscanf(fp, "Scale to width = %d\n", &scalew) != 1)
869 return (L_RECOG *)ERROR_PTR("width not read", __func__, NULL);
870 if (fscanf(fp, "Scale to height = %d\n", &scaleh) != 1)
871 return (L_RECOG *)ERROR_PTR("height not read", __func__, NULL);
872 if (fscanf(fp, "Normalized line width = %d\n", &linew) != 1)
873 return (L_RECOG *)ERROR_PTR("line width not read", __func__, NULL);
874 if ((recog = recogCreate(scalew, scaleh, linew, threshold,
875 maxyshift)) == NULL)
876 return (L_RECOG *)ERROR_PTR("recog not made", __func__, NULL);
877
878 if (fscanf(fp, "\nLabels for character set:\n") != 0) {
879 recogDestroy(&recog);
880 return (L_RECOG *)ERROR_PTR("label intro not read", __func__, NULL);
881 }
882 l_dnaDestroy(&recog->dna_tochar);
883 if ((dna_tochar = l_dnaReadStream(fp)) == NULL) {
884 recogDestroy(&recog);
885 return (L_RECOG *)ERROR_PTR("dna_tochar not read", __func__, NULL);
886 }
887 recog->dna_tochar = dna_tochar;
888 sarrayDestroy(&recog->sa_text);
889 if ((sa_text = sarrayReadStream(fp)) == NULL) {
890 recogDestroy(&recog);
891 return (L_RECOG *)ERROR_PTR("sa_text not read", __func__, NULL);
892 }
893 recog->sa_text = sa_text;
894
895 if (fscanf(fp, "\nPixaa of all samples in the training set:\n") != 0) {
896 recogDestroy(&recog);
897 return (L_RECOG *)ERROR_PTR("pixaa intro not read", __func__, NULL);
898 }
899 if ((paa = pixaaReadStream(fp)) == NULL) {
900 recogDestroy(&recog);
901 return (L_RECOG *)ERROR_PTR("pixaa not read", __func__, NULL);
902 }
903 recog->setsize = setsize;
904 nc = pixaaGetCount(paa, NULL);
905 if (nc != setsize) {
906 recogDestroy(&recog);
907 pixaaDestroy(&paa);
908 L_ERROR("(setsize = %d) != (paa count = %d)\n", __func__,
909 setsize, nc);
910 return NULL;
911 }
912
913 recogAddAllSamples(&recog, paa, 0); /* this finishes */
914 pixaaDestroy(&paa);
915 if (!recog)
916 return (L_RECOG *)ERROR_PTR("bad templates", __func__, NULL);
917 return recog;
918}
919
920
928L_RECOG *
929recogReadMem(const l_uint8 *data,
930 size_t size)
931{
932FILE *fp;
933L_RECOG *recog;
934
935 if (!data)
936 return (L_RECOG *)ERROR_PTR("data not defined", __func__, NULL);
937 if ((fp = fopenReadFromMemory(data, size)) == NULL)
938 return (L_RECOG *)ERROR_PTR("stream not opened", __func__, NULL);
939
940 recog = recogReadStream(fp);
941 fclose(fp);
942 if (!recog) L_ERROR("recog not read\n", __func__);
943 return recog;
944}
945
946
963l_ok
964recogWrite(const char *filename,
965 L_RECOG *recog)
966{
967l_int32 ret;
968FILE *fp;
969
970 if (!filename)
971 return ERROR_INT("filename not defined", __func__, 1);
972 if (!recog)
973 return ERROR_INT("recog not defined", __func__, 1);
974
975 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
976 return ERROR_INT("stream not opened", __func__, 1);
977 ret = recogWriteStream(fp, recog);
978 fclose(fp);
979 if (ret)
980 return ERROR_INT("recog not written to stream", __func__, 1);
981 return 0;
982}
983
984
992l_ok
994 L_RECOG *recog)
995{
996 if (!fp)
997 return ERROR_INT("stream not defined", __func__, 1);
998 if (!recog)
999 return ERROR_INT("recog not defined", __func__, 1);
1000
1001 fprintf(fp, "\nRecog Version %d\n", RECOG_VERSION_NUMBER);
1002 fprintf(fp, "Size of character set = %d\n", recog->setsize);
1003 fprintf(fp, "Binarization threshold = %d\n", recog->threshold);
1004 fprintf(fp, "Maxyshift = %d\n", recog->maxyshift);
1005 fprintf(fp, "Scale to width = %d\n", recog->scalew);
1006 fprintf(fp, "Scale to height = %d\n", recog->scaleh);
1007 fprintf(fp, "Normalized line width = %d\n", recog->linew);
1008 fprintf(fp, "\nLabels for character set:\n");
1009 l_dnaWriteStream(fp, recog->dna_tochar);
1010 sarrayWriteStream(fp, recog->sa_text);
1011 fprintf(fp, "\nPixaa of all samples in the training set:\n");
1012 pixaaWriteStream(fp, recog->pixaa);
1013
1014 return 0;
1015}
1016
1017
1031l_ok
1032recogWriteMem(l_uint8 **pdata,
1033 size_t *psize,
1034 L_RECOG *recog)
1035{
1036l_int32 ret;
1037FILE *fp;
1038
1039 if (pdata) *pdata = NULL;
1040 if (psize) *psize = 0;
1041 if (!pdata)
1042 return ERROR_INT("&data not defined", __func__, 1);
1043 if (!psize)
1044 return ERROR_INT("&size not defined", __func__, 1);
1045 if (!recog)
1046 return ERROR_INT("recog not defined", __func__, 1);
1047
1048#if HAVE_FMEMOPEN
1049 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1050 return ERROR_INT("stream not opened", __func__, 1);
1051 ret = recogWriteStream(fp, recog);
1052 fputc('\0', fp);
1053 fclose(fp);
1054 *psize = *psize - 1;
1055#else
1056 L_INFO("work-around: writing to a temp file\n", __func__);
1057 #ifdef _WIN32
1058 if ((fp = fopenWriteWinTempfile()) == NULL)
1059 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1060 #else
1061 if ((fp = tmpfile()) == NULL)
1062 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1063 #endif /* _WIN32 */
1064 ret = recogWriteStream(fp, recog);
1065 rewind(fp);
1066 *pdata = l_binaryReadStream(fp, psize);
1067 fclose(fp);
1068#endif /* HAVE_FMEMOPEN */
1069 return ret;
1070}
1071
1072
1086PIXA *
1087recogExtractPixa(L_RECOG *recog)
1088{
1089 if (!recog)
1090 return (PIXA *)ERROR_PTR("recog not defined", __func__, NULL);
1091
1092 recogAddCharstrLabels(recog);
1093 return pixaaFlattenToPixa(recog->pixaa_u, NULL, L_CLONE);
1094}
1095
1096
1103static l_int32
1105{
1106char *text;
1107l_int32 i, j, n1, n2;
1108PIX *pix;
1109PIXA *pixa;
1110PIXAA *paa;
1111
1112 if (!recog)
1113 return ERROR_INT("recog not defined", __func__, 1);
1114
1115 /* Add the labels to each unscaled pix */
1116 paa = recog->pixaa_u;
1117 n1 = pixaaGetCount(paa, NULL);
1118 for (i = 0; i < n1; i++) {
1119 pixa = pixaaGetPixa(paa, i, L_CLONE);
1120 text = sarrayGetString(recog->sa_text, i, L_NOCOPY);
1121 n2 = pixaGetCount(pixa);
1122 for (j = 0; j < n2; j++) {
1123 pix = pixaGetPix(pixa, j, L_CLONE);
1124 pixSetText(pix, text);
1125 pixDestroy(&pix);
1126 }
1127 pixaDestroy(&pixa);
1128 }
1129
1130 return 0;
1131}
1132
1133
1153static l_int32
1154recogAddAllSamples(L_RECOG **precog,
1155 PIXAA *paa,
1156 l_int32 debug)
1157{
1158char *text;
1159l_int32 i, j, nc, ns;
1160PIX *pix;
1161PIXA *pixa, *pixa1;
1162L_RECOG *recog;
1163
1164 if (!precog)
1165 return ERROR_INT("&recog not defined", __func__, 1);
1166 if ((recog = *precog) == NULL)
1167 return ERROR_INT("recog not defined", __func__, 1);
1168 if (!paa) {
1169 recogDestroy(&recog);
1170 *precog = NULL;
1171 return ERROR_INT("paa not defined", __func__, 1);
1172 }
1173
1174 nc = pixaaGetCount(paa, NULL);
1175 for (i = 0; i < nc; i++) {
1176 pixa = pixaaGetPixa(paa, i, L_CLONE);
1177 ns = pixaGetCount(pixa);
1178 text = sarrayGetString(recog->sa_text, i, L_NOCOPY);
1179 pixa1 = pixaCreate(ns);
1180 pixaaAddPixa(recog->pixaa_u, pixa1, L_INSERT);
1181 for (j = 0; j < ns; j++) {
1182 pix = pixaGetPix(pixa, j, L_CLONE);
1183 if (debug) lept_stderr("pix[%d,%d]: text = %s\n", i, j, text);
1184 pixaaAddPix(recog->pixaa_u, i, pix, NULL, L_INSERT);
1185 }
1186 pixaDestroy(&pixa);
1187 }
1188
1189 recogTrainingFinished(&recog, 0, -1, -1.0); /* For second parameter,
1190 see comment in recogRead() */
1191 if (!recog)
1192 return ERROR_INT("bad templates; recog destroyed", __func__, 1);
1193 return 0;
1194}
struct L_Dna L_DNA
Definition array.h:72
struct Sarray SARRAY
Definition array.h:81
struct Pixaa PIXAA
Definition pix.h:246
@ L_COPY
Definition pix.h:505
@ L_CLONE
Definition pix.h:506
@ L_NOCOPY
Definition pix.h:503
@ L_INSERT
Definition pix.h:504
struct Pix PIX
Definition pix.h:228
struct Pixa PIXA
Definition pix.h:243
@ L_LC_ALPHA
Definition recog.h:250
@ L_ARABIC_NUMERALS
Definition recog.h:247
@ L_UC_ALPHA
Definition recog.h:251
@ L_LC_ROMAN_NUMERALS
Definition recog.h:248
@ L_UNKNOWN
Definition recog.h:246
@ L_UC_ROMAN_NUMERALS
Definition recog.h:249
@ L_USE_ALL_TEMPLATES
Definition recog.h:260
l_ok recogStringToIndex(L_RECOG *recog, char *text, l_int32 *pindex)
recogStringToIndex()
Definition recogbasic.c:682
l_ok recogWrite(const char *filename, L_RECOG *recog)
recogWrite()
Definition recogbasic.c:964
L_RECOG * recogCreateFromPixa(PIXA *pixa, l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift)
recogCreateFromPixa()
Definition recogbasic.c:282
static l_int32 recogGetCharsetSize(l_int32 type)
recogGetCharsetSize()
Definition recogbasic.c:588
l_ok recogWriteMem(l_uint8 **pdata, size_t *psize, L_RECOG *recog)
recogWriteMem()
l_ok recogWriteStream(FILE *fp, L_RECOG *recog)
recogWriteStream()
Definition recogbasic.c:993
l_ok recogSetParams(L_RECOG *recog, l_int32 type, l_int32 min_nopad, l_float32 max_wh_ratio, l_float32 max_ht_ratio)
recogSetParams()
Definition recogbasic.c:561
static l_int32 recogAddAllSamples(L_RECOG **precog, PIXAA *paa, l_int32 debug)
recogAddAllSamples()
L_RECOG * recogRead(const char *filename)
recogRead()
Definition recogbasic.c:819
l_ok l_convertCharstrToInt(const char *str, l_int32 *pval)
l_convertCharstrToInt()
Definition recogbasic.c:761
L_RECOG * recogCreate(l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift)
recogCreate()
Definition recogbasic.c:405
l_int32 recogGetClassIndex(L_RECOG *recog, l_int32 val, char *text, l_int32 *pindex)
recogGetClassIndex()
Definition recogbasic.c:639
static l_int32 recogAddCharstrLabels(L_RECOG *recog)
recogAddCharstrLabels()
L_RECOG * recogCreateFromPixaNoFinish(PIXA *pixa, l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift)
recogCreateFromPixaNoFinish()
Definition recogbasic.c:326
L_RECOG * recogCreateFromRecog(L_RECOG *recs, l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift)
recogCreateFromRecog()
Definition recogbasic.c:237
l_int32 recogGetClassString(L_RECOG *recog, l_int32 index, char **pcharstr)
recogGetClassString()
Definition recogbasic.c:733
PIXA * recogExtractPixa(L_RECOG *recog)
recogExtractPixa()
l_int32 recogGetCount(L_RECOG *recog)
recogGetCount()
Definition recogbasic.c:525
void recogDestroy(L_RECOG **precog)
recogDestroy()
Definition recogbasic.c:472
L_RECOG * recogReadMem(const l_uint8 *data, size_t size)
recogReadMem()
Definition recogbasic.c:929
L_RECOG * recogReadStream(FILE *fp)
recogReadStream()
Definition recogbasic.c:846
l_int32 charset_size
Definition recog.h:132
struct Numa * nasum
Definition recog.h:163
struct L_Dna * dna_tochar
Definition recog.h:149
l_int32 templ_use
Definition recog.h:123
l_int32 * centtab
Definition recog.h:150
l_int32 min_nopad
Definition recog.h:133
struct L_Rch * rch
Definition recog.h:174
struct Pixa * pixa_u
Definition recog.h:158
struct Pta * pta_u
Definition recog.h:159
struct Ptaa * ptaa_u
Definition recog.h:153
l_int32 maxyshift
Definition recog.h:129
l_int32 linew
Definition recog.h:121
struct Numaa * naasum_u
Definition recog.h:154
l_int32 scalew
Definition recog.h:117
struct Ptaa * ptaa
Definition recog.h:156
l_int32 min_splitw
Definition recog.h:146
l_float32 max_ht_ratio
Definition recog.h:145
l_int32 bmf_size
Definition recog.h:172
struct Pixa * pixadb_ave
Definition recog.h:165
struct Pixa * pixa_tr
Definition recog.h:164
l_int32 threshold
Definition recog.h:128
struct Numa * nasum_u
Definition recog.h:160
struct L_Rcha * rcha
Definition recog.h:175
struct Pixa * pixa_id
Definition recog.h:166
l_int32 scaleh
Definition recog.h:119
l_int32 max_splith
Definition recog.h:147
struct Pix * pixdb_range
Definition recog.h:168
l_int32 * sumtab
Definition recog.h:151
struct Pix * pixdb_ave
Definition recog.h:167
struct Pixa * pixadb_split
Definition recog.h:170
struct Pta * pta
Definition recog.h:162
l_int32 charset_type
Definition recog.h:131
struct Numaa * naasum
Definition recog.h:157
l_float32 max_wh_ratio
Definition recog.h:144
struct Pixaa * pixaa_u
Definition recog.h:152
l_int32 setsize
Definition recog.h:127
struct Sarray * sa_text
Definition recog.h:148
struct L_Bmf * bmf
Definition recog.h:171
struct Pixa * pixadb_boot
Definition recog.h:169
struct Pixaa * pixaa
Definition recog.h:155
struct Pixa * pixa
Definition recog.h:161
l_int32 maxarraysize
Definition recog.h:126