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 
27 /*
28  *   dewarptest3.c
29  *
30  *   This exercise functions in dewarp.c for dewarping based on lines
31  *   of horizontal text, showing results for different interpolations
32  *   (quadratic, cubic, quartic).
33  *
34  *   Inspection of the output pdf shows that using LS fitting beyond
35  *   quadratic has a tendency to overfit.  So we choose to use
36  *   quadratic LSF for the textlines.
37  */
38 
39 #include "allheaders.h"
40 
main(int argc,char ** argv)41 l_int32 main(int    argc,
42              char **argv)
43 {
44 l_int32     i, n;
45 l_float32   a, b, c, d, e;
46 NUMA       *nax, *nafit;
47 PIX        *pixs, *pixn, *pixg, *pixb, *pixt1, *pixt2;
48 PIXA       *pixa;
49 PTA        *pta, *ptad;
50 PTAA       *ptaa1, *ptaa2;
51 
52     setLeptDebugOK(1);
53     lept_mkdir("lept");
54 
55     pixs = pixRead("cat.035.jpg");
56 /*    pixs = pixRead("zanotti-78.jpg"); */
57 
58         /* Normalize for varying background and binarize */
59     pixn = pixBackgroundNormSimple(pixs, NULL, NULL);
60     pixg = pixConvertRGBToGray(pixn, 0.5, 0.3, 0.2);
61     pixb = pixThresholdToBinary(pixg, 130);
62     pixDestroy(&pixn);
63     pixDestroy(&pixg);
64 
65         /* Get the textline centers */
66     pixa = pixaCreate(6);
67     ptaa1 = dewarpGetTextlineCenters(pixb, 0);
68     pixt1 = pixCreateTemplate(pixs);
69     pixSetAll(pixt1);
70     pixt2 = pixDisplayPtaa(pixt1, ptaa1);
71     pixWrite("/tmp/lept/textline1.png", pixt2, IFF_PNG);
72     pixDisplayWithTitle(pixt2, 0, 100, "textline centers 1", 1);
73     pixaAddPix(pixa, pixt2, L_INSERT);
74     pixDestroy(&pixt1);
75 
76         /* Remove short lines */
77     fprintf(stderr, "Num all lines = %d\n", ptaaGetCount(ptaa1));
78     ptaa2 = dewarpRemoveShortLines(pixb, ptaa1, 0.8, 0);
79     pixt1 = pixCreateTemplate(pixs);
80     pixSetAll(pixt1);
81     pixt2 = pixDisplayPtaa(pixt1, ptaa2);
82     pixWrite("/tmp/lept/textline2.png", pixt2, IFF_PNG);
83     pixDisplayWithTitle(pixt2, 300, 100, "textline centers 2", 1);
84     pixaAddPix(pixa, pixt2, L_INSERT);
85     pixDestroy(&pixt1);
86     n = ptaaGetCount(ptaa2);
87     fprintf(stderr, "Num long lines = %d\n", n);
88     ptaaDestroy(&ptaa1);
89     pixDestroy(&pixb);
90 
91         /* Long lines over input image */
92     pixt1 = pixCopy(NULL, pixs);
93     pixt2 = pixDisplayPtaa(pixt1, ptaa2);
94     pixWrite("/tmp/lept/textline3.png", pixt2, IFF_PNG);
95     pixDisplayWithTitle(pixt2, 600, 100, "textline centers 3", 1);
96     pixaAddPix(pixa, pixt2, L_INSERT);
97     pixDestroy(&pixt1);
98 
99         /* Quadratic fit to curve */
100     pixt1 = pixCopy(NULL, pixs);
101     for (i = 0; i < n; i++) {
102         pta = ptaaGetPta(ptaa2, i, L_CLONE);
103         ptaGetArrays(pta, &nax, NULL);
104         ptaGetQuadraticLSF(pta, &a, &b, &c, &nafit);
105         fprintf(stderr, "Quadratic: a = %10.6f, b = %7.3f, c = %7.3f\n",
106                 a, b, c);
107         ptad = ptaCreateFromNuma(nax, nafit);
108         pixDisplayPta(pixt1, pixt1, ptad);
109         ptaDestroy(&pta);
110         ptaDestroy(&ptad);
111         numaDestroy(&nax);
112         numaDestroy(&nafit);
113     }
114     pixWrite("/tmp/lept/textline4.png", pixt1, IFF_PNG);
115     pixDisplayWithTitle(pixt1, 900, 100, "textline centers 4", 1);
116     pixaAddPix(pixa, pixt1, L_INSERT);
117 
118         /* Cubic fit to curve */
119     pixt1 = pixCopy(NULL, pixs);
120     for (i = 0; i < n; i++) {
121         pta = ptaaGetPta(ptaa2, i, L_CLONE);
122         ptaGetArrays(pta, &nax, NULL);
123         ptaGetCubicLSF(pta, &a, &b, &c, &d, &nafit);
124         fprintf(stderr, "Cubic: a = %10.6f, b = %10.6f, c = %7.3f, d = %7.3f\n",
125                 a, b, c, d);
126         ptad = ptaCreateFromNuma(nax, nafit);
127         pixDisplayPta(pixt1, pixt1, ptad);
128         ptaDestroy(&pta);
129         ptaDestroy(&ptad);
130         numaDestroy(&nax);
131         numaDestroy(&nafit);
132     }
133     pixWrite("/tmp/lept/textline5.png", pixt1, IFF_PNG);
134     pixDisplayWithTitle(pixt1, 1200, 100, "textline centers 5", 1);
135     pixaAddPix(pixa, pixt1, L_INSERT);
136 
137         /* Quartic fit to curve */
138     pixt1 = pixCopy(NULL, pixs);
139     for (i = 0; i < n; i++) {
140         pta = ptaaGetPta(ptaa2, i, L_CLONE);
141         ptaGetArrays(pta, &nax, NULL);
142         ptaGetQuarticLSF(pta, &a, &b, &c, &d, &e, &nafit);
143         fprintf(stderr,
144             "Quartic: a = %7.3f, b = %7.3f, c = %9.5f, d = %7.3f, e = %7.3f\n",
145             a, b, c, d, e);
146         ptad = ptaCreateFromNuma(nax, nafit);
147         pixDisplayPta(pixt1, pixt1, ptad);
148         ptaDestroy(&pta);
149         ptaDestroy(&ptad);
150         numaDestroy(&nax);
151         numaDestroy(&nafit);
152     }
153     pixWrite("/tmp/lept/textline6.png", pixt1, IFF_PNG);
154     pixDisplayWithTitle(pixt1, 1500, 100, "textline centers 6", 1);
155     pixaAddPix(pixa, pixt1, L_INSERT);
156 
157     pixaConvertToPdf(pixa, 300, 0.5, L_JPEG_ENCODE, 75,
158                      "LS fittings to textlines",
159                      "/tmp/lept/dewarp_fittings.pdf");
160     pixaDestroy(&pixa);
161     pixDestroy(&pixs);
162     ptaaDestroy(&ptaa2);
163     return 0;
164 }
165