summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'leptonica/prog/dewarprules.c')
-rw-r--r--leptonica/prog/dewarprules.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/leptonica/prog/dewarprules.c b/leptonica/prog/dewarprules.c
new file mode 100644
index 00000000..3eab1e1f
--- /dev/null
+++ b/leptonica/prog/dewarprules.c
@@ -0,0 +1,176 @@
+/*====================================================================*
+ - 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.
+ *====================================================================*/
+
+/*
+ * dewarprules.c
+ *
+ * Syntax: dewarprules select ndew
+ * where select = 0 (sudoku), 1 (graph paper)
+ * ndew = 1 (simple) or 2 (twice with rotations)
+ *
+ * There are two ways to dewarp the images:
+ * (1) use dewarpBuildLineModel() to correct both vertical and
+ * horizontal disparity with 1 dew
+ * (2) use dewarpBuildPageModel() twice, correcting only for
+ * vertical disparity, with 90 degree rotations in between
+ * and at the end.
+ *
+ * A challenge was presented in:
+ * http://stackoverflow.com/questions/10196198/how-to-remove-convexity-defects-in-sudoku-square/10226971#10226971
+ *
+ * Solutions were given there using mathematica and opencv.
+ */
+
+#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)
+{
+l_int32 w, h, select, ndew;
+BOXA *boxa1;
+L_DEWARP *dew;
+L_DEWARPA *dewa;
+PIX *pixs, *pixd, *pix1, *pix2, *pix3, *pix4, *pix5, *pix6, *pix7;
+PIX *pix8, *pix9, *pix10;
+PIXA *pixa1, *pixa2;
+
+ if (argc != 3) {
+ lept_stderr(" Syntax: dewarprules select ndew\n");
+ return 1;
+ }
+ select = atoi(argv[1]);
+ ndew = atoi(argv[2]);
+
+ setLeptDebugOK(1);
+ lept_mkdir("dewarp");
+
+ if (select == 0) {
+ /* Extract the basic grid from the sudoku image */
+ pixs = pixRead("warped_sudoku.jpg");
+ pixGetDimensions(pixs, &w, &h, NULL);
+ pix1 = pixConvertTo1(pixs, 220);
+ boxa1 = pixConnComp(pix1, &pixa1, 8);
+ pixa2 = pixaSelectBySize(pixa1, 400, 400, L_SELECT_IF_BOTH,
+ L_SELECT_IF_GT, NULL);
+ pix2 = pixaDisplay(pixa2, w, h); /* grid */
+ pixDisplay(pix1, 600, 300);
+ pixDisplay(pix2, 100, 100);
+ } else { /* select == 1 */
+ /* Extract the grid from the graph paper image */
+ pixs = pixRead("warped_paper.jpg");
+ pixDisplay(pixs, 1500, 1000);
+ pix3 = pixConvertTo8(pixs, 0);
+ pix4 = pixBackgroundNormSimple(pix3, NULL, NULL);
+ pix5 = pixGammaTRC(NULL, pix4, 1.0, 50, 200);
+ pix1 = pixConvertTo1(pix5, 220);
+ pixGetDimensions(pix1, &w, &h, NULL);
+ boxa1 = pixConnComp(pix1, &pixa1, 8);
+ pixa2 = pixaSelectBySize(pixa1, 400, 400, L_SELECT_IF_BOTH,
+ L_SELECT_IF_GT, NULL);
+ pix2 = pixaDisplay(pixa2, w, h); /* grid */
+ pixDisplay(pix1, 600, 300);
+ pixDisplay(pix2, 600, 400);
+ pixDestroy(&pix3);
+ pixDestroy(&pix4);
+ pixDestroy(&pix5);
+ }
+
+ if (ndew == 1) {
+ /* -------------------------------------------------------------------*
+ * Use dewarpBuildLineModel() to correct using both horizontal
+ * and vertical lines with one dew.
+ * -------------------------------------------------------------------*/
+ dewa = dewarpaCreate(1, 30, 1, 4, 50);
+ dewarpaSetCurvatures(dewa, 500, 0, 500, 100, 100, 200);
+ dewarpaUseBothArrays(dewa, 1);
+ dew = dewarpCreate(pix2, 0);
+ dewarpaInsertDewarp(dewa, dew);
+ dewarpBuildLineModel(dew, 10, "/tmp/dewarp/sud.pdf");
+ dewarpaApplyDisparity(dewa, 0, pix1, 255, 0, 0, &pix3, NULL);
+ dewarpaApplyDisparity(dewa, 0, pix2, 255, 0, 0, &pix4, NULL);
+ pixDisplay(pix3, 500, 100);
+ pixDisplay(pix4, 600, 100);
+ pixDestroy(&pix3);
+ pixDestroy(&pix4);
+ dewarpaDestroy(&dewa);
+ } else {
+ /* -------------------------------------------------------------------*
+ * Hack: use dewarpBuildPageModel() twice, first straightening
+ * the horizontal lines, then rotating the result by 90 degrees
+ * and doing it again, and finally rotating back by -90 degrees.
+ * -------------------------------------------------------------------*/
+ /* Extract the horizontal lines */
+ pix3 = pixMorphSequence(pix2, "d1.3 + c6.1 + o8.1", 0);
+ pixDisplay(pix3, 600, 100);
+
+ /* Correct for vertical disparity */
+ dewa = dewarpaCreate(1, 30, 1, 4, 50);
+ dewarpaSetCurvatures(dewa, 500, 0, 500, 100, 100, 200);
+ dewarpaUseBothArrays(dewa, 0);
+ dew = dewarpCreate(pix3, 0);
+ dewarpaInsertDewarp(dewa, dew);
+ dewarpBuildPageModel(dew, "/tmp/dewarp/sud1.pdf");
+ dewarpaApplyDisparity(dewa, 0, pix1, 255, 0, 0, &pix4, NULL);
+ dewarpaApplyDisparity(dewa, 0, pix2, 255, 0, 0, &pix5, NULL);
+ pixDisplay(pix4, 500, 100);
+ pixDisplay(pix5, 600, 100);
+ dewarpaDestroy(&dewa);
+
+ /* Rotate result 90 degrees */
+ pix6 = pixRotateOrth(pix4, 1);
+ pix7 = pixRotateOrth(pix5, 1); /* grid: vertical lines now are horiz */
+
+ /* Extract the vertical lines (which are now horizontal) */
+ pix8 = pixMorphSequence(pix7, "d1.3 + c6.1 + o8.1", 0);
+ pixDisplay(pix8, 600, 500);
+
+ /* Correct for vertical (now horizontal) disparity */
+ dewa = dewarpaCreate(1, 30, 1, 4, 50);
+ dewarpaSetCurvatures(dewa, 500, 0, 500, 100, 100, 200);
+ dewarpaUseBothArrays(dewa, 0);
+ dew = dewarpCreate(pix8, 0);
+ dewarpaInsertDewarp(dewa, dew);
+ dewarpBuildPageModel(dew, "/tmp/dewarp/sud2.pdf");
+ dewarpaApplyDisparity(dewa, 0, pix6, 255, 0, 0, &pix9, NULL);
+ dewarpaApplyDisparity(dewa, 0, pix8, 255, 0, 0, &pix10, NULL);
+ pixd = pixRotateOrth(pix9, 3);
+ pixDisplay(pix10, 600, 300);
+ pixDisplay(pixd, 600, 700);
+ }
+
+ pixDestroy(&pixs);
+ pixDestroy(&pix1);
+ pixDestroy(&pix2);
+ boxaDestroy(&boxa1);
+ pixaDestroy(&pixa1);
+ pixaDestroy(&pixa2);
+ return 0;
+}