162#include <config_auto.h>
166#include "allheaders.h"
171 l_float32 minfract, l_int32 *pok);
176 l_int32 maxclass, l_float32 maxscore);
182static const l_int32 DefaultMinSetSize = 1;
184static const l_float32 DefaultMinSetFract = 0.4f;
188static const l_float32 DefaultMinScore = 0.75;
189static const l_int32 DefaultMinTarget = 3;
190static const l_float32 LowerScoreThreshold = 0.5;
227 return ERROR_INT(
"recog not defined", __func__, 1);
229 return ERROR_INT(
"pixs not defined", __func__, 1);
236 L_WARNING(
"failure to get sample '%s' for training\n", __func__,
271l_int32 textinpix, textin, nsets;
273PIX *pix1, *pix2, *pix3, *pix4;
276 return ERROR_INT(
"&pix not defined", __func__, 1);
279 return ERROR_INT(
"recog not defined", __func__, 1);
281 return ERROR_INT(
"pixs not defined", __func__, 1);
284 textin = text && (text[0] !=
'\0');
285 textinpix = (pixs->
text && (pixs->
text[0] !=
'\0'));
286 if (!textin && !textinpix) {
287 L_ERROR(
"no text: %d\n", __func__, recog->
num_samples);
290 textdata = (textin) ? text : pixs->
text;
294 pix1 = pixClipRectangle(pixs, box, NULL);
296 pix1 = pixClone(pixs);
297 if (pixGetDepth(pix1) > 1)
298 pix2 = pixConvertTo1(pix1, recog->
threshold);
300 pix2 = pixClone(pix1);
305 pix3 = pixMorphSequence(pix2,
"o1.5", 0);
306 pixSeedfillBinary(pix3, pix3, pix2, 8);
310 pixClipToForeground(pix3, &pix4, NULL);
313 return ERROR_INT(
"pix4 is empty", __func__, 1);
317 na = pixCountByColumn(pix4, NULL);
318 numaCountNonzeroRuns(na, &nsets);
321 L_WARNING(
"found %d sets of horiz separated c.c.; skipping\n",
327 pixSetText(pix4, textdata);
358l_int32 npa, charint, index;
363 return ERROR_INT(
"recog not defined", __func__, 1);
364 if (!pix || pixGetDepth(pix) != 1)
365 return ERROR_INT(
"pix not defined or not 1 bpp\n", __func__, 1);
367 return ERROR_INT(
"not added: training has been completed", __func__, 1);
371 text = pixGetText(pix);
372 if (l_convertCharstrToInt(text, &charint) == 1) {
373 L_ERROR(
"invalid text: %s\n", __func__, text);
379 if (recogGetClassIndex(recog, charint, text, &index) == 1) {
381 npa = pixaaGetCount(paa, NULL);
383 L_ERROR(
"oops: bad index %d > npa %d!!\n", __func__, index, npa);
387 L_INFO(
"Adding new class and pixa: index = %d, text = %s\n",
388 __func__, index, text);
389 pixa1 = pixaCreate(10);
394 L_INFO(
"Identified text label: %s\n", __func__, text);
395 L_INFO(
"Identified: charint = %d, index = %d\n",
396 __func__, charint, index);
402 pixaaAddPix(paa, index, pix, NULL,
L_COPY);
423 return (
PIX *)ERROR_PTR(
"recog not defined", __func__, NULL);
425 return (
PIX *)ERROR_PTR(
"pixs not defined", __func__, NULL);
428 pixGetDimensions(pixs, &w, &h, NULL);
431 pix1 = pixCopy(NULL, pixs);
433 pix1 = pixScaleToSize(pixs, recog->
scalew, recog->
scaleh);
436 return (
PIX *)ERROR_PTR(
"pix1 not made", __func__, NULL);
439 if (recog->
linew <= 0) {
440 pix2 = pixClone(pix1);
442 pix2 = pixSetStrokeWidth(pix1, recog->
linew, 1, 8);
446 return (
PIX *)ERROR_PTR(
"pix2 not made", __func__, NULL);
449 pixZero(pix2, &empty);
452 return (
PIX *)ERROR_PTR(
"modified template has no pixels",
487l_int32 i, nsamp, size, area, bx, by, badclass;
488l_float32 x, y, hratio;
491PIX *pix1, *pix2, *pix3;
495 return ERROR_INT(
"recog not defined", __func__, 1);
505 pixaDestroy(&recog->
pixa_u);
506 ptaDestroy(&recog->
pta_u);
508 recog->
pixa_u = pixaCreate(size);
509 recog->
pta_u = ptaCreate(size);
510 recog->
nasum_u = numaCreate(size);
512 pixaDestroy(&recog->
pixa);
513 ptaDestroy(&recog->
pta);
514 numaDestroy(&recog->
nasum);
515 recog->
pixa = pixaCreate(size);
516 recog->
pta = ptaCreate(size);
517 recog->
nasum = numaCreate(size);
528 for (i = 0; i < size; i++) {
531 nsamp = pixaGetCount(pixa1);
532 nsamp = L_MIN(nsamp, 256);
534 L_ERROR(
"no samples in class %d\n", __func__, i);
541 pix2 = pixThresholdToBinary(pix1, L_MAX(1, nsamp / 2));
542 pixInvert(pix2, pix2);
543 pixClipToForeground(pix2, &pix3, &box);
545 L_ERROR(
"no fg pixels in average for uclass %d\n", __func__, i);
553 boxGetGeometry(box, &bx, &by, NULL, NULL);
555 ptaAddPt(recog->
pta_u, x - bx, y - by);
556 pixCountPixels(pix3, &area, recog->
sumtab);
557 numaAddNumber(recog->
nasum_u, area);
569 return ERROR_INT(
"at least 1 bad class", __func__, 1);
577 L_ERROR(
"ratio of max/min height of average templates = %4.1f\n",
583 for (i = 0; i < size; i++) {
586 nsamp = pixaGetCount(pixa1);
587 nsamp = L_MIN(nsamp, 256);
589 pix2 = pixThresholdToBinary(pix1, L_MAX(1, nsamp / 2));
590 pixInvert(pix2, pix2);
591 pixClipToForeground(pix2, &pix3, &box);
593 L_ERROR(
"no fg pixels in average for class %d\n", __func__, i);
601 boxGetGeometry(box, &bx, &by, NULL, NULL);
603 ptaAddPt(recog->
pta, x - bx, y - by);
604 pixCountPixels(pix3, &area, recog->
sumtab);
605 numaAddNumber(recog->
nasum, area);
615 return ERROR_INT(
"no fg pixels in at least 1 class", __func__, 1);
658l_int32 i, n, maxw, maxh, xdiff, ydiff;
659l_int32 *centtab, *sumtab;
660l_float32 xc, yc, xave, yave;
661PIX *pix1, *pix2, *pixsum;
667 return ERROR_INT(
"&pixd not defined", __func__, 1);
670 return ERROR_INT(
"pixa not defined", __func__, 1);
672 n = pixaGetCount(pixa);
673 if (pta && ptaGetCount(pta) != n)
674 return ERROR_INT(
"pta count differs from pixa count", __func__, 1);
677 return ERROR_INT(
"pixa array empty", __func__, 1);
681 ptac = ptaClone(pta);
684 centtab = makePixelCentroidTab8();
685 sumtab = makePixelSumTab8();
686 for (i = 0; i < n; i++) {
687 pix1 = pixaGetPix(pixa, i,
L_CLONE);
688 pixCentroid(pix1, centtab, sumtab, &xc, &yc);
689 ptaAddPt(ptac, xc, yc);
697 for (i = 0; i < n; i++) {
698 ptaGetPt(pta, i, &xc, &yc);
702 xave = xave / (l_float32)n;
703 yave = yave / (l_float32)n;
711 pixaSizeRange(pixa, NULL, NULL, &maxw, &maxh);
712 pixsum = pixInitAccumulate(maxw + 5, maxh + 5, 0);
713 pix1 = pixCreate(maxw, maxh, 1);
714 for (i = 0; i < n; i++) {
715 pix2 = pixaGetPix(pixa, i,
L_CLONE);
716 ptaGetPt(ptac, i, &xc, &yc);
717 xdiff = (l_int32)(xave - xc);
718 ydiff = (l_int32)(yave - yc);
720 pixRasterop(pix1, xdiff, ydiff, maxw, maxh,
PIX_SRC,
722 pixAccumulate(pixsum, pix1, L_ARITH_ADD);
725 *ppixd = pixFinalAccumulate(pixsum, 0, 8);
774l_int32 ok, i, j, size, nc, ns, area;
784 return ERROR_INT(
"&recog not defined", __func__, 1);
785 if ((recog = *precog) == NULL)
786 return ERROR_INT(
"recog not defined", __func__, 1);
792 recogDestroy(precog);
793 return ERROR_INT(
"bad templates", __func__, 1);
798 paa = pixaaCreate(size);
799 pixa = pixaCreate(1);
800 pixaaInitFull(paa, pixa);
802 pixaaDestroy(&recog->
pixaa);
806 ptaa = ptaaCreate(size);
808 ptaaInitFull(ptaa, pta);
809 ptaaDestroy(&recog->
ptaa_u);
813 ptaa = ptaaCreate(size);
814 ptaaInitFull(ptaa, pta);
816 ptaaDestroy(&recog->
ptaa);
821 numaaDestroy(&recog->
naasum);
822 recog->
naasum_u = numaaCreateFull(size, 0);
823 recog->
naasum = numaaCreateFull(size, 0);
827 for (i = 0; i < nc; i++) {
828 pixa = pixaaGetPixa(paa, i,
L_CLONE);
829 ns = pixaGetCount(pixa);
830 for (j = 0; j < ns; j++) {
832 pix = pixaGetPix(pixa, j,
L_CLONE);
833 pixCentroid(pix, recog->
centtab, recog->
sumtab, &xave, &yave);
834 ptaaAddPt(recog->
ptaa_u, i, xave, yave);
835 pixCountPixels(pix, &area, recog->
sumtab);
836 numaaAddNumber(recog->
naasum_u, i, area);
843 pixd = pixClone(pix);
846 pixCentroid(pixd, recog->
centtab, recog->
sumtab, &xave, &yave);
847 ptaaAddPt(recog->
ptaa, i, xave, yave);
848 pixCountPixels(pixd, &area, recog->
sumtab);
849 numaaAddNumber(recog->
naasum, i, area);
851 L_ERROR(
"failed: modified template for class %d, sample %d\n",
861 pixaaTruncate(recog->
pixaa);
862 ptaaTruncate(recog->
ptaa_u);
863 ptaaTruncate(recog->
ptaa);
865 numaaTruncate(recog->
naasum);
897l_int32 i, n, validsets, nt;
902 return ERROR_INT(
"&ok not defined", __func__, 1);
905 return ERROR_INT(
"recog not defined", __func__, 1);
907 minsize = (minsize < 0) ? DefaultMinSetSize : minsize;
908 minfract = (minfract < 0) ? DefaultMinSetFract : minfract;
909 n = pixaaGetCount(recog->
pixaa_u, &na);
911 for (i = 0, validsets = 0; i < n; i++) {
912 numaGetIValue(na, i, &nt);
917 ratio = (l_float32)validsets / (l_float32)recog->
charset_size;
918 *pok = (ratio >= minfract) ? 1 : 0;
955 l_float32 max_ht_ratio,
958l_int32 i, j, h90, hj, j1, j2, j90, n, nc;
961PIXA *pixa1, *pixa2, *pixa3, *pixa4, *pixa5;
964 if (pna) *pna = NULL;
966 return (
PIXA *)ERROR_PTR(
"pixas not defined", __func__, NULL);
969 return (
PIXA *)ERROR_PTR(
"paa not made", __func__, NULL);
970 nc = pixaaGetCount(paa, NULL);
971 na = (pna) ? numaCreate(0) : NULL;
973 pixa5 = pixaCreate(0);
974 for (i = 0; i < nc; i++) {
975 pixa1 = pixaaGetPixa(paa, i,
L_CLONE);
976 if ((n = pixaGetCount(pixa1)) == 0) {
982 j90 = (l_int32)(0.9 * n);
983 pixaGetPixDimensions(pixa2, j90, NULL, &h90, NULL);
984 pixa3 = pixaCreate(n);
985 for (j = 0; j < n; j++) {
986 pixaGetPixDimensions(pixa2, j, NULL, &hj, NULL);
987 ratio = (l_float32)h90 / (l_float32)hj;
988 if (ratio <= max_ht_ratio)
991 n = pixaGetCount(pixa3);
993 pixa4 = pixaCopy(pixa3,
L_CLONE);
995 j1 = (n - maxkeep) / 2;
996 j2 = j1 + maxkeep - 1;
997 pixa4 = pixaSelectRange(pixa3, j1, j2,
L_CLONE);
999 if (na) numaAddNumber(na, pixaGetCount(pixa4));
1000 pixaJoin(pixa5, pixa4, 0, -1);
1001 pixaDestroy(&pixa1);
1002 pixaDestroy(&pixa2);
1003 pixaDestroy(&pixa3);
1004 pixaDestroy(&pixa4);
1028 return (
PIXAA *)ERROR_PTR(
"pixa not defined", __func__, NULL);
1030 if ((recog = recogCreateFromPixaNoFinish(pixa, 0, 0, 0, 0, 0)) == NULL)
1031 return (
PIXAA *)ERROR_PTR(
"recog not made", __func__, NULL);
1034 recogDestroy(&recog);
1070 return ERROR_INT(
"&recog not defined", __func__, 1);
1071 if (*precog == NULL)
1072 return ERROR_INT(
"recog not defined", __func__, 1);
1075 pixa1 = recogExtractPixa(*precog);
1076 recogDestroy(precog);
1080 pixaDestroy(&pixa1);
1082 return ERROR_INT(
"failure to remove outliers", __func__, 1);
1084 recog = recogCreateFromPixa(pixa2, 0, 0, 0, 150, 1);
1085 pixaDestroy(&pixa2);
1087 return ERROR_INT(
"failure to make recog from pixa sans outliers",
1142l_int32 i, j, debug, n, area1, area2;
1143l_float32 x1, y1, x2, y2, minfract, score, rankscore, threshscore;
1144NUMA *nasum, *narem, *nasave, *nascore;
1146PIXA *pixa, *pixarem, *pixad;
1150 if (ppixsave) *ppixsave = NULL;
1151 if (ppixrem) *ppixrem = NULL;
1153 return (
PIXA *)ERROR_PTR(
"pixas not defined", __func__, NULL);
1154 minscore = L_MIN(minscore, 1.0);
1155 if (minscore <= 0.0)
1156 minscore = DefaultMinScore;
1157 mintarget = L_MIN(mintarget, 3);
1159 mintarget = DefaultMinTarget;
1161 minsize = DefaultMinSetSize;
1164 debug = (ppixsave || ppixrem) ? 1 : 0;
1165 recog = recogCreateFromPixa(pixas, 0, 40, 0, 128, 1);
1167 return (
PIXA *)ERROR_PTR(
"bad pixas; recog not made", __func__, NULL);
1169 recogDestroy(&recog);
1170 return (
PIXA *)ERROR_PTR(
"bad templates", __func__, NULL);
1173 nasave = (ppixsave) ? numaCreate(0) : NULL;
1174 pixarem = (ppixrem) ? pixaCreate(0) : NULL;
1175 narem = (ppixrem) ? numaCreate(0) : NULL;
1177 pixad = pixaCreate(0);
1178 for (i = 0; i < recog->
setsize; i++) {
1182 ptaGetPt(recog->
pta, i, &x1, &y1);
1183 numaGetIValue(recog->
nasum, i, &area1);
1189 n = pixaGetCount(pixa);
1190 nascore = numaCreate(n);
1191 for (j = 0; j < n; j++) {
1192 pix2 = pixaGetPix(pixa, j,
L_CLONE);
1193 ptaGetPt(pta, j, &x2, &y2);
1194 numaGetIValue(nasum, j, &area2);
1195 pixCorrelationScoreSimple(pix1, pix2, area1, area2,
1196 x1 - x2, y1 - y2, 5, 5,
1198 numaAddNumber(nascore, score);
1199 if (debug && score == 0.0)
1200 lept_stderr(
"Got 0 score for i = %d, j = %d\n", i, j);
1210 minfract = (l_float32)mintarget / (l_float32)n;
1211 numaGetRankValue(nascore, 1.0 - minfract, NULL, 0, &rankscore);
1212 threshscore = L_MAX(LowerScoreThreshold,
1213 L_MIN(minscore, rankscore));
1215 L_INFO(
"minscore = %4.2f, rankscore = %4.2f, threshscore = %4.2f\n",
1216 __func__, minscore, rankscore, threshscore);
1221 for (j = 0; j < n; j++) {
1222 numaGetFValue(nascore, j, &score);
1224 if (score >= threshscore && n >= minsize) {
1226 if (nasave) numaAddNumber(nasave, score);
1228 pixaAddPix(pixarem, pix1,
L_INSERT);
1229 numaAddNumber(narem, score);
1237 numaDestroy(&nasum);
1238 numaDestroy(&nascore);
1243 numaDestroy(&nasave);
1247 pixaDestroy(&pixarem);
1248 numaDestroy(&narem);
1250 recogDestroy(&recog);
1284 return ERROR_INT(
"&recog not defined", __func__, 1);
1285 if (*precog == NULL)
1286 return ERROR_INT(
"recog not defined", __func__, 1);
1289 pixa1 = recogExtractPixa(*precog);
1290 recogDestroy(precog);
1293 pixaDestroy(&pixa1);
1295 return ERROR_INT(
"failure to remove outliers", __func__, 1);
1297 recog = recogCreateFromPixa(pixa2, 0, 0, 0, 150, 1);
1298 pixaDestroy(&pixa2);
1300 return ERROR_INT(
"failure to make recog from pixa sans outliers",
1342l_int32 i, j, k, n, area1, area2, maxk, debug;
1343l_float32 x1, y1, x2, y2, score, maxscore;
1344NUMA *nan, *nascore, *nasave;
1345PIX *pix1, *pix2, *pix3;
1346PIXA *pixarem, *pixad;
1349 if (ppixsave) *ppixsave = NULL;
1350 if (ppixrem) *ppixrem = NULL;
1352 return (
PIXA *)ERROR_PTR(
"pixas not defined", __func__, NULL);
1353 minscore = L_MIN(minscore, 1.0);
1354 if (minscore <= 0.0)
1355 minscore = DefaultMinScore;
1357 minsize = DefaultMinSetSize;
1360 debug = (ppixsave || ppixrem) ? 1 : 0;
1361 recog = recogCreateFromPixa(pixas, 0, 40, 0, 128, 1);
1363 return (
PIXA *)ERROR_PTR(
"bad pixas; recog not made", __func__, NULL);
1365 recogDestroy(&recog);
1366 return (
PIXA *)ERROR_PTR(
"bad templates", __func__, NULL);
1369 nasave = (ppixsave) ? numaCreate(0) : NULL;
1370 pixarem = (ppixrem) ? pixaCreate(0) : NULL;
1372 pixad = pixaCreate(0);
1373 pixaaGetCount(recog->
pixaa, &nan);
1374 for (i = 0; i < recog->
setsize; i++) {
1377 numaGetIValue(nan, i, &n);
1378 for (j = 0; j < n; j++) {
1380 ptaaGetPt(recog->
ptaa, i, j, &x1, &y1);
1381 numaaGetValue(recog->
naasum, i, j, NULL, &area1);
1382 nascore = numaCreate(n);
1383 for (k = 0; k < recog->
setsize; k++) {
1385 ptaGetPt(recog->
pta, k, &x2, &y2);
1386 numaGetIValue(recog->
nasum, k, &area2);
1387 pixCorrelationScoreSimple(pix1, pix2, area1, area2,
1388 x1 - x2, y1 - y2, 5, 5,
1390 numaAddNumber(nascore, score);
1397 numaGetMax(nascore, &maxscore, &maxk);
1398 if (maxk == i && maxscore >= minscore && n >= minsize) {
1402 if (nasave) numaAddNumber(nasave, maxscore);
1403 }
else if (ppixrem) {
1405 pixaAddPix(pixarem, pix3,
L_INSERT);
1407 numaDestroy(&nascore);
1414 numaDestroy(&nasave);
1417 *ppixrem = pixaDisplayTiledInRows(pixarem, 32, 1500, 1.0, 0, 20, 2);
1418 pixaDestroy(&pixarem);
1422 recogDestroy(&recog);
1467l_int32 i, n, same, maxd, scaleh, linew;
1469PIX *pix1, *pix2, *pixdb = NULL;
1470PIXA *pixa1, *pixa2, *pixa3, *pixad;
1473 return (
PIXA *)ERROR_PTR(
"recogboot not defined", __func__, NULL);
1475 return (
PIXA *)ERROR_PTR(
"pixas not defined", __func__, NULL);
1478 if ((n = pixaGetCount(pixas)) == 0)
1479 return (
PIXA *)ERROR_PTR(
"no pix in pixa", __func__, NULL);
1480 pixaVerifyDepth(pixas, &same, &maxd);
1482 pixa1 = pixaCopy(pixas,
L_COPY);
1484 pixa1 = pixaCreate(n);
1485 for (i = 0; i < n; i++) {
1486 pix1 = pixaGetPix(pixas, i,
L_CLONE);
1487 pix2 = pixConvertTo1(pix1, threshold);
1494 scaleh = recogboot->
scaleh;
1495 linew = recogboot->
linew;
1496 pixa2 = pixaCreate(n);
1497 for (i = 0; i < n; i++) {
1498 pix1 = pixaGetPix(pixa1, i,
L_CLONE);
1499 pix2 = pixScaleToSize(pix1, 0, scaleh);
1503 pixaDestroy(&pixa1);
1507 pixa3 = pixaSetStrokeWidth(pixa2, linew, 4, 8);
1509 pixa3 = pixaCopy(pixa2,
L_CLONE);
1510 pixaDestroy(&pixa2);
1513 n = pixaGetCount(pixa3);
1514 pixad = pixaCreate(n);
1515 for (i = 0; i < n; i++) {
1516 pix1 = pixaGetPix(pixa3, i,
L_COPY);
1517 pixSetText(pix1, NULL);
1519 recogIdentifyPix(recogboot, pix1, NULL);
1521 recogIdentifyPix(recogboot, pix1, &pixdb);
1524 rchExtract(recogboot->
rch, NULL, &score, &text, NULL, NULL, NULL, NULL);
1525 if (score >= minscore) {
1526 pix2 = pixaGetPix(pixas, i,
L_COPY);
1527 pixSetText(pix2, text);
1534 pixaDestroy(&pixa3);
1571 return ERROR_INT(
"&recog not defined", __func__, 1);
1581 return ERROR_INT(
"pixa not made", __func__, 1);
1585 L_WARNING(
"templates must be scaled to fixed height; using %d\n",
1592 recog2 = recogCreateFromPixa(pixa, 0, scaleh, linew, recog1->
threshold,
1595 recogDestroy(precog);
1622l_int32 i, nt, min_nopad, nclass, allclasses;
1628 return ERROR_INT(
"&sa not defined", __func__, 1);
1631 return ERROR_INT(
"recog not defined", __func__, 1);
1634 nclass = pixaaGetCount(recog->
pixaa_u, &naclass);
1639 numaGetMin(naclass, &minval, NULL);
1640 if (allclasses && (minval >= min_nopad)) {
1641 numaDestroy(&naclass);
1650 for (i = 0; i < nclass; i++) {
1651 numaGetIValue(naclass, i, &nt);
1652 if (nt < min_nopad) {
1654 sarrayAddString(sa, str,
L_INSERT);
1657 numaDestroy(&naclass);
1679l_int32 i, nclass, index, ival;
1684 return (
SARRAY *)ERROR_PTR(
"recog not defined", __func__, NULL);
1687 nclass = pixaaGetCount(recog->
pixaa_u, NULL);
1689 return sarrayCreate(0);
1693 sa = sarrayCreate(0);
1695 numaAddNumber(na, 1);
1696 for (i = 0; i < nclass; i++) {
1698 index = text[0] -
'0';
1699 numaSetValue(na, index, 0);
1703 for (i = 0; i < nclass; i++) {
1704 numaGetIValue(na, i, &ival);
1708 sarrayAddString(sa, str,
L_COPY);
1741 return (
PIXA *)ERROR_PTR(
"recog not defined", __func__, NULL);
1743 return (
PIXA *)ERROR_PTR(
"sa not defined", __func__, NULL);
1745 return (
PIXA *)ERROR_PTR(
"boot charset not available", __func__, NULL);
1749 n = pixaGetCount(pixa1);
1752 pixa2 = recogExtractPixa(recog);
1755 nt = sarrayGetCount(sa);
1756 for (i = 0; i < n; i++) {
1757 pix = pixaGetPix(pixa1, i,
L_CLONE);
1758 text = pixGetText(pix);
1759 for (j = 0; j < nt; j++) {
1760 str = sarrayGetString(sa, j,
L_NOCOPY);
1761 if (!strcmp(text, str)) {
1762 pixaAddPix(pixa2, pix,
L_COPY);
1769 pixaDestroy(&pixa1);
1794 L_INFO(
"charset type %d not available\n", __func__, type);
1798 L_INFO(
"charset type %d is unknown\n", __func__, type);
1855 recog = recogCreateFromPixa(pixa, 0, scaleh, linew, 128, maxyshift);
1881PIX *pix1, *pix2, *pix3;
1882PIXA *pixa1, *pixa2, *pixa3;
1885 pixa1 = l_bootnum_gen4(nsamp);
1887 pix1 = pixaDisplayTiledWithText(pixa1, 1500, 1.0, 10,
1889 pixDisplay(pix1, 0, 0);
1896 pixa1 = l_bootnum_gen1();
1897 pixa2 = l_bootnum_gen2();
1898 pixa3 = l_bootnum_gen3();
1900 pix1 = pixaDisplayTiledWithText(pixa1, 1500, 1.0, 10, 2, 6, 0xff000000);
1901 pix2 = pixaDisplayTiledWithText(pixa2, 1500, 1.0, 10, 2, 6, 0xff000000);
1902 pix3 = pixaDisplayTiledWithText(pixa3, 1500, 1.0, 10, 2, 6, 0xff000000);
1903 pixDisplay(pix1, 0, 0);
1904 pixDisplay(pix2, 600, 0);
1905 pixDisplay(pix3, 1200, 0);
1910 pixaJoin(pixa1, pixa2, 0, -1);
1911 pixaJoin(pixa1, pixa3, 0, -1);
1912 pixaDestroy(&pixa2);
1913 pixaDestroy(&pixa3);
1916 na1 = numaCreate(4);
1917 numaAddNumber(na1, 0.9f);
1918 numaAddNumber(na1, 1.1f);
1919 numaAddNumber(na1, 1.2f);
1920 pixa2 = pixaExtendByScaling(pixa1, na1, L_HORIZ, 1);
1922 pixaDestroy(&pixa1);
1947l_int32 i, val, count;
1952 return ERROR_INT(
"stream not defined", __func__, 1);
1954 return ERROR_INT(
"recog not defined", __func__, 1);
1956 fprintf(fp,
"Debug print of recog contents\n");
1957 fprintf(fp,
" Setsize: %d\n", recog->
setsize);
1958 fprintf(fp,
" Binarization threshold: %d\n", recog->
threshold);
1959 fprintf(fp,
" Maximum matching y-jiggle: %d\n", recog->
maxyshift);
1960 if (recog->
linew <= 0)
1961 fprintf(fp,
" Using image templates for matching\n");
1963 fprintf(fp,
" Using templates with fixed line width for matching\n");
1965 fprintf(fp,
" No width scaling of templates\n");
1967 fprintf(fp,
" Template width scaled to %d\n", recog->
scalew);
1969 fprintf(fp,
" No height scaling of templates\n");
1971 fprintf(fp,
" Template height scaled to %d\n", recog->
scaleh);
1972 fprintf(fp,
" Number of samples in each class:\n");
1973 pixaaGetCount(recog->
pixaa_u, &na);
1974 for (i = 0; i < recog->
setsize; i++) {
1976 numaGetIValue(na, i, &count);
1978 fprintf(fp,
" class %d, char %c: %d\n", i, val, count);
1980 fprintf(fp,
" class %d, val %d: %d\n", i, val, count);
1985 lept_mkdir(
"lept/recog");
1986 pix = pixaaDisplayByPixa(recog->
pixaa_u, 50, 1.0, 20, 20, 0);
1987 snprintf(buf,
sizeof(buf),
"/tmp/lept/recog/templates_u.%d.png", index);
1988 pixWriteDebug(buf, pix, IFF_PNG);
1989 pixDisplay(pix, 0, 200 * index);
1992 pix = pixaaDisplayByPixa(recog->
pixaa, 50, 1.0, 20, 20, 0);
1993 snprintf(buf,
sizeof(buf),
1994 "/tmp/lept/recog/templates.%d.png", index);
1995 pixWriteDebug(buf, pix, IFF_PNG);
1996 pixDisplay(pix, 800, 200 * index);
2025l_int32 i, j, n, np, index;
2027PIX *pix1, *pix2, *pix3;
2032 return ERROR_INT(
"recog not defined", __func__, 1);
2037 return ERROR_INT(
"averaging failed", __func__, 1);
2040 paa1 = recog->
pixaa;
2047 n = pixaaGetCount(paa1, NULL);
2048 paa2 = pixaaCreate(n);
2049 for (i = 0; i < n; i++) {
2050 pixa = pixaCreate(0);
2051 pixat = pixaaGetPixa(paa1, i,
L_CLONE);
2052 np = pixaGetCount(pixat);
2053 for (j = 0; j < np; j++) {
2054 pix1 = pixaaGetPix(paa1, i, j,
L_CLONE);
2055 recogIdentifyPix(recog, pix1, &pix2);
2056 rchExtract(recog->
rch, &index, &score, NULL, NULL, NULL,
2059 lept_stderr(
"index = %d, score = %7.3f\n", index, score);
2060 pix3 = pixAddBorder(pix2, 2, 1);
2065 pixaaAddPixa(paa2, pixa,
L_INSERT);
2066 pixaDestroy(&pixat);
2068 recog->
pixdb_ave = pixaaDisplayByPixa(paa2, 50, 1.0, 20, 20, 0);
2070 lept_mkdir(
"lept/recog");
2071 pixWriteDebug(
"/tmp/lept/recog/templ_match.png", recog->
pixdb_ave,
2076 pixaaDestroy(&paa2);
2098PIX *pix1, *pix2, *pixr;
2099PIXA *pixat, *pixadb;
2102 return ERROR_INT(
"recog not defined", __func__, 1);
2104 lept_stderr(
"min/max width_u = (%d,%d); min/max height_u = (%d,%d)\n",
2107 lept_stderr(
"min splitw = %d, max splith = %d\n",
2112 pixr = pixCreate(3, 3, 32);
2113 pixSetAllArbitrary(pixr, 0xff000000);
2114 pixadb = pixaCreate(2);
2118 pixat = pixaCreate(size);
2119 for (i = 0; i < size; i++) {
2122 pix2 = pixConvertTo32(pix1);
2123 ptaGetPt(recog->
pta_u, i, &x, &y);
2124 pixRasterop(pix2, (l_int32)(x - 0.5), (l_int32)(y - 0.5), 3, 3,
2129 pix1 = pixaDisplayTiledInRows(pixat, 32, 3000, 1.0, 0, 20, 0);
2130 pixaAddPix(pixadb, pix1,
L_INSERT);
2131 pixDisplay(pix1, 100, 100);
2132 pixaDestroy(&pixat);
2135 pixat = pixaCreate(size);
2136 for (i = 0; i < size; i++) {
2137 if ((pix1 = pixaGetPix(recog->
pixa, i,
L_CLONE)) == NULL)
2139 pix2 = pixConvertTo32(pix1);
2140 ptaGetPt(recog->
pta, i, &x, &y);
2141 pixRasterop(pix2, (l_int32)(x - 0.5), (l_int32)(y - 0.5), 3, 3,
2146 pix1 = pixaDisplayTiledInRows(pixat, 32, 3000, 1.0, 0, 20, 0);
2147 pixaAddPix(pixadb, pix1,
L_INSERT);
2148 pixDisplay(pix1, 100, 100);
2149 pixaDestroy(&pixat);
2181 return (
PIX *)ERROR_PTR(
"pixas not defined", __func__, NULL);
2183 return (
PIX *)ERROR_PTR(
"nas not defined", __func__, NULL);
2184 n = pixaGetCount(pixas);
2185 if (numaGetCount(nas) != n)
2186 return (
PIX *)ERROR_PTR(
"pixas and nas sizes differ", __func__, NULL);
2188 pixa1 = pixaCreate(n);
2189 for (i = 0; i < n; i++) {
2190 pix1 = pixaGetPix(pixas, i,
L_CLONE);
2192 text = pixGetText(pix1);
2193 numaGetFValue(nas, i, &fval);
2194 snprintf(buf,
sizeof(buf),
"'%s': %5.2f", text, fval);
2195 pixSetText(pix2, buf);
2199 pix1 = pixaDisplayTiledWithText(pixa1, 1500, 1.0, 20, 2, 6, 0xff000000);
2200 pixaDestroy(&pixa1);
2231PIX *pix1, *pix2, *pix3, *pix4, *pix5;
2235 return (
PIX *)ERROR_PTR(
"recog not defined", __func__, NULL);
2237 pix1 = pixaaGetPix(recog->
pixaa, iclass, jsamp,
L_CLONE);
2239 pix3 = pixaGetPix(recog->
pixa, maxclass,
L_CLONE);
2240 pixa = pixaCreate(3);
2244 pix4 = pixaDisplayTiledInRows(pixa, 32, 400, 2.0, 0, 12, 2);
2245 snprintf(buf,
sizeof(buf),
"C=%d, BAC=%d, S=%4.2f", iclass, maxclass,
2247 pix5 = pixAddSingleTextblock(pix4, recog->
bmf, buf, 0xff000000,
2283l_int32 i, n, index, depth;
2285NUMA *nascore, *naindex;
2290 return ERROR_INT(
"recog not defined", __func__, 1);
2292 return ERROR_INT(
"pixa not defined", __func__, 1);
2295 n = pixaGetCount(pixa);
2296 nascore = numaCreate(n);
2297 naindex = numaCreate(n);
2298 pixa1 = pixaCreate(n);
2299 for (i = 0; i < n; i++) {
2300 pix1 = pixaGetPix(pixa, i,
L_CLONE);
2301 recogIdentifyPix(recog, pix1, &pix2);
2302 rchExtract(recog->
rch, &index, &score, NULL, NULL, NULL, NULL, NULL);
2303 numaAddNumber(nascore, score);
2304 numaAddNumber(naindex, index);
2310 pixa2 = pixaCreate(n);
2312 for (i = 0; i < n; i++) {
2313 numaGetFValue(nascore, i, &score);
2314 if (score < minscore || score > maxscore)
continue;
2315 pix1 = pixaGetPix(pixa1, i,
L_CLONE);
2316 numaGetIValue(naindex, i, &index);
2318 if (i == 0) depth = pixGetDepth(pix2);
2325 if (pixaGetCount(pixa2) > 0) {
2327 pixaDisplayTiledInRows(pixa2, depth, 2500, 1.0, 0, 20, 1);
2331 L_INFO(
"no character matches in the range of scores\n", __func__);
2334 pixaDestroy(&pixa1);
2335 pixaDestroy(&pixa2);
2336 numaDestroy(&nascore);
2337 numaDestroy(&naindex);
2379PIX *pix3, *pix4, *pix5, *pixd;
2383 return (
PIX *)ERROR_PTR(
"recog not defined", __func__, NULL);
2385 return (
PIX *)ERROR_PTR(
"pix1 not defined", __func__, NULL);
2387 bmf = (recog->
bmf && index >= 0) ? recog->
bmf : NULL;
2388 if (!pix2 && !box && !bmf)
2389 return pixCopy(NULL, pix1);
2391 pix3 = pixConvertTo32(pix1);
2393 pixRenderBoxArb(pix3, box, 1, 255, 0, 0);
2396 pixa = pixaCreate(2);
2397 pixaAddPix(pixa, pix3,
L_CLONE);
2398 pixaAddPix(pixa, pix2,
L_CLONE);
2399 pix4 = pixaDisplayTiledInRows(pixa, 1, 500, 1.0, 0, 15, 0);
2402 pix4 = pixCopy(NULL, pix3);
2407 pix5 = pixAddBorderGeneral(pix4, 55, 55, 0, 0, 0xffffff00);
2408 recogGetClassString(recog, index, &text);
2409 snprintf(buf,
sizeof(buf),
"C=%s, S=%4.3f, I=%d", text, score, index);
2410 pixd = pixAddSingleTextblock(pix5, bmf, buf, 0xff000000,
2415 pixd = pixClone(pix4);
l_ok recogProcessLabeled(L_RECOG *recog, PIX *pixs, BOX *box, char *text, PIX **ppix)
recogProcessLabeled()
l_int32 recogIsPaddingNeeded(L_RECOG *recog, SARRAY **psa)
recogIsPaddingNeeded()
l_ok recogPadDigitTrainingSet(L_RECOG **precog, l_int32 scaleh, l_int32 linew)
recogPadDigitTrainingSet()
l_int32 recogShowAverageTemplates(L_RECOG *recog)
recogShowAverageTemplates()
l_int32 pixaAccumulateSamples(PIXA *pixa, PTA *pta, PIX **ppixd, l_float32 *px, l_float32 *py)
pixaAccumulateSamples()
l_ok recogShowMatchesInRange(L_RECOG *recog, PIXA *pixa, l_float32 minscore, l_float32 maxscore, l_int32 display)
recogShowMatchesInRange()
static PIX * pixDisplayOutliers(PIXA *pixas, NUMA *nas)
pixDisplayOutliers()
PIX * recogShowMatch(L_RECOG *recog, PIX *pix1, PIX *pix2, BOX *box, l_int32 index, l_float32 score)
recogShowMatch()
l_ok recogTrainingFinished(L_RECOG **precog, l_int32 modifyflag, l_int32 minsize, l_float32 minfract)
recogTrainingFinished()
PIX * recogModifyTemplate(L_RECOG *recog, PIX *pixs)
recogModifyTemplate()
PIXA * recogFilterPixaBySize(PIXA *pixas, l_int32 setsize, l_int32 maxkeep, l_float32 max_ht_ratio, NUMA **pna)
recogFilterPixaBySize()
PIXA * pixaRemoveOutliers2(PIXA *pixas, l_float32 minscore, l_int32 minsize, PIX **ppixsave, PIX **ppixrem)
pixaRemoveOutliers2()
l_ok recogTrainLabeled(L_RECOG *recog, PIX *pixs, BOX *box, char *text, l_int32 debug)
recogTrainLabeled()
l_ok recogRemoveOutliers1(L_RECOG **precog, l_float32 minscore, l_int32 mintarget, l_int32 minsize, PIX **ppixsave, PIX **ppixrem)
recogRemoveOutliers1()
L_RECOG * recogMakeBootDigitRecog(l_int32 nsamp, l_int32 scaleh, l_int32 linew, l_int32 maxyshift, l_int32 debug)
recogMakeBootDigitRecog()
static PIX * recogDisplayOutlier(L_RECOG *recog, l_int32 iclass, l_int32 jsamp, l_int32 maxclass, l_float32 maxscore)
recogDisplayOutlier()
l_int32 recogAverageSamples(L_RECOG *recog, l_int32 debug)
recogAverageSamples()
l_ok recogRemoveOutliers2(L_RECOG **precog, l_float32 minscore, l_int32 minsize, PIX **ppixsave, PIX **ppixrem)
recogRemoveOutliers2()
l_ok recogShowContent(FILE *fp, L_RECOG *recog, l_int32 index, l_int32 display)
recogShowContent()
l_ok recogAddSample(L_RECOG *recog, PIX *pix, l_int32 debug)
recogAddSample()
static l_int32 recogTemplatesAreOK(L_RECOG *recog, l_int32 minsize, l_float32 minfract, l_int32 *pok)
recogTemplatesAreOK()
static SARRAY * recogAddMissingClassStrings(L_RECOG *recog)
recogAddMissingClassStrings()
static l_int32 recogCharsetAvailable(l_int32 type)
recogCharsetAvailable()
PIXA * recogAddDigitPadTemplates(L_RECOG *recog, SARRAY *sa)
recogAddDigitPadTemplates()
PIXA * recogTrainFromBoot(L_RECOG *recogboot, PIXA *pixas, l_float32 minscore, l_int32 threshold, l_int32 debug)
recogTrainFromBoot()
PIXAA * recogSortPixaByClass(PIXA *pixa, l_int32 setsize)
recogSortPixaByClass()
PIXA * recogMakeBootDigitTemplates(l_int32 nsamp, l_int32 debug)
recogMakeBootDigitTemplates()
l_ok recogDebugAverages(L_RECOG *recog, l_int32 debug)
recogDebugAverages()
PIXA * pixaRemoveOutliers1(PIXA *pixas, l_float32 minscore, l_int32 mintarget, l_int32 minsize, PIX **ppixsave, PIX **ppixrem)
pixaRemoveOutliers1()
struct L_Dna * dna_tochar
struct Pixa * pixadb_boot