summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'leptonica/prog/recogtest3.c')
-rw-r--r--leptonica/prog/recogtest3.c182
1 files changed, 182 insertions, 0 deletions
diff --git a/leptonica/prog/recogtest3.c b/leptonica/prog/recogtest3.c
new file mode 100644
index 00000000..c54be397
--- /dev/null
+++ b/leptonica/prog/recogtest3.c
@@ -0,0 +1,182 @@
+/*====================================================================*
+ - Copyright (C) 2001 Leptonica. All rights reserved.
+ -
+ - Redistribution and use in source and binary forms, with or without
+ - modification, are permitted provided that the following conditions
+ - are met:
+ - 1. Redistributions of source code must retain the above copyright
+ - notice, this list of conditions and the following disclaimer.
+ - 2. Redistributions in binary form must reproduce the above
+ - copyright notice, this list of conditions and the following
+ - disclaimer in the documentation and/or other materials
+ - provided with the distribution.
+ -
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
+ - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *====================================================================*/
+
+/*
+ * recogtest3.c
+ *
+ * Test padding of book-adapted recognizer (BAR) using templates
+ * from a bootstrap recognizer (BSR) to identify unlabeled samples
+ * from the book.
+ *
+ * Terminology note:
+ * templates: labeled character images that can be inserted
+ * into a recognizer.
+ * samples: unlabeled character images that must be labeled by
+ * a recognizer before they can be used as templates.
+ *
+ * This demonstrates the following operations:
+ * (1) Making a BAR from labeled book templates (as a pixa).
+ * (2) Making a hybrid BAR/BSR from scaled templates in the BAR,
+ * supplemented with similarly scaled bootstrap templates for those
+ * classes where the BAR templates are either missing or not
+ * of sufficient quantity.
+ * (3) Using the BAR/BSR to label unlabeled book sampless.
+ * (4) Adding the pixa of the original set of labeled book
+ * templates to the pixa of the newly labeled templates, and
+ * making a BAR from the joined pixa. The BAR would then
+ * work to identify unscaled samples from the book.
+ * (5) Removing outliers from the BAR.
+ *
+ * Note that if this final BAR were not to have a sufficient number
+ * of templates in each class, it can again be augmented with BSR
+ * templates, and the hybrid BAR/BSR would be the final recognizer
+ * that is used to identify unknown (scaled) samples.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config_auto.h>
+#endif /* HAVE_CONFIG_H */
+
+#include "string.h"
+#include "allheaders.h"
+
+
+l_int32 main(int argc,
+ char **argv)
+{
+char *text;
+l_int32 histo[10];
+l_int32 i, n, ival, same;
+PIX *pix1, *pix2;
+PIXA *pixa1, *pixa2, *pixa3, *pixa4;
+L_RECOG *recog1, *recog2, *recog3;
+
+ if (argc != 1) {
+ lept_stderr(" Syntax: recogtest3\n");
+ return 1;
+ }
+
+ setLeptDebugOK(1);
+ lept_mkdir("lept/recog");
+
+ /* Read templates and split them into two sets. Use one to
+ * make a BAR recog that needs padding; use the other with a
+ * hybrid BAR/BSR to make more labeled templates to augment
+ * the BAR */
+ pixa1 = pixaRead("recog/sets/train05.pa");
+ pixa2 = pixaCreate(0); /* to generate a small BAR */
+ pixa3 = pixaCreate(0); /* for templates to be labeled and
+ * added to the BAR */
+ n = pixaGetCount(pixa1);
+ for (i = 0; i < 10; i++)
+ histo[i] = 0;
+ for (i = 0; i < n; i++) {
+ pix1 = pixaGetPix(pixa1, i, L_COPY);
+ text = pixGetText(pix1);
+ ival = text[0] - '0';
+ /* remove all 4's, and all but 2 7's and 9's */
+ if (ival == 4 || (ival == 7 && histo[7] == 2) ||
+ (ival == 9 && histo[9] == 2)) {
+ pixaAddPix(pixa3, pix1, L_INSERT);
+ } else {
+ pixaAddPix(pixa2, pix1, L_INSERT);
+ histo[ival]++;
+ }
+ }
+ pix1 = pixaDisplayTiledWithText(pixa3, 1500, 1.0, 15, 2, 6, 0xff000000);
+ pixDisplay(pix1, 500, 0);
+ pixDestroy(&pix1);
+
+ /* Make a BAR from the small set */
+ recog1 = recogCreateFromPixa(pixa2, 0, 40, 0, 128, 1);
+ recogShowContent(stderr, recog1, 0, 1);
+
+ /* Pad with BSR templates to make a hybrid BAR/BSR */
+ recogPadDigitTrainingSet(&recog1, 40, 0);
+ recogShowContent(stderr, recog1, 1, 1);
+
+ /* Use the BAR/BSR to label the left-over templates from the book */
+ pixa4 = recogTrainFromBoot(recog1, pixa3, 0.75, 128, 1);
+
+ /* Join the two sets */
+ pixaJoin(pixa1, pixa4, 0, 0);
+ pixaDestroy(&pixa4);
+
+ /* Make a new BAR that uses unscaled templates.
+ * This now has all the templates from pixa1, before deletions */
+ recog2 = recogCreateFromPixa(pixa1, 0, 0, 5, 128, 1);
+ recogShowContent(stderr, recog2, 2, 1);
+
+ /* Test recog serialization */
+ recogWrite("/tmp/lept/recog/recog2.rec", recog2);
+ recog3 = recogRead("/tmp/lept/recog/recog2.rec");
+ recogWrite("/tmp/lept/recog/recog3.rec", recog3);
+ filesAreIdentical("/tmp/lept/recog/recog2.rec",
+ "/tmp/lept/recog/recog3.rec", &same);
+ if (!same)
+ lept_stderr("Error in serialization!\n");
+ recogDestroy(&recog3);
+
+ /* Remove outliers: method 1 */
+ pixa4 = pixaRemoveOutliers1(pixa1, 0.8, 4, 3, &pix1, &pix2);
+ pixDisplay(pix1, 500, 0);
+ pixDisplay(pix2, 500, 500);
+ pixDestroy(&pix1);
+ pixDestroy(&pix2);
+ recog3 = recogCreateFromPixa(pixa4, 0, 0, 0, 128, 1);
+ recogShowContent(stderr, recog3, 3, 1);
+ pixaDestroy(&pixa4);
+ recogDestroy(&recog3);
+
+ /* Relabel a few templates to put them in the wrong classes */
+ pix1 = pixaGetPix(pixa1, 7, L_CLONE);
+ pixSetText(pix1, "4");
+ pixDestroy(&pix1);
+ pix1 = pixaGetPix(pixa1, 38, L_CLONE);
+ pixSetText(pix1, "9");
+ pixDestroy(&pix1);
+ pix1 = pixaGetPix(pixa1, 61, L_CLONE);
+ pixSetText(pix1, "2");
+ pixDestroy(&pix1);
+
+ /* Remove outliers: method 2 */
+ pixa4 = pixaRemoveOutliers2(pixa1, 0.65, 3, &pix1, &pix2);
+ pixDisplay(pix1, 900, 0);
+ pixDisplay(pix2, 900, 500);
+ pixDestroy(&pix1);
+ pixDestroy(&pix2);
+ recog3 = recogCreateFromPixa(pixa4, 0, 0, 0, 128, 1);
+ recogShowContent(stderr, recog3, 3, 1);
+ pixaDestroy(&pixa4);
+ recogDestroy(&recog3);
+
+ recogDestroy(&recog1);
+ recogDestroy(&recog2);
+ pixaDestroy(&pixa1);
+ pixaDestroy(&pixa2);
+ pixaDestroy(&pixa3);
+ return 0;
+}