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  *  binmorph5_reg.c
29  *
30  *    Regression test for expanded dwa morph operations.
31  *    We compare:
32  *       (1) dwa composite     vs.    morph composite
33  *       (2) dwa composite     vs.    morph non-composite
34  */
35 
36 #include "allheaders.h"
37 
38 void  TestAll(L_REGPARAMS *rp, PIX *pixs, l_int32 symmetric);
39 
40 l_int32 DoComparisonDwa1(L_REGPARAMS *rp,
41                          PIX *pixs, PIX *pix1, PIX *pix2, PIX *pix3,
42                          PIX *pix4, PIX *pix5, PIX *pix6, l_int32 isize);
43 l_int32 DoComparisonDwa2(L_REGPARAMS *rp,
44                          PIX *pixs, PIX *pix1, PIX *pix2, PIX *pix3,
45                          PIX *pix4, PIX *pix5, PIX *pix6, l_int32 size);
46 void PixCompareDwa(L_REGPARAMS *rp,
47                    l_int32 size, const char *type, PIX *pix1, PIX *pix2,
48                    PIX *pix3, PIX *pix4, PIX *pix5, PIX *pix6);
49 
50 #define  TIMING         0
51 #define  FASTER_TEST    1
52 #define  SLOWER_TEST    1
53 
54     /* Note: this fails on the symmetric case when the added border
55      * is 64 pixels, but the differences are relatively small.
56      * Most of the problem seems to be in the non-dwa code, because we
57      * are doing sequential erosions without an extra border, and
58      * things aren't being properly initialized.  To avoid these errors,
59      * add a sufficiently large border for symmetric b.c.  The size of
60      * the border needs to be half the size of the largest SE that is
61      * being used.  Here we test up to size 240, and a border of 128
62      * pixels is sufficient for symmetric b.c.  (For a SE of size 240
63      * with its center in the middle at 120, the maximum translation will
64      * be about 120.)
65      * Note also that asymmetric b.c. are recommended for document image
66      * operations, and this test passes with no added border for
67      * asymmetric b.c. */
68 
main(int argc,char ** argv)69 int main(int    argc,
70          char **argv)
71 {
72 PIX  *pixs;
73 L_REGPARAMS  *rp;
74 
75     if (regTestSetup(argc, argv, &rp))
76         return 1;
77 
78     pixs = pixRead("feyn-fract.tif");
79     TestAll(rp, pixs, FALSE);
80     TestAll(rp, pixs, TRUE);
81     pixDestroy(&pixs);
82     return regTestCleanup(rp);
83 }
84 
85 void
TestAll(L_REGPARAMS * rp,PIX * pixs,l_int32 symmetric)86 TestAll(L_REGPARAMS  *rp,
87         PIX          *pixs,
88         l_int32       symmetric)
89 {
90 l_int32  i, n, rsize, fact1, fact2, extra;
91 l_int32  size, lastsize;
92 l_int32  dwasize[256];
93 l_int32  ropsize[256];
94 PIX     *pix1, *pix2, *pix3, *pix4, *pix5, *pix6;
95 
96     if (symmetric) {
97             /* This works properly with an added border of 128 */
98         resetMorphBoundaryCondition(SYMMETRIC_MORPH_BC);
99         pix1 = pixAddBorder(pixs, 128, 0);
100         pixTransferAllData(pixs, &pix1, 0, 0);
101         fprintf(stderr, "Testing with symmetric boundary conditions\n");
102     } else {
103         resetMorphBoundaryCondition(ASYMMETRIC_MORPH_BC);
104         fprintf(stderr, "Testing with asymmetric boundary conditions\n");
105     }
106 
107     pix1 = pixCreateTemplateNoInit(pixs);
108     pix2 = pixCreateTemplateNoInit(pixs);
109     pix3 = pixCreateTemplateNoInit(pixs);
110     pix4 = pixCreateTemplateNoInit(pixs);
111     pix5 = pixCreateTemplateNoInit(pixs);
112     pix6 = pixCreateTemplateNoInit(pixs);
113 
114     /* ---------------------------------------------------------------- *
115      *                  Faster test; testing fewer sizes                *
116      * ---------------------------------------------------------------- */
117 #if  FASTER_TEST
118         /* Compute the actual sizes used for each input size 'i' */
119     for (i = 0; i < 256; i++) {
120         dwasize[i] = 0;
121         ropsize[i] = 0;
122     }
123     for (i = 65; i < 256; i++) {
124         selectComposableSizes(i, &fact1, &fact2);
125         rsize = fact1 * fact2;
126         ropsize[i] = rsize;
127         getExtendedCompositeParameters(i, &n, &extra, &dwasize[i]);
128     }
129 
130         /* Use only values where the resulting sizes are equal */
131     for (i = 65; i < 240; i++) {
132         n = 1 + (l_int32)((i - 63) / 62);
133         extra = i - 63 - (n - 1) * 62 + 1;
134         if (extra == 2) continue;  /* don't use this one (e.g., i == 126) */
135         if (ropsize[i] == dwasize[i])
136             DoComparisonDwa1(rp, pixs, pix1, pix2, pix3, pix4, pix5, pix6, i);
137     }
138 #endif  /* FASTER_TEST */
139 
140     /* ---------------------------------------------------------------- *
141      *          Slower test; testing maximum number of sizes            *
142      * ---------------------------------------------------------------- */
143 #if  SLOWER_TEST
144     lastsize = 0;
145     for (i = 65; i < 199; i++) {
146         getExtendedCompositeParameters(i, &n, &extra, &size);
147         if (size == lastsize) continue;
148         if (size == 126 || size == 188) continue;  /* deliberately off by one */
149         lastsize = size;
150         DoComparisonDwa2(rp, pixs, pix1, pix2, pix3, pix4, pix5, pix6, size);
151     }
152 #endif  /* SLOWER_TEST */
153 
154     fprintf(stderr, "\n");
155     pixDestroy(&pix1);
156     pixDestroy(&pix2);
157     pixDestroy(&pix3);
158     pixDestroy(&pix4);
159     pixDestroy(&pix5);
160     pixDestroy(&pix6);
161 }
162 
163 
164 l_int32
DoComparisonDwa1(L_REGPARAMS * rp,PIX * pixs,PIX * pix1,PIX * pix2,PIX * pix3,PIX * pix4,PIX * pix5,PIX * pix6,l_int32 isize)165 DoComparisonDwa1(L_REGPARAMS  *rp,
166                  PIX          *pixs,
167                  PIX          *pix1,
168                  PIX          *pix2,
169                  PIX          *pix3,
170                  PIX          *pix4,
171                  PIX          *pix5,
172                  PIX          *pix6,
173                  l_int32       isize)
174 {
175 l_int32   fact1, fact2, size;
176 
177     selectComposableSizes(isize, &fact1, &fact2);
178     size = fact1 * fact2;
179 
180     fprintf(stderr, "..%d..", size);
181 
182     if (TIMING) startTimer();
183     pixDilateCompBrickExtendDwa(pix1, pixs, size, 1);
184     pixDilateCompBrickExtendDwa(pix3, pixs, 1, size);
185     pixDilateCompBrickExtendDwa(pix5, pixs, size, size);
186     if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer());
187     if (TIMING) startTimer();
188     pixDilateCompBrick(pix2, pixs, size, 1);
189     pixDilateCompBrick(pix4, pixs, 1, size);
190     pixDilateCompBrick(pix6, pixs, size, size);
191     if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer());
192     PixCompareDwa(rp, size, "dilate", pix1, pix2, pix3, pix4, pix5, pix6);
193 
194     if (TIMING) startTimer();
195     pixErodeCompBrickExtendDwa(pix1, pixs, size, 1);
196     pixErodeCompBrickExtendDwa(pix3, pixs, 1, size);
197     pixErodeCompBrickExtendDwa(pix5, pixs, size, size);
198     if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer());
199     if (TIMING) startTimer();
200     pixErodeCompBrick(pix2, pixs, size, 1);
201     pixErodeCompBrick(pix4, pixs, 1, size);
202     pixErodeCompBrick(pix6, pixs, size, size);
203     if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer());
204     PixCompareDwa(rp, size, "erode", pix1, pix2, pix3, pix4, pix5, pix6);
205 
206     if (TIMING) startTimer();
207     pixOpenCompBrickExtendDwa(pix1, pixs, size, 1);
208     pixOpenCompBrickExtendDwa(pix3, pixs, 1, size);
209     pixOpenCompBrickExtendDwa(pix5, pixs, size, size);
210     if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer());
211     if (TIMING) startTimer();
212     pixOpenCompBrick(pix2, pixs, size, 1);
213     pixOpenCompBrick(pix4, pixs, 1, size);
214     pixOpenCompBrick(pix6, pixs, size, size);
215     if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer());
216     PixCompareDwa(rp, size, "open", pix1, pix2, pix3, pix4, pix5, pix6);
217 
218     if (TIMING) startTimer();
219     pixCloseCompBrickExtendDwa(pix1, pixs, size, 1);
220     pixCloseCompBrickExtendDwa(pix3, pixs, 1, size);
221     pixCloseCompBrickExtendDwa(pix5, pixs, size, size);
222     if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer());
223     if (TIMING) startTimer();
224     pixCloseSafeCompBrick(pix2, pixs, size, 1);
225     pixCloseSafeCompBrick(pix4, pixs, 1, size);
226     pixCloseSafeCompBrick(pix6, pixs, size, size);
227     if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer());
228     PixCompareDwa(rp, size, "close", pix1, pix2, pix3, pix4, pix5, pix6);
229 
230     return 0;
231 }
232 
233 
234 l_int32
DoComparisonDwa2(L_REGPARAMS * rp,PIX * pixs,PIX * pix1,PIX * pix2,PIX * pix3,PIX * pix4,PIX * pix5,PIX * pix6,l_int32 size)235 DoComparisonDwa2(L_REGPARAMS  *rp,
236                  PIX          *pixs,
237                  PIX          *pix1,
238                  PIX          *pix2,
239                  PIX          *pix3,
240                  PIX          *pix4,
241                  PIX          *pix5,
242                  PIX          *pix6,
243                  l_int32       size)  /* exactly decomposable */
244 {
245     fprintf(stderr, "..%d..", size);
246 
247     if (TIMING) startTimer();
248     pixDilateCompBrickExtendDwa(pix1, pixs, size, 1);
249     pixDilateCompBrickExtendDwa(pix3, pixs, 1, size);
250     pixDilateCompBrickExtendDwa(pix5, pixs, size, size);
251     if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer());
252     if (TIMING) startTimer();
253     pixDilateBrick(pix2, pixs, size, 1);
254     pixDilateBrick(pix4, pixs, 1, size);
255     pixDilateBrick(pix6, pixs, size, size);
256     if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer());
257     PixCompareDwa(rp, size, "dilate", pix1, pix2, pix3, pix4, pix5, pix6);
258 
259     if (TIMING) startTimer();
260     pixErodeCompBrickExtendDwa(pix1, pixs, size, 1);
261     pixErodeCompBrickExtendDwa(pix3, pixs, 1, size);
262     pixErodeCompBrickExtendDwa(pix5, pixs, size, size);
263     if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer());
264     if (TIMING) startTimer();
265     pixErodeBrick(pix2, pixs, size, 1);
266     pixErodeBrick(pix4, pixs, 1, size);
267     pixErodeBrick(pix6, pixs, size, size);
268     if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer());
269     PixCompareDwa(rp, size, "erode", pix1, pix2, pix3, pix4, pix5, pix6);
270 
271     if (TIMING) startTimer();
272     pixOpenCompBrickExtendDwa(pix1, pixs, size, 1);
273     pixOpenCompBrickExtendDwa(pix3, pixs, 1, size);
274     pixOpenCompBrickExtendDwa(pix5, pixs, size, size);
275     if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer());
276     if (TIMING) startTimer();
277     pixOpenBrick(pix2, pixs, size, 1);
278     pixOpenBrick(pix4, pixs, 1, size);
279     pixOpenBrick(pix6, pixs, size, size);
280     if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer());
281     PixCompareDwa(rp, size, "open", pix1, pix2, pix3, pix4, pix5, pix6);
282 
283     if (TIMING) startTimer();
284     pixCloseCompBrickExtendDwa(pix1, pixs, size, 1);
285     pixCloseCompBrickExtendDwa(pix3, pixs, 1, size);
286     pixCloseCompBrickExtendDwa(pix5, pixs, size, size);
287     if (TIMING) fprintf(stderr, "Time Dwa: %7.3f sec\n", stopTimer());
288     if (TIMING) startTimer();
289     pixCloseSafeBrick(pix2, pixs, size, 1);
290     pixCloseSafeBrick(pix4, pixs, 1, size);
291     pixCloseSafeBrick(pix6, pixs, size, size);
292     if (TIMING) fprintf(stderr, "Time Rop: %7.3f sec\n", stopTimer());
293     PixCompareDwa(rp, size, "close", pix1, pix2, pix3, pix4, pix5, pix6);
294 
295     return 0;
296 }
297 
298 
299 void
PixCompareDwa(L_REGPARAMS * rp,l_int32 size,const char * type,PIX * pix1,PIX * pix2,PIX * pix3,PIX * pix4,PIX * pix5,PIX * pix6)300 PixCompareDwa(L_REGPARAMS  *rp,
301               l_int32       size,
302               const char   *type,
303               PIX          *pix1,
304               PIX          *pix2,
305               PIX          *pix3,
306               PIX          *pix4,
307               PIX          *pix5,
308               PIX          *pix6)
309 {
310 l_int32  same;
311 
312     pixEqual(pix1, pix2, &same);
313     regTestCompareValues(rp, TRUE, same, 0);
314     if (!same)
315         fprintf(stderr, "%s (%d, 1) not same\n", type, size);
316     pixEqual(pix3, pix4, &same);
317     regTestCompareValues(rp, TRUE, same, 0);
318     if (!same)
319         fprintf(stderr, "%s (1, %d) not same\n", type, size);
320     pixEqual(pix5, pix6, &same);
321     regTestCompareValues(rp, TRUE, same, 0);
322     if (!same)
323         fprintf(stderr, "%s (%d, %d) not same\n", type, size, size);
324 }
325 
326