Leptonica  1.82.0
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  PROCNAME("recogCreateFromRecog");
248 
249  if (!recs)
250  return (L_RECOG *)ERROR_PTR("recs not defined", procName, NULL);
251 
252  pixa = recogExtractPixa(recs);
253  recd = recogCreateFromPixa(pixa, scalew, scaleh, linew, threshold,
254  maxyshift);
255  pixaDestroy(&pixa);
256  return recd;
257 }
258 
259 
283 L_RECOG *
285  l_int32 scalew,
286  l_int32 scaleh,
287  l_int32 linew,
288  l_int32 threshold,
289  l_int32 maxyshift)
290 {
291 L_RECOG *recog;
292 
293  PROCNAME("recogCreateFromPixa");
294 
295  if (!pixa)
296  return (L_RECOG *)ERROR_PTR("pixa not defined", procName, NULL);
297 
298  recog = recogCreateFromPixaNoFinish(pixa, scalew, scaleh, linew,
299  threshold, maxyshift);
300  if (!recog)
301  return (L_RECOG *)ERROR_PTR("recog not made", procName, NULL);
302 
303  recogTrainingFinished(&recog, 1, -1, -1.0);
304  if (!recog)
305  return (L_RECOG *)ERROR_PTR("bad templates", procName, NULL);
306  return recog;
307 }
308 
309 
329 L_RECOG *
331  l_int32 scalew,
332  l_int32 scaleh,
333  l_int32 linew,
334  l_int32 threshold,
335  l_int32 maxyshift)
336 {
337 char *text;
338 l_int32 full, n, i, ntext, same, maxd;
339 PIX *pix;
340 L_RECOG *recog;
341 
342  PROCNAME("recogCreateFromPixaNoFinish");
343 
344  if (!pixa)
345  return (L_RECOG *)ERROR_PTR("pixa not defined", procName, NULL);
346  pixaVerifyDepth(pixa, &same, &maxd);
347  if (maxd > 1)
348  return (L_RECOG *)ERROR_PTR("not all pix are 1 bpp", procName, NULL);
349 
350  pixaIsFull(pixa, &full, NULL);
351  if (!full)
352  return (L_RECOG *)ERROR_PTR("not all pix are present", procName, NULL);
353 
354  n = pixaGetCount(pixa);
355  pixaCountText(pixa, &ntext);
356  if (ntext == 0)
357  return (L_RECOG *)ERROR_PTR("no pix have text strings", procName, NULL);
358  if (ntext < n)
359  L_ERROR("%d text strings < %d pix\n", procName, ntext, n);
360 
361  recog = recogCreate(scalew, scaleh, linew, threshold, maxyshift);
362  if (!recog)
363  return (L_RECOG *)ERROR_PTR("recog not made", procName, NULL);
364  for (i = 0; i < n; i++) {
365  pix = pixaGetPix(pixa, i, L_CLONE);
366  text = pixGetText(pix);
367  if (!text || strlen(text) == 0) {
368  L_ERROR("pix[%d] has no text\n", procName, i);
369  pixDestroy(&pix);
370  continue;
371  }
372  recogTrainLabeled(recog, pix, NULL, text, 0);
373  pixDestroy(&pix);
374  }
375 
376  return recog;
377 }
378 
379 
410 L_RECOG *
411 recogCreate(l_int32 scalew,
412  l_int32 scaleh,
413  l_int32 linew,
414  l_int32 threshold,
415  l_int32 maxyshift)
416 {
417 L_RECOG *recog;
418 
419  PROCNAME("recogCreate");
420 
421  if (scalew < 0 || scaleh < 0)
422  return (L_RECOG *)ERROR_PTR("invalid scalew or scaleh", procName, NULL);
423  if (linew > 10)
424  return (L_RECOG *)ERROR_PTR("invalid linew > 10", procName, NULL);
425  if (threshold == 0) threshold = DefaultThreshold;
426  if (threshold < 0 || threshold > 255) {
427  L_WARNING("invalid threshold; using default\n", procName);
428  threshold = DefaultThreshold;
429  }
430  if (maxyshift < 0 || maxyshift > 2) {
431  L_WARNING("invalid maxyshift; using default value\n", procName);
432  maxyshift = DefaultMaxYShift;
433  } else if (maxyshift == 0) {
434  L_WARNING("Using maxyshift = 0; faster, worse correlation results\n",
435  procName);
436  } else if (maxyshift == 2) {
437  L_WARNING("Using maxyshift = 2; slower\n", procName);
438  }
439 
440  recog = (L_RECOG *)LEPT_CALLOC(1, sizeof(L_RECOG));
441  recog->templ_use = L_USE_ALL_TEMPLATES; /* default */
442  recog->threshold = threshold;
443  recog->scalew = scalew;
444  recog->scaleh = scaleh;
445  recog->linew = linew;
446  recog->maxyshift = maxyshift;
447  recogSetParams(recog, 1, -1, -1.0, -1.0);
448  recog->bmf = bmfCreate(NULL, 6);
449  recog->bmf_size = 6;
450  recog->maxarraysize = MaxExamplesInClass;
451 
452  /* Generate the LUTs */
453  recog->centtab = makePixelCentroidTab8();
454  recog->sumtab = makePixelSumTab8();
455  recog->sa_text = sarrayCreate(0);
456  recog->dna_tochar = l_dnaCreate(0);
457 
458  /* Input default values for min component size for splitting.
459  * These are overwritten when pixTrainingFinished() is called. */
460  recog->min_splitw = 6;
461  recog->max_splith = 60;
462 
463  /* Allocate the paa for the unscaled training bitmaps */
464  recog->pixaa_u = pixaaCreate(recog->maxarraysize);
465 
466  /* Generate the storage for debugging */
467  recog->pixadb_boot = pixaCreate(2);
468  recog->pixadb_split = pixaCreate(2);
469  return recog;
470 }
471 
472 
479 void
481 {
482 L_RECOG *recog;
483 
484  PROCNAME("recogDestroy");
485 
486  if (!precog) {
487  L_WARNING("ptr address is null\n", procName);
488  return;
489  }
490 
491  if ((recog = *precog) == NULL) return;
492 
493  LEPT_FREE(recog->centtab);
494  LEPT_FREE(recog->sumtab);
495  sarrayDestroy(&recog->sa_text);
496  l_dnaDestroy(&recog->dna_tochar);
497  pixaaDestroy(&recog->pixaa_u);
498  pixaDestroy(&recog->pixa_u);
499  ptaaDestroy(&recog->ptaa_u);
500  ptaDestroy(&recog->pta_u);
501  numaDestroy(&recog->nasum_u);
502  numaaDestroy(&recog->naasum_u);
503  pixaaDestroy(&recog->pixaa);
504  pixaDestroy(&recog->pixa);
505  ptaaDestroy(&recog->ptaa);
506  ptaDestroy(&recog->pta);
507  numaDestroy(&recog->nasum);
508  numaaDestroy(&recog->naasum);
509  pixaDestroy(&recog->pixa_tr);
510  pixaDestroy(&recog->pixadb_ave);
511  pixaDestroy(&recog->pixa_id);
512  pixDestroy(&recog->pixdb_ave);
513  pixDestroy(&recog->pixdb_range);
514  pixaDestroy(&recog->pixadb_boot);
515  pixaDestroy(&recog->pixadb_split);
516  bmfDestroy(&recog->bmf);
517  rchDestroy(&recog->rch);
518  rchaDestroy(&recog->rcha);
519  recogDestroyDid(recog);
520  LEPT_FREE(recog);
521  *precog = NULL;
522 }
523 
524 
525 /*------------------------------------------------------------------------*
526  * Recog accessors *
527  *------------------------------------------------------------------------*/
534 l_int32
536 {
537  PROCNAME("recogGetCount");
538 
539  if (!recog)
540  return ERROR_INT("recog not defined", procName, 0);
541  return recog->setsize;
542 }
543 
544 
572 l_ok
574  l_int32 type,
575  l_int32 min_nopad,
576  l_float32 max_wh_ratio,
577  l_float32 max_ht_ratio)
578 {
579  PROCNAME("recogSetParams");
580 
581  if (!recog)
582  return ERROR_INT("recog not defined", procName, 1);
583 
584  recog->charset_type = (type >= 0) ? type : DefaultCharsetType;
586  recog->min_nopad = (min_nopad >= 0) ? min_nopad : DefaultMinNopad;
587  recog->max_wh_ratio = (max_wh_ratio > 0.0) ? max_wh_ratio :
588  DefaultMaxWHRatio;
589  recog->max_ht_ratio = (max_ht_ratio > 1.0) ? max_ht_ratio :
590  DefaultMaxHTRatio;
591  return 0;
592 }
593 
594 
601 static l_int32
602 recogGetCharsetSize(l_int32 type)
603 {
604  PROCNAME("recogGetCharsetSize");
605 
606  switch (type) {
607  case L_UNKNOWN:
608  return 0;
609  case L_ARABIC_NUMERALS:
610  return 10;
611  case L_LC_ROMAN_NUMERALS:
612  return 7;
613  case L_UC_ROMAN_NUMERALS:
614  return 7;
615  case L_LC_ALPHA:
616  return 26;
617  case L_UC_ALPHA:
618  return 26;
619  default:
620  L_ERROR("invalid charset_type %d\n", procName, type);
621  return 0;
622  }
623  return 0; /* shouldn't happen */
624 }
625 
626 
627 /*------------------------------------------------------------------------*
628  * Character/index lookup *
629  *------------------------------------------------------------------------*/
654 l_int32
656  l_int32 val,
657  char *text,
658  l_int32 *pindex)
659 {
660 l_int32 i, n, ival;
661 
662  PROCNAME("recogGetClassIndex");
663 
664  if (!pindex)
665  return ERROR_INT("&index not defined", procName, 2);
666  *pindex = -1;
667  if (!recog)
668  return ERROR_INT("recog not defined", procName, 2);
669  if (!text)
670  return ERROR_INT("text not defined", procName, 2);
671 
672  /* Search existing characters */
673  n = l_dnaGetCount(recog->dna_tochar);
674  for (i = 0; i < n; i++) {
675  l_dnaGetIValue(recog->dna_tochar, i, &ival);
676  if (val == ival) { /* found */
677  *pindex = i;
678  return 0;
679  }
680  }
681 
682  /* If not found... */
683  l_dnaAddNumber(recog->dna_tochar, val);
684  sarrayAddString(recog->sa_text, text, L_COPY);
685  recog->setsize++;
686  *pindex = n;
687  return 1;
688 }
689 
690 
699 l_ok
701  char *text,
702  l_int32 *pindex)
703 {
704 char *charstr;
705 l_int32 i, n, diff;
706 
707  PROCNAME("recogStringtoIndex");
708 
709  if (!pindex)
710  return ERROR_INT("&index not defined", procName, 1);
711  *pindex = -1;
712  if (!recog)
713  return ERROR_INT("recog not defined", procName, 1);
714  if (!text)
715  return ERROR_INT("text not defined", procName, 1);
716 
717  /* Search existing characters */
718  n = recog->setsize;
719  for (i = 0; i < n; i++) {
720  recogGetClassString(recog, i, &charstr);
721  if (!charstr) {
722  L_ERROR("string not found for index %d\n", procName, i);
723  continue;
724  }
725  diff = strcmp(text, charstr);
726  LEPT_FREE(charstr);
727  if (diff) continue;
728  *pindex = i;
729  return 0;
730  }
731 
732  return 1; /* not found */
733 }
734 
735 
752 l_int32
754  l_int32 index,
755  char **pcharstr)
756 {
757  PROCNAME("recogGetClassString");
758 
759  if (!pcharstr)
760  return ERROR_INT("&charstr not defined", procName, 1);
761  *pcharstr = stringNew("");
762  if (!recog)
763  return ERROR_INT("recog not defined", procName, 2);
764 
765  if (index < 0 || index >= recog->setsize)
766  return ERROR_INT("invalid index", procName, 1);
767  LEPT_FREE(*pcharstr);
768  *pcharstr = sarrayGetString(recog->sa_text, index, L_COPY);
769  return 0;
770 }
771 
772 
782 l_ok
783 l_convertCharstrToInt(const char *str,
784  l_int32 *pval)
785 {
786 l_int32 size, val;
787 
788  PROCNAME("l_convertCharstrToInt");
789 
790  if (!pval)
791  return ERROR_INT("&val not defined", procName, 1);
792  *pval = 0;
793  if (!str)
794  return ERROR_INT("str not defined", procName, 1);
795  size = strlen(str);
796  if (size == 0)
797  return ERROR_INT("empty string", procName, 1);
798  if (size > 4)
799  return ERROR_INT("invalid string: > 4 bytes", procName, 1);
800 
801  val = (l_int32)str[0];
802  if (size > 1)
803  val = (val << 8) + (l_int32)str[1];
804  if (size > 2)
805  val = (val << 8) + (l_int32)str[2];
806  if (size > 3)
807  val = (val << 8) + (l_int32)str[3];
808  *pval = val;
809  return 0;
810 }
811 
812 
813 /*------------------------------------------------------------------------*
814  * Serialization *
815  *------------------------------------------------------------------------*/
841 L_RECOG *
842 recogRead(const char *filename)
843 {
844 FILE *fp;
845 L_RECOG *recog;
846 
847  PROCNAME("recogRead");
848 
849  if (!filename)
850  return (L_RECOG *)ERROR_PTR("filename not defined", procName, NULL);
851  if ((fp = fopenReadStream(filename)) == NULL)
852  return (L_RECOG *)ERROR_PTR("stream not opened", procName, NULL);
853 
854  if ((recog = recogReadStream(fp)) == NULL) {
855  fclose(fp);
856  return (L_RECOG *)ERROR_PTR("recog not read", procName, NULL);
857  }
858 
859  fclose(fp);
860  return recog;
861 }
862 
863 
870 L_RECOG *
872 {
873 l_int32 version, setsize, threshold, scalew, scaleh, linew;
874 l_int32 maxyshift, nc;
875 L_DNA *dna_tochar;
876 PIXAA *paa;
877 L_RECOG *recog;
878 SARRAY *sa_text;
879 
880  PROCNAME("recogReadStream");
881 
882  if (!fp)
883  return (L_RECOG *)ERROR_PTR("stream not defined", procName, NULL);
884 
885  if (fscanf(fp, "\nRecog Version %d\n", &version) != 1)
886  return (L_RECOG *)ERROR_PTR("not a recog file", procName, NULL);
887  if (version != RECOG_VERSION_NUMBER)
888  return (L_RECOG *)ERROR_PTR("invalid recog version", procName, NULL);
889  if (fscanf(fp, "Size of character set = %d\n", &setsize) != 1)
890  return (L_RECOG *)ERROR_PTR("setsize not read", procName, NULL);
891  if (fscanf(fp, "Binarization threshold = %d\n", &threshold) != 1)
892  return (L_RECOG *)ERROR_PTR("binary thresh not read", procName, NULL);
893  if (fscanf(fp, "Maxyshift = %d\n", &maxyshift) != 1)
894  return (L_RECOG *)ERROR_PTR("maxyshift not read", procName, NULL);
895  if (fscanf(fp, "Scale to width = %d\n", &scalew) != 1)
896  return (L_RECOG *)ERROR_PTR("width not read", procName, NULL);
897  if (fscanf(fp, "Scale to height = %d\n", &scaleh) != 1)
898  return (L_RECOG *)ERROR_PTR("height not read", procName, NULL);
899  if (fscanf(fp, "Normalized line width = %d\n", &linew) != 1)
900  return (L_RECOG *)ERROR_PTR("line width not read", procName, NULL);
901  if ((recog = recogCreate(scalew, scaleh, linew, threshold,
902  maxyshift)) == NULL)
903  return (L_RECOG *)ERROR_PTR("recog not made", procName, NULL);
904 
905  if (fscanf(fp, "\nLabels for character set:\n") != 0) {
906  recogDestroy(&recog);
907  return (L_RECOG *)ERROR_PTR("label intro not read", procName, NULL);
908  }
909  l_dnaDestroy(&recog->dna_tochar);
910  if ((dna_tochar = l_dnaReadStream(fp)) == NULL) {
911  recogDestroy(&recog);
912  return (L_RECOG *)ERROR_PTR("dna_tochar not read", procName, NULL);
913  }
914  recog->dna_tochar = dna_tochar;
915  sarrayDestroy(&recog->sa_text);
916  if ((sa_text = sarrayReadStream(fp)) == NULL) {
917  recogDestroy(&recog);
918  return (L_RECOG *)ERROR_PTR("sa_text not read", procName, NULL);
919  }
920  recog->sa_text = sa_text;
921 
922  if (fscanf(fp, "\nPixaa of all samples in the training set:\n") != 0) {
923  recogDestroy(&recog);
924  return (L_RECOG *)ERROR_PTR("pixaa intro not read", procName, NULL);
925  }
926  if ((paa = pixaaReadStream(fp)) == NULL) {
927  recogDestroy(&recog);
928  return (L_RECOG *)ERROR_PTR("pixaa not read", procName, NULL);
929  }
930  recog->setsize = setsize;
931  nc = pixaaGetCount(paa, NULL);
932  if (nc != setsize) {
933  recogDestroy(&recog);
934  pixaaDestroy(&paa);
935  L_ERROR("(setsize = %d) != (paa count = %d)\n", procName,
936  setsize, nc);
937  return NULL;
938  }
939 
940  recogAddAllSamples(&recog, paa, 0); /* this finishes */
941  pixaaDestroy(&paa);
942  if (!recog)
943  return (L_RECOG *)ERROR_PTR("bad templates", procName, NULL);
944  return recog;
945 }
946 
947 
955 L_RECOG *
956 recogReadMem(const l_uint8 *data,
957  size_t size)
958 {
959 FILE *fp;
960 L_RECOG *recog;
961 
962  PROCNAME("recogReadMem");
963 
964  if (!data)
965  return (L_RECOG *)ERROR_PTR("data not defined", procName, NULL);
966  if ((fp = fopenReadFromMemory(data, size)) == NULL)
967  return (L_RECOG *)ERROR_PTR("stream not opened", procName, NULL);
968 
969  recog = recogReadStream(fp);
970  fclose(fp);
971  if (!recog) L_ERROR("recog not read\n", procName);
972  return recog;
973 }
974 
975 
992 l_ok
993 recogWrite(const char *filename,
994  L_RECOG *recog)
995 {
996 l_int32 ret;
997 FILE *fp;
998 
999  PROCNAME("recogWrite");
1000 
1001  if (!filename)
1002  return ERROR_INT("filename not defined", procName, 1);
1003  if (!recog)
1004  return ERROR_INT("recog not defined", procName, 1);
1005 
1006  if ((fp = fopenWriteStream(filename, "wb")) == NULL)
1007  return ERROR_INT("stream not opened", procName, 1);
1008  ret = recogWriteStream(fp, recog);
1009  fclose(fp);
1010  if (ret)
1011  return ERROR_INT("recog not written to stream", procName, 1);
1012  return 0;
1013 }
1014 
1015 
1023 l_ok
1025  L_RECOG *recog)
1026 {
1027  PROCNAME("recogWriteStream");
1028 
1029  if (!fp)
1030  return ERROR_INT("stream not defined", procName, 1);
1031  if (!recog)
1032  return ERROR_INT("recog not defined", procName, 1);
1033 
1034  fprintf(fp, "\nRecog Version %d\n", RECOG_VERSION_NUMBER);
1035  fprintf(fp, "Size of character set = %d\n", recog->setsize);
1036  fprintf(fp, "Binarization threshold = %d\n", recog->threshold);
1037  fprintf(fp, "Maxyshift = %d\n", recog->maxyshift);
1038  fprintf(fp, "Scale to width = %d\n", recog->scalew);
1039  fprintf(fp, "Scale to height = %d\n", recog->scaleh);
1040  fprintf(fp, "Normalized line width = %d\n", recog->linew);
1041  fprintf(fp, "\nLabels for character set:\n");
1042  l_dnaWriteStream(fp, recog->dna_tochar);
1043  sarrayWriteStream(fp, recog->sa_text);
1044  fprintf(fp, "\nPixaa of all samples in the training set:\n");
1045  pixaaWriteStream(fp, recog->pixaa);
1046 
1047  return 0;
1048 }
1049 
1050 
1064 l_ok
1065 recogWriteMem(l_uint8 **pdata,
1066  size_t *psize,
1067  L_RECOG *recog)
1068 {
1069 l_int32 ret;
1070 FILE *fp;
1071 
1072  PROCNAME("recogWriteMem");
1073 
1074  if (pdata) *pdata = NULL;
1075  if (psize) *psize = 0;
1076  if (!pdata)
1077  return ERROR_INT("&data not defined", procName, 1);
1078  if (!psize)
1079  return ERROR_INT("&size not defined", procName, 1);
1080  if (!recog)
1081  return ERROR_INT("recog not defined", procName, 1);
1082 
1083 #if HAVE_FMEMOPEN
1084  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1085  return ERROR_INT("stream not opened", procName, 1);
1086  ret = recogWriteStream(fp, recog);
1087  fputc('\0', fp);
1088  fclose(fp);
1089  *psize = *psize - 1;
1090 #else
1091  L_INFO("work-around: writing to a temp file\n", procName);
1092  #ifdef _WIN32
1093  if ((fp = fopenWriteWinTempfile()) == NULL)
1094  return ERROR_INT("tmpfile stream not opened", procName, 1);
1095  #else
1096  if ((fp = tmpfile()) == NULL)
1097  return ERROR_INT("tmpfile stream not opened", procName, 1);
1098  #endif /* _WIN32 */
1099  ret = recogWriteStream(fp, recog);
1100  rewind(fp);
1101  *pdata = l_binaryReadStream(fp, psize);
1102  fclose(fp);
1103 #endif /* HAVE_FMEMOPEN */
1104  return ret;
1105 }
1106 
1107 
1121 PIXA *
1123 {
1124  PROCNAME("recogExtractPixa");
1125 
1126  if (!recog)
1127  return (PIXA *)ERROR_PTR("recog not defined", procName, NULL);
1128 
1129  recogAddCharstrLabels(recog);
1130  return pixaaFlattenToPixa(recog->pixaa_u, NULL, L_CLONE);
1131 }
1132 
1133 
1140 static l_int32
1142 {
1143 char *text;
1144 l_int32 i, j, n1, n2;
1145 PIX *pix;
1146 PIXA *pixa;
1147 PIXAA *paa;
1148 
1149  PROCNAME("recogAddCharstrLabels");
1150 
1151  if (!recog)
1152  return ERROR_INT("recog not defined", procName, 1);
1153 
1154  /* Add the labels to each unscaled pix */
1155  paa = recog->pixaa_u;
1156  n1 = pixaaGetCount(paa, NULL);
1157  for (i = 0; i < n1; i++) {
1158  pixa = pixaaGetPixa(paa, i, L_CLONE);
1159  text = sarrayGetString(recog->sa_text, i, L_NOCOPY);
1160  n2 = pixaGetCount(pixa);
1161  for (j = 0; j < n2; j++) {
1162  pix = pixaGetPix(pixa, j, L_CLONE);
1163  pixSetText(pix, text);
1164  pixDestroy(&pix);
1165  }
1166  pixaDestroy(&pixa);
1167  }
1168 
1169  return 0;
1170 }
1171 
1172 
1192 static l_int32
1194  PIXAA *paa,
1195  l_int32 debug)
1196 {
1197 char *text;
1198 l_int32 i, j, nc, ns;
1199 PIX *pix;
1200 PIXA *pixa, *pixa1;
1201 L_RECOG *recog;
1202 
1203  PROCNAME("recogAddAllSamples");
1204 
1205  if (!precog)
1206  return ERROR_INT("&recog not defined", procName, 1);
1207  if ((recog = *precog) == NULL)
1208  return ERROR_INT("recog not defined", procName, 1);
1209  if (!paa) {
1210  recogDestroy(&recog);
1211  return ERROR_INT("paa not defined", procName, 1);
1212  }
1213 
1214  nc = pixaaGetCount(paa, NULL);
1215  for (i = 0; i < nc; i++) {
1216  pixa = pixaaGetPixa(paa, i, L_CLONE);
1217  ns = pixaGetCount(pixa);
1218  text = sarrayGetString(recog->sa_text, i, L_NOCOPY);
1219  pixa1 = pixaCreate(ns);
1220  pixaaAddPixa(recog->pixaa_u, pixa1, L_INSERT);
1221  for (j = 0; j < ns; j++) {
1222  pix = pixaGetPix(pixa, j, L_CLONE);
1223  if (debug) lept_stderr("pix[%d,%d]: text = %s\n", i, j, text);
1224  pixaaAddPix(recog->pixaa_u, i, pix, NULL, L_INSERT);
1225  }
1226  pixaDestroy(&pixa);
1227  }
1228 
1229  recogTrainingFinished(&recog, 0, -1, -1.0); /* For second parameter,
1230  see comment in recogRead() */
1231  if (!recog)
1232  return ERROR_INT("bad templates; recog destroyed", procName, 1);
1233  return 0;
1234 }
void bmfDestroy(L_BMF **pbmf)
bmfDestroy()
Definition: bmf.c:169
L_BMF * bmfCreate(const char *dir, l_int32 fontsize)
bmfCreate()
Definition: bmf.c:117
L_DNA * l_dnaReadStream(FILE *fp)
l_dnaReadStream()
Definition: dnabasic.c:1047
l_ok l_dnaWriteStream(FILE *fp, L_DNA *da)
l_dnaWriteStream()
Definition: dnabasic.c:1155
L_DNA * l_dnaCreate(l_int32 n)
l_dnaCreate()
Definition: dnabasic.c:180
l_ok l_dnaGetIValue(L_DNA *da, l_int32 index, l_int32 *pival)
l_dnaGetIValue()
Definition: dnabasic.c:727
l_ok l_dnaAddNumber(L_DNA *da, l_float64 val)
l_dnaAddNumber()
Definition: dnabasic.c:448
void l_dnaDestroy(L_DNA **pda)
l_dnaDestroy()
Definition: dnabasic.c:332
l_int32 l_dnaGetCount(L_DNA *da)
l_dnaGetCount()
Definition: dnabasic.c:631
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
void numaaDestroy(NUMAA **pnaa)
numaaDestroy()
Definition: numabasic.c:1510
void pixDestroy(PIX **ppix)
pixDestroy()
Definition: pix1.c:621
char * pixGetText(PIX *pix)
pixGetText()
Definition: pix1.c:1512
l_ok pixSetText(PIX *pix, const char *textstring)
pixSetText()
Definition: pix1.c:1536
l_int32 * makePixelSumTab8(void)
makePixelSumTab8()
Definition: pix3.c:2411
l_int32 * makePixelCentroidTab8(void)
makePixelCentroidTab8()
Definition: pix3.c:2451
@ L_COPY
Definition: pix.h:712
@ L_CLONE
Definition: pix.h:713
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
PIXAA * pixaaCreate(l_int32 n)
pixaaCreate()
Definition: pixabasic.c:1852
void pixaDestroy(PIXA **ppixa)
pixaDestroy()
Definition: pixabasic.c:412
l_ok pixaVerifyDepth(PIXA *pixa, l_int32 *psame, l_int32 *pmaxd)
pixaVerifyDepth()
Definition: pixabasic.c:960
l_ok pixaCountText(PIXA *pixa, l_int32 *pntext)
pixaCountText()
Definition: pixabasic.c:1107
PIXAA * pixaaReadStream(FILE *fp)
pixaaReadStream()
Definition: pixabasic.c:3066
l_ok pixaaAddPix(PIXAA *paa, l_int32 index, PIX *pix, BOX *box, l_int32 copyflag)
pixaaAddPix()
Definition: pixabasic.c:2083
l_ok pixaaAddPixa(PIXAA *paa, PIXA *pixa, l_int32 copyflag)
pixaaAddPixa()
Definition: pixabasic.c:1998
PIXA * pixaCreate(l_int32 n)
pixaCreate()
Definition: pixabasic.c:167
l_int32 pixaGetCount(PIXA *pixa)
pixaGetCount()
Definition: pixabasic.c:650
l_ok pixaIsFull(PIXA *pixa, l_int32 *pfullpa, l_int32 *pfullba)
pixaIsFull()
Definition: pixabasic.c:1057
l_ok pixaaWriteStream(FILE *fp, PIXAA *paa)
pixaaWriteStream()
Definition: pixabasic.c:3204
void pixaaDestroy(PIXAA **ppaa)
pixaaDestroy()
Definition: pixabasic.c:1957
l_int32 pixaaGetCount(PIXAA *paa, NUMA **pna)
pixaaGetCount()
Definition: pixabasic.c:2157
PIXA * pixaaGetPixa(PIXAA *paa, l_int32 index, l_int32 accesstype)
pixaaGetPixa()
Definition: pixabasic.c:2206
PIX * pixaGetPix(PIXA *pixa, l_int32 index, l_int32 accesstype)
pixaGetPix()
Definition: pixabasic.c:691
PIXA * pixaaFlattenToPixa(PIXAA *paa, NUMA **pnaindex, l_int32 copyflag)
pixaaFlattenToPixa()
Definition: pixafunc1.c:2482
void ptaaDestroy(PTAA **pptaa)
ptaaDestroy()
Definition: ptabasic.c:1003
void ptaDestroy(PTA **ppta)
ptaDestroy()
Definition: ptabasic.c:195
@ 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:700
l_ok recogWrite(const char *filename, L_RECOG *recog)
recogWrite()
Definition: recogbasic.c:993
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:602
L_RECOG * recogRead(const char *filename)
recogRead()
Definition: recogbasic.c:842
l_ok recogWriteMem(l_uint8 **pdata, size_t *psize, L_RECOG *recog)
recogWriteMem()
Definition: recogbasic.c:1065
l_ok recogWriteStream(FILE *fp, L_RECOG *recog)
recogWriteStream()
Definition: recogbasic.c:1024
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:573
static l_int32 recogAddAllSamples(L_RECOG **precog, PIXAA *paa, l_int32 debug)
recogAddAllSamples()
Definition: recogbasic.c:1193
l_ok l_convertCharstrToInt(const char *str, l_int32 *pval)
l_convertCharstrToInt()
Definition: recogbasic.c:783
PIXA * recogExtractPixa(L_RECOG *recog)
recogExtractPixa()
Definition: recogbasic.c:1122
l_int32 recogGetClassIndex(L_RECOG *recog, l_int32 val, char *text, l_int32 *pindex)
recogGetClassIndex()
Definition: recogbasic.c:655
static l_int32 recogAddCharstrLabels(L_RECOG *recog)
recogAddCharstrLabels()
Definition: recogbasic.c:1141
L_RECOG * recogCreate(l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift)
recogCreate()
Definition: recogbasic.c:411
L_RECOG * recogCreateFromPixa(PIXA *pixa, l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift)
recogCreateFromPixa()
Definition: recogbasic.c:284
L_RECOG * recogReadMem(const l_uint8 *data, size_t size)
recogReadMem()
Definition: recogbasic.c:956
l_int32 recogGetClassString(L_RECOG *recog, l_int32 index, char **pcharstr)
recogGetClassString()
Definition: recogbasic.c:753
l_int32 recogGetCount(L_RECOG *recog)
recogGetCount()
Definition: recogbasic.c:535
L_RECOG * recogReadStream(FILE *fp)
recogReadStream()
Definition: recogbasic.c:871
void recogDestroy(L_RECOG **precog)
recogDestroy()
Definition: recogbasic.c:480
L_RECOG * recogCreateFromPixaNoFinish(PIXA *pixa, l_int32 scalew, l_int32 scaleh, l_int32 linew, l_int32 threshold, l_int32 maxyshift)
recogCreateFromPixaNoFinish()
Definition: recogbasic.c:330
l_ok recogDestroyDid(L_RECOG *recog)
recogDestroyDid()
Definition: recogdid.c:822
void rchaDestroy(L_RCHA **prcha)
rchaDestroy()
Definition: recogident.c:1172
void rchDestroy(L_RCH **prch)
rchDestroy()
Definition: recogident.c:1245
l_ok recogTrainingFinished(L_RECOG **precog, l_int32 modifyflag, l_int32 minsize, l_float32 minfract)
recogTrainingFinished()
Definition: recogtrain.c:787
l_ok recogTrainLabeled(L_RECOG *recog, PIX *pixs, BOX *box, char *text, l_int32 debug)
recogTrainLabeled()
Definition: recogtrain.c:216
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:170
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
SARRAY * sarrayReadStream(FILE *fp)
sarrayReadStream()
Definition: sarray1.c:1479
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:451
l_ok sarrayWriteStream(FILE *fp, SARRAY *sa)
sarrayWriteStream()
Definition: sarray1.c:1614
Definition: array.h:95
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
Definition: pix.h:139
Definition: pix.h:456
Definition: pix.h:467
Definition: array.h:127
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:1402
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:2009
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:2055
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932