Leptonica  1.83.1
Image processing and image analysis suite
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 
196 static const l_int32 MaxExamplesInClass = 256;
197 
198  /* Default recog parameters that can be changed */
199 static const l_int32 DefaultCharsetType = L_ARABIC_NUMERALS;
200 static const l_int32 DefaultMinNopad = 1;
201 static const l_float32 DefaultMaxWHRatio = 3.0; /* max allowed w/h
202  ratio for a component to be split */
203 static const l_float32 DefaultMaxHTRatio = 2.6; /* max allowed ratio of
204  max/min unscaled averaged template heights */
205 static const l_int32 DefaultThreshold = 150; /* for binarization */
206 static const l_int32 DefaultMaxYShift = 1; /* for identification */
207 
208  /* Static functions */
209 static l_int32 recogGetCharsetSize(l_int32 type);
210 static l_int32 recogAddCharstrLabels(L_RECOG *recog);
211 static l_int32 recogAddAllSamples(L_RECOG **precog, PIXAA *paa, l_int32 debug);
212 
213 
214 /*------------------------------------------------------------------------*
215  * Recog: initialization and destruction *
216  *------------------------------------------------------------------------*/
236 L_RECOG *
238  l_int32 scalew,
239  l_int32 scaleh,
240  l_int32 linew,
241  l_int32 threshold,
242  l_int32 maxyshift)
243 {
244 L_RECOG *recd;
245 PIXA *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 
281 L_RECOG *
283  l_int32 scalew,
284  l_int32 scaleh,
285  l_int32 linew,
286  l_int32 threshold,
287  l_int32 maxyshift)
288 {
289 L_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 
325 L_RECOG *
327  l_int32 scalew,
328  l_int32 scaleh,
329  l_int32 linew,
330  l_int32 threshold,
331  l_int32 maxyshift)
332 {
333 char *text;
334 l_int32 full, n, i, ntext, same, maxd;
335 PIX *pix;
336 L_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 
404 L_RECOG *
405 recogCreate(l_int32 scalew,
406  l_int32 scaleh,
407  l_int32 linew,
408  l_int32 threshold,
409  l_int32 maxyshift)
410 {
411 L_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 
471 void
473 {
474 L_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  *------------------------------------------------------------------------*/
524 l_int32
526 {
527  if (!recog)
528  return ERROR_INT("recog not defined", __func__, 0);
529  return recog->setsize;
530 }
531 
532 
560 l_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 
587 static l_int32
588 recogGetCharsetSize(l_int32 type)
589 {
590  switch (type) {
591  case L_UNKNOWN:
592  return 0;
593  case L_ARABIC_NUMERALS:
594  return 10;
595  case L_LC_ROMAN_NUMERALS:
596  return 7;
597  case L_UC_ROMAN_NUMERALS:
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  *------------------------------------------------------------------------*/
638 l_int32
640  l_int32 val,
641  char *text,
642  l_int32 *pindex)
643 {
644 l_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 
681 l_ok
683  char *text,
684  l_int32 *pindex)
685 {
686 char *charstr;
687 l_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 
732 l_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 
760 l_ok
761 l_convertCharstrToInt(const char *str,
762  l_int32 *pval)
763 {
764 l_int32 size;
765 l_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  *------------------------------------------------------------------------*/
818 L_RECOG *
819 recogRead(const char *filename)
820 {
821 FILE *fp;
822 L_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 
845 L_RECOG *
847 {
848 l_int32 version, setsize, threshold, scalew, scaleh, linew;
849 l_int32 maxyshift, nc;
850 L_DNA *dna_tochar;
851 PIXAA *paa;
852 L_RECOG *recog;
853 SARRAY *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 
928 L_RECOG *
929 recogReadMem(const l_uint8 *data,
930  size_t size)
931 {
932 FILE *fp;
933 L_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 
963 l_ok
964 recogWrite(const char *filename,
965  L_RECOG *recog)
966 {
967 l_int32 ret;
968 FILE *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 
992 l_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 
1031 l_ok
1032 recogWriteMem(l_uint8 **pdata,
1033  size_t *psize,
1034  L_RECOG *recog)
1035 {
1036 l_int32 ret;
1037 FILE *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 
1086 PIXA *
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 
1103 static l_int32
1105 {
1106 char *text;
1107 l_int32 i, j, n1, n2;
1108 PIX *pix;
1109 PIXA *pixa;
1110 PIXAA *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 
1153 static l_int32
1155  PIXAA *paa,
1156  l_int32 debug)
1157 {
1158 char *text;
1159 l_int32 i, j, nc, ns;
1160 PIX *pix;
1161 PIXA *pixa, *pixa1;
1162 L_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 }
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition: bmf.c:168
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition: bmf.c:118
L_DNA * l_dnaReadStream(FILE *fp)
l_dnaReadStream()
Definition: dnabasic.c:958
l_ok l_dnaWriteStream(FILE *fp, L_DNA *da)
l_dnaWriteStream()
Definition: dnabasic.c:1060
L_DNA * l_dnaCreate(l_int32 n)
l_dnaCreate()
Definition: dnabasic.c:179
l_ok l_dnaGetIValue(L_DNA *da, l_int32 index, l_int32 *pival)
l_dnaGetIValue()
Definition: dnabasic.c:693
l_ok l_dnaAddNumber(L_DNA *da, l_float64 val)
l_dnaAddNumber()
Definition: dnabasic.c:430
void l_dnaDestroy(L_DNA **pda)
l_dnaDestroy()
Definition: dnabasic.c:323
l_int32 l_dnaGetCount(L_DNA *da)
l_dnaGetCount()
Definition: dnabasic.c:603
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:357
void numaaDestroy(NUMAA **pnaa)
numaaDestroy()
Definition: numabasic.c:1401
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:608
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1408
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1430
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2354
l_int32 * makePixelCentroidTab8(void)
makePixelCentroidTab8()
Definition: pix3.c:2394
@ L_COPY
Definition: pix.h:505
@ L_CLONE
Definition: pix.h:506
@ L_NOCOPY
Definition: pix.h:503
@ L_INSERT
Definition: pix.h:504
PIXAA * pixaaCreate(l_int32 n)
pixaaCreate()
Definition: pixabasic.c:1758
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:404
l_ok pixaVerifyDepth(PIXA *pixa, l_int32 *psame, l_int32 *pmaxd)
pixaVerifyDepth()
Definition: pixabasic.c:900
l_ok pixaCountText(PIXA *pixa, l_int32 *pntext)
pixaCountText()
Definition: pixabasic.c:1041
PIXAA * pixaaReadStream(FILE *fp)
pixaaReadStream()
Definition: pixabasic.c:2916
l_ok pixaaAddPix(PIXAA *paa, l_int32 index, PIX *pix, BOX *box, l_int32 copyflag)
pixaaAddPix()
Definition: pixabasic.c:1979
l_ok pixaaAddPixa(PIXAA *paa, PIXA *pixa, l_int32 copyflag)
pixaaAddPixa()
Definition: pixabasic.c:1898
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:629
l_ok pixaIsFull(PIXA *pixa, l_int32 *pfullpa, l_int32 *pfullba)
pixaIsFull()
Definition: pixabasic.c:993
l_ok pixaaWriteStream(FILE *fp, PIXAA *paa)
pixaaWriteStream()
Definition: pixabasic.c:3048
void pixaaDestroy(PIXAA **ppaa)
pixaaDestroy()
Definition: pixabasic.c:1859
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2049
PIXA * pixaaGetPixa(PIXAA *paa, l_int32 index, l_int32 accesstype)
pixaaGetPixa()
Definition: pixabasic.c:2096
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:647
PIXA * pixaaFlattenToPixa(PIXAA *paa, NUMA **pnaindex, l_int32 copyflag)
pixaaFlattenToPixa()
Definition: pixafunc1.c:2413
void ptaaDestroy(PTAA **pptaa)
ptaaDestroy()
Definition: ptabasic.c:930
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:191
@ 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:964
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
static l_int32 recogGetCharsetSize(l_int32 type)
recogGetCharsetSize()
Definition: recogbasic.c:588
L_RECOG * recogRead(const char *filename)
recogRead()
Definition: recogbasic.c:819
l_ok recogWriteMem(l_uint8 **pdata, size_t *psize, L_RECOG *recog)
recogWriteMem()
Definition: recogbasic.c:1032
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()
Definition: recogbasic.c:1154
l_ok l_convertCharstrToInt(const char *str, l_int32 *pval)
l_convertCharstrToInt()
Definition: recogbasic.c:761
PIXA * recogExtractPixa(L_RECOG *recog)
recogExtractPixa()
Definition: recogbasic.c:1087
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()
Definition: recogbasic.c:1104
L_RECOG * recogCreate(l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift)
recogCreate()
Definition: recogbasic.c:405
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
L_RECOG * recogReadMem(const l_uint8 *data, size_t size)
recogReadMem()
Definition: recogbasic.c:929
l_int32 recogGetClassString(L_RECOG *recog, l_int32 index, char **pcharstr)
recogGetClassString()
Definition: recogbasic.c:733
l_int32 recogGetCount(L_RECOG *recog)
recogGetCount()
Definition: recogbasic.c:525
L_RECOG * recogReadStream(FILE *fp)
recogReadStream()
Definition: recogbasic.c:846
void recogDestroy(L_RECOG **precog)
recogDestroy()
Definition: recogbasic.c:472
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_ok recogDestroyDid(L_RECOG *recog)
recogDestroyDid()
Definition: recogdid.c:811
void rchaDestroy(L_RCHA **prcha)
rchaDestroy()
Definition: recogident.c:1157
void rchDestroy(L_RCH **prch)
rchDestroy()
Definition: recogident.c:1228
l_ok recogTrainingFinished(L_RECOG **precog, l_int32 modifyflag, l_int32 minsize, l_float32 minfract)
recogTrainingFinished()
Definition: recogtrain.c:769
l_ok recogTrainLabeled(L_RECOG *recog, PIX *pixs, BOX *box, char *text, l_int32 debug)
recogTrainLabeled()
Definition: recogtrain.c:217
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:169
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:673
SARRAY * sarrayReadStream(FILE *fp)
sarrayReadStream()
Definition: sarray1.c:1386
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:353
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:435
l_ok sarrayWriteStream(FILE *fp, SARRAY *sa)
sarrayWriteStream()
Definition: sarray1.c:1515
Definition: recog.h:116
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
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:223
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1358
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1937
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1905
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:1981
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1864