Leptonica 1.85.0
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
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.0f; /* max allowed w/h
202 ratio for a component to be split */
203static const l_float32 DefaultMaxHTRatio = 2.6f; /* 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
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
526{
527 if (!recog)
528 return ERROR_INT("recog not defined", __func__, 0);
529 return recog->setsize;
530}
531
532
560l_ok
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
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
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
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_1("stream not opened",
828 filename, __func__, NULL);
829
830 if ((recog = recogReadStream(fp)) == NULL) {
831 fclose(fp);
832 return (L_RECOG *)ERROR_PTR_1("recog not read",
833 filename, __func__, NULL);
834 }
835
836 fclose(fp);
837 return recog;
838}
839
840
847L_RECOG *
849{
850l_int32 version, setsize, threshold, scalew, scaleh, linew;
851l_int32 maxyshift, nc;
852L_DNA *dna_tochar;
853PIXAA *paa;
854L_RECOG *recog;
855SARRAY *sa_text;
856
857 if (!fp)
858 return (L_RECOG *)ERROR_PTR("stream not defined", __func__, NULL);
859
860 if (fscanf(fp, "\nRecog Version %d\n", &version) != 1)
861 return (L_RECOG *)ERROR_PTR("not a recog file", __func__, NULL);
862 if (version != RECOG_VERSION_NUMBER)
863 return (L_RECOG *)ERROR_PTR("invalid recog version", __func__, NULL);
864 if (fscanf(fp, "Size of character set = %d\n", &setsize) != 1)
865 return (L_RECOG *)ERROR_PTR("setsize not read", __func__, NULL);
866 if (fscanf(fp, "Binarization threshold = %d\n", &threshold) != 1)
867 return (L_RECOG *)ERROR_PTR("binary thresh not read", __func__, NULL);
868 if (fscanf(fp, "Maxyshift = %d\n", &maxyshift) != 1)
869 return (L_RECOG *)ERROR_PTR("maxyshift not read", __func__, NULL);
870 if (fscanf(fp, "Scale to width = %d\n", &scalew) != 1)
871 return (L_RECOG *)ERROR_PTR("width not read", __func__, NULL);
872 if (fscanf(fp, "Scale to height = %d\n", &scaleh) != 1)
873 return (L_RECOG *)ERROR_PTR("height not read", __func__, NULL);
874 if (fscanf(fp, "Normalized line width = %d\n", &linew) != 1)
875 return (L_RECOG *)ERROR_PTR("line width not read", __func__, NULL);
876 if ((recog = recogCreate(scalew, scaleh, linew, threshold,
877 maxyshift)) == NULL)
878 return (L_RECOG *)ERROR_PTR("recog not made", __func__, NULL);
879
880 if (fscanf(fp, "\nLabels for character set:\n") == -1) {
881 recogDestroy(&recog);
882 return (L_RECOG *)ERROR_PTR("label intro not read", __func__, NULL);
883 }
884 l_dnaDestroy(&recog->dna_tochar);
885 if ((dna_tochar = l_dnaReadStream(fp)) == NULL) {
886 recogDestroy(&recog);
887 return (L_RECOG *)ERROR_PTR("dna_tochar not read", __func__, NULL);
888 }
889 recog->dna_tochar = dna_tochar;
890 sarrayDestroy(&recog->sa_text);
891 if ((sa_text = sarrayReadStream(fp)) == NULL) {
892 recogDestroy(&recog);
893 return (L_RECOG *)ERROR_PTR("sa_text not read", __func__, NULL);
894 }
895 recog->sa_text = sa_text;
896
897 if (fscanf(fp, "\nPixaa of all samples in the training set:\n") == -1) {
898 recogDestroy(&recog);
899 return (L_RECOG *)ERROR_PTR("pixaa intro not read", __func__, NULL);
900 }
901 if ((paa = pixaaReadStream(fp)) == NULL) {
902 recogDestroy(&recog);
903 return (L_RECOG *)ERROR_PTR("pixaa not read", __func__, NULL);
904 }
905 recog->setsize = setsize;
906 nc = pixaaGetCount(paa, NULL);
907 if (nc != setsize) {
908 recogDestroy(&recog);
909 pixaaDestroy(&paa);
910 L_ERROR("(setsize = %d) != (paa count = %d)\n", __func__,
911 setsize, nc);
912 return NULL;
913 }
914
915 recogAddAllSamples(&recog, paa, 0); /* this finishes */
916 pixaaDestroy(&paa);
917 if (!recog)
918 return (L_RECOG *)ERROR_PTR("bad templates", __func__, NULL);
919 return recog;
920}
921
922
930L_RECOG *
931recogReadMem(const l_uint8 *data,
932 size_t size)
933{
934FILE *fp;
935L_RECOG *recog;
936
937 if (!data)
938 return (L_RECOG *)ERROR_PTR("data not defined", __func__, NULL);
939 if ((fp = fopenReadFromMemory(data, size)) == NULL)
940 return (L_RECOG *)ERROR_PTR("stream not opened", __func__, NULL);
941
942 recog = recogReadStream(fp);
943 fclose(fp);
944 if (!recog) L_ERROR("recog not read\n", __func__);
945 return recog;
946}
947
948
965l_ok
966recogWrite(const char *filename,
967 L_RECOG *recog)
968{
969l_int32 ret;
970FILE *fp;
971
972 if (!filename)
973 return ERROR_INT("filename not defined", __func__, 1);
974 if (!recog)
975 return ERROR_INT("recog not defined", __func__, 1);
976
977 if ((fp = fopenWriteStream(filename, "wb")) == NULL)
978 return ERROR_INT_1("stream not opened", filename, __func__, 1);
979 ret = recogWriteStream(fp, recog);
980 fclose(fp);
981 if (ret)
982 return ERROR_INT_1("recog not written to stream",
983 filename, __func__, 1);
984 return 0;
985}
986
987
995l_ok
997 L_RECOG *recog)
998{
999 if (!fp)
1000 return ERROR_INT("stream not defined", __func__, 1);
1001 if (!recog)
1002 return ERROR_INT("recog not defined", __func__, 1);
1003
1004 fprintf(fp, "\nRecog Version %d\n", RECOG_VERSION_NUMBER);
1005 fprintf(fp, "Size of character set = %d\n", recog->setsize);
1006 fprintf(fp, "Binarization threshold = %d\n", recog->threshold);
1007 fprintf(fp, "Maxyshift = %d\n", recog->maxyshift);
1008 fprintf(fp, "Scale to width = %d\n", recog->scalew);
1009 fprintf(fp, "Scale to height = %d\n", recog->scaleh);
1010 fprintf(fp, "Normalized line width = %d\n", recog->linew);
1011 fprintf(fp, "\nLabels for character set:\n");
1012 l_dnaWriteStream(fp, recog->dna_tochar);
1013 sarrayWriteStream(fp, recog->sa_text);
1014 fprintf(fp, "\nPixaa of all samples in the training set:\n");
1015 pixaaWriteStream(fp, recog->pixaa);
1016
1017 return 0;
1018}
1019
1020
1034l_ok
1035recogWriteMem(l_uint8 **pdata,
1036 size_t *psize,
1037 L_RECOG *recog)
1038{
1039l_int32 ret;
1040FILE *fp;
1041
1042 if (pdata) *pdata = NULL;
1043 if (psize) *psize = 0;
1044 if (!pdata)
1045 return ERROR_INT("&data not defined", __func__, 1);
1046 if (!psize)
1047 return ERROR_INT("&size not defined", __func__, 1);
1048 if (!recog)
1049 return ERROR_INT("recog not defined", __func__, 1);
1050
1051#if HAVE_FMEMOPEN
1052 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1053 return ERROR_INT("stream not opened", __func__, 1);
1054 ret = recogWriteStream(fp, recog);
1055 fputc('\0', fp);
1056 fclose(fp);
1057 if (*psize > 0) *psize = *psize - 1;
1058#else
1059 L_INFO("no fmemopen API --> work-around: write to temp file\n", __func__);
1060 #ifdef _WIN32
1061 if ((fp = fopenWriteWinTempfile()) == NULL)
1062 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1063 #else
1064 if ((fp = tmpfile()) == NULL)
1065 return ERROR_INT("tmpfile stream not opened", __func__, 1);
1066 #endif /* _WIN32 */
1067 ret = recogWriteStream(fp, recog);
1068 rewind(fp);
1069 *pdata = l_binaryReadStream(fp, psize);
1070 fclose(fp);
1071#endif /* HAVE_FMEMOPEN */
1072 return ret;
1073}
1074
1075
1089PIXA *
1091{
1092 if (!recog)
1093 return (PIXA *)ERROR_PTR("recog not defined", __func__, NULL);
1094
1095 recogAddCharstrLabels(recog);
1096 return pixaaFlattenToPixa(recog->pixaa_u, NULL, L_CLONE);
1097}
1098
1099
1106static l_int32
1108{
1109char *text;
1110l_int32 i, j, n1, n2;
1111PIX *pix;
1112PIXA *pixa;
1113PIXAA *paa;
1114
1115 if (!recog)
1116 return ERROR_INT("recog not defined", __func__, 1);
1117
1118 /* Add the labels to each unscaled pix */
1119 paa = recog->pixaa_u;
1120 n1 = pixaaGetCount(paa, NULL);
1121 for (i = 0; i < n1; i++) {
1122 pixa = pixaaGetPixa(paa, i, L_CLONE);
1123 text = sarrayGetString(recog->sa_text, i, L_NOCOPY);
1124 n2 = pixaGetCount(pixa);
1125 for (j = 0; j < n2; j++) {
1126 pix = pixaGetPix(pixa, j, L_CLONE);
1127 pixSetText(pix, text);
1128 pixDestroy(&pix);
1129 }
1130 pixaDestroy(&pixa);
1131 }
1132
1133 return 0;
1134}
1135
1136
1156static l_int32
1158 PIXAA *paa,
1159 l_int32 debug)
1160{
1161char *text;
1162l_int32 i, j, nc, ns;
1163PIX *pix;
1164PIXA *pixa, *pixa1;
1165L_RECOG *recog;
1166
1167 if (!precog)
1168 return ERROR_INT("&recog not defined", __func__, 1);
1169 if ((recog = *precog) == NULL)
1170 return ERROR_INT("recog not defined", __func__, 1);
1171 if (!paa) {
1172 recogDestroy(&recog);
1173 *precog = NULL;
1174 return ERROR_INT("paa not defined", __func__, 1);
1175 }
1176
1177 nc = pixaaGetCount(paa, NULL);
1178 for (i = 0; i < nc; i++) {
1179 pixa = pixaaGetPixa(paa, i, L_CLONE);
1180 ns = pixaGetCount(pixa);
1181 text = sarrayGetString(recog->sa_text, i, L_NOCOPY);
1182 pixa1 = pixaCreate(ns);
1183 pixaaAddPixa(recog->pixaa_u, pixa1, L_INSERT);
1184 for (j = 0; j < ns; j++) {
1185 pix = pixaGetPix(pixa, j, L_CLONE);
1186 if (debug) lept_stderr("pix[%d,%d]: text = %s\n", i, j, text);
1187 pixaaAddPix(recog->pixaa_u, i, pix, NULL, L_INSERT);
1188 }
1189 pixaDestroy(&pixa);
1190 }
1191
1192 recogTrainingFinished(&recog, 0, -1, -1.0); /* For second parameter,
1193 see comment in recogRead() */
1194 if (!recog)
1195 return ERROR_INT("bad templates; recog destroyed", __func__, 1);
1196 return 0;
1197}
@ L_COPY
Definition pix.h:505
@ L_CLONE
Definition pix.h:506
@ L_NOCOPY
Definition pix.h:503
@ L_INSERT
Definition pix.h:504
@ L_USE_ALL_TEMPLATES
Definition recog.h:260
@ 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_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:966
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:996
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:931
L_RECOG * recogReadStream(FILE *fp)
recogReadStream()
Definition recogbasic.c:848
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