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 /*
29  * wordboxes_reg.c
30  *
31  *   This tests:
32  *     - functions that make word boxes
33  *     - the function that finds the nearest box to a given box in a boxa
34  */
35 
36 #include "allheaders.h"
37 
38 void MakeWordBoxes1(PIX *pixs, l_float32 scalefact, l_int32 thresh,
39                     l_int32 index, L_REGPARAMS *rp);
40 void MakeWordBoxes2(PIX *pixs, l_float32 scalefact, l_int32 thresh,
41                     L_REGPARAMS  *rp);
42 void TestBoxaAdjacency(PIX *pixs, L_REGPARAMS  *rp);
43 
44 
main(int argc,char ** argv)45 int main(int    argc,
46          char **argv)
47 {
48 PIX          *pix1;
49 L_REGPARAMS  *rp;
50 
51     if (regTestSetup(argc, argv, &rp))
52         return 1;
53 
54 #if 1
55         /* Make word boxes using pixWordMaskByDilation() */
56     pix1 = pixRead("lucasta.150.jpg");
57     MakeWordBoxes1(pix1, 1.0, 140, 0, rp);  /* 0 */
58     MakeWordBoxes1(pix1, 0.6, 140, 1, rp);  /* 1 */
59     pixDestroy(&pix1);
60 #endif
61 
62 #if 1
63     pix1 = pixRead("zanotti-78.jpg");
64     MakeWordBoxes1(pix1, 1.0, 140, 2, rp);  /* 2 */
65     MakeWordBoxes1(pix1, 0.6, 140, 3, rp);  /* 3 */
66     pixDestroy(&pix1);
67 #endif
68 
69 #if 1
70     pix1 = pixRead("words.15.tif");
71     MakeWordBoxes1(pix1, 1.0, 140, 4, rp);  /* 4 */
72     MakeWordBoxes1(pix1, 0.6, 140, 5, rp);  /* 5 */
73     pixDestroy(&pix1);
74 #endif
75 
76 #if 1
77     pix1 = pixRead("words.44.tif");
78     MakeWordBoxes1(pix1, 1.0, 140, 6, rp);  /* 6 */
79     MakeWordBoxes1(pix1, 0.6, 140, 7, rp);  /* 7 */
80     pixDestroy(&pix1);
81 #endif
82 
83 #if 1
84         /* Make word boxes using the higher-level functions
85          * pixGetWordsInTextlines() and pixGetWordBoxesInTextlines() */
86 
87     pix1 = pixRead("lucasta.150.jpg");
88     MakeWordBoxes2(pix1, 0.7, 140, rp);  /* 8, 9 */
89     pixDestroy(&pix1);
90 #endif
91 
92 #if 1
93     pix1 = pixRead("zanotti-78.jpg");
94     MakeWordBoxes2(pix1, 0.7, 140, rp);  /* 10, 11 */
95     pixDestroy(&pix1);
96 #endif
97 
98 #if 1
99         /* Test boxa adjacency function */
100     pix1 = pixRead("lucasta.150.jpg");
101     TestBoxaAdjacency(pix1, rp);  /* 12 - 15 */
102     pixDestroy(&pix1);
103 #endif
104 
105     return regTestCleanup(rp);
106 }
107 
108 void
MakeWordBoxes1(PIX * pixs,l_float32 scalefact,l_int32 thresh,l_int32 index,L_REGPARAMS * rp)109 MakeWordBoxes1(PIX          *pixs,
110                l_float32     scalefact,
111                l_int32       thresh,
112                l_int32       index,
113                L_REGPARAMS  *rp)
114 {
115 BOXA  *boxa1, *boxa2;
116 PIX   *pix1, *pix2, *pix3, *pix4, *pix5;
117 PIXA  *pixa1;
118 
119     pix1 = pixScale(pixs, scalefact, scalefact);
120     pix2 = pixConvertTo1(pix1, thresh);
121     pixa1 = pixaCreate(3);
122     pixWordMaskByDilation(pix2, &pix3, NULL, pixa1);
123     pix4 = NULL;
124     if (pix3) {
125         boxa1 = pixConnComp(pix3, NULL, 8);
126         boxa2 = boxaTransform(boxa1, 0, 0, 1.0/scalefact, 1.0/scalefact);
127         pix4 = pixConvertTo32(pixs);
128         pixRenderBoxaArb(pix4, boxa2, 2, 255, 0, 0);
129         pix5 = pixaDisplayTiledInColumns(pixa1, 1, 1.0, 25, 2);
130         pixDisplayWithTitle(pix5, 200 * index, 0, NULL, rp->display);
131         boxaDestroy(&boxa1);
132         boxaDestroy(&boxa2);
133         pixDestroy(&pix3);
134         pixDestroy(&pix5);
135     }
136     regTestWritePixAndCheck(rp, pix4, IFF_JFIF_JPEG);
137     pixDisplayWithTitle(pix4, 200 * index, 800, NULL, rp->display);
138     pixDestroy(&pix1);
139     pixDestroy(&pix2);
140     pixDestroy(&pix4);
141     pixaDestroy(&pixa1);
142 }
143 
144 void
MakeWordBoxes2(PIX * pixs,l_float32 scalefact,l_int32 thresh,L_REGPARAMS * rp)145 MakeWordBoxes2(PIX          *pixs,
146                l_float32     scalefact,
147                l_int32       thresh,
148                L_REGPARAMS  *rp)
149 {
150 l_int32  default_minwidth = 10;
151 l_int32  default_minheight = 10;
152 l_int32  default_maxwidth = 400;
153 l_int32  default_maxheight = 70;
154 l_int32  minwidth, minheight, maxwidth, maxheight;
155 BOXA    *boxa1, *boxa2;
156 NUMA    *na;
157 PIX     *pix1, *pix2, *pix3, *pix4;
158 PIXA    *pixa;
159 
160     minwidth = scalefact * default_minwidth;
161     minheight = scalefact * default_minheight;
162     maxwidth = scalefact * default_maxwidth;
163     maxheight = scalefact * default_maxheight;
164 
165         /* Get the word boxes */
166     pix1 = pixScale(pixs, scalefact, scalefact);
167     pix2 = pixConvertTo1(pix1, thresh);
168     pixGetWordsInTextlines(pix2, minwidth, minheight,
169                            maxwidth, maxheight, &boxa1, &pixa, &na);
170     pixaDestroy(&pixa);
171     numaDestroy(&na);
172     boxa2 = boxaTransform(boxa1, 0, 0, 1.0 / scalefact, 1.0 / scalefact);
173     pix3 = pixConvertTo32(pixs);
174     pixRenderBoxaArb(pix3, boxa2, 2, 255, 0, 0);
175     regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG);
176     pixDisplayWithTitle(pix3, 900, 0, NULL, rp->display);
177     boxaDestroy(&boxa1);
178     boxaDestroy(&boxa2);
179 
180         /* Do it again with this interface.  The result should be the same. */
181     pixGetWordBoxesInTextlines(pix2, minwidth, minheight,
182                                maxwidth, maxheight, &boxa1, NULL);
183     boxa2 = boxaTransform(boxa1, 0, 0, 1.0 / scalefact, 1.0 / scalefact);
184     pix4 = pixConvertTo32(pixs);
185     pixRenderBoxaArb(pix4, boxa2, 2, 255, 0, 0);
186     if (regTestComparePix(rp, pix3, pix4)) {
187         L_ERROR("pix not the same", "MakeWordBoxes2");
188         pixDisplayWithTitle(pix4, 1200, 0, NULL, rp->display);
189     }
190     pixDestroy(&pix1);
191     pixDestroy(&pix2);
192     pixDestroy(&pix3);
193     pixDestroy(&pix4);
194     boxaDestroy(&boxa1);
195     boxaDestroy(&boxa2);
196 }
197 
198 void
TestBoxaAdjacency(PIX * pixs,L_REGPARAMS * rp)199 TestBoxaAdjacency(PIX          *pixs,
200                   L_REGPARAMS  *rp)
201 {
202 l_int32  i, j, k, n;
203 BOX     *box1, *box2;
204 BOXA    *boxa0, *boxa1, *boxa2;
205 PIX     *pix0, *pix1, *pix2, *pix3;
206 NUMAA   *naai, *naad;
207 
208     pix0 = pixConvertTo1(pixs, 140);
209 
210         /* Make a word mask and remove small components */
211     pixWordMaskByDilation(pix0, &pix1, NULL, NULL);
212     boxa0 = pixConnComp(pix1, NULL, 8);
213     boxa1 = boxaSelectBySize(boxa0, 8, 8, L_SELECT_IF_BOTH,
214                              L_SELECT_IF_GT, NULL);
215     pix2 = pixConvertTo32(pixs);
216     pixRenderBoxaArb(pix2, boxa1, 2, 255, 0, 0);
217     regTestWritePixAndCheck(rp, pix2, IFF_JFIF_JPEG);
218     pixDisplayWithTitle(pix2, 600, 700, NULL, rp->display);
219     pixDestroy(&pix1);
220 
221         /* Find the adjacent boxes and their distances */
222     boxaFindNearestBoxes(boxa1, L_NON_NEGATIVE, 0, &naai, &naad);
223     numaaWrite("/tmp/lept/regout/index.naa", naai);
224     regTestCheckFile(rp, "/tmp/lept/regout/index.naa");
225     numaaWrite("/tmp/lept/regout/dist.naa", naad);
226     regTestCheckFile(rp, "/tmp/lept/regout/dist.naa");
227 
228         /* For a few boxes, show the (up to 4) adjacent boxes */
229     n = boxaGetCount(boxa1);
230     pix3 = pixConvertTo32(pixs);
231     for (i = 10; i < n; i += 25) {
232         box1 = boxaGetBox(boxa1, i, L_COPY);
233         pixRenderBoxArb(pix3, box1, 2, 255, 0, 0);
234         boxa2 = boxaCreate(4);
235         for (j = 0; j < 4; j++) {
236             numaaGetValue(naai, i, j, NULL, &k);
237             if (k >= 0) {
238                 box2 = boxaGetBox(boxa1, k, L_COPY);
239                 boxaAddBox(boxa2, box2, L_INSERT);
240             }
241         }
242         pixRenderBoxaArb(pix3, boxa2, 2, 0, 255, 0);
243         boxDestroy(&box1);
244         boxaDestroy(&boxa2);
245     }
246     regTestWritePixAndCheck(rp, pix3, IFF_JFIF_JPEG);
247     pixDisplayWithTitle(pix3, 1100, 700, NULL, rp->display);
248 
249     pixDestroy(&pix0);
250     pixDestroy(&pix2);
251     pixDestroy(&pix3);
252     boxaDestroy(&boxa0);
253     boxaDestroy(&boxa1);
254     numaaDestroy(&naai);
255     numaaDestroy(&naad);
256 }
257 
258