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  * nearline_reg.c
29  *
30  *   Regression test for finding min or max values (and averages)
31  *   near a specified line.
32  */
33 
34 #include "allheaders.h"
35 
main(int argc,char ** argv)36 l_int32 main(int    argc,
37              char **argv)
38 {
39 l_int32       ret, i, n, similar, x1, y1, val1, val2, val3, val4;
40 l_float32     minave, minave2, maxave, fract;
41 NUMA         *na1, *na2, *na3, *na4, *na5, *na6;
42 NUMAA        *naa;
43 PIX          *pixs, *pix1, *pix2, *pix3, *pix4;
44 L_REGPARAMS  *rp;
45 
46    if (regTestSetup(argc, argv, &rp))
47         return 1;
48 
49     pixs = pixRead("feyn.tif");
50     pix1 = pixScaleToGray6(pixs);
51     pixDisplayWithTitle(pix1, 100, 600, NULL, rp->display);
52 
53         /* Find averages of min and max along about 120 horizontal lines */
54     fprintf(stderr, "Ignore the following 12 error messages:\n");
55     na1 = numaCreate(0);
56     na3 = numaCreate(0);
57     for (y1 = 40; y1 < 575; y1 += 5) {
58         ret = pixMinMaxNearLine(pix1, 20, y1, 400, y1, 5, L_SCAN_BOTH,
59                                 NULL, NULL, &minave, &maxave);
60         if (!ret) {
61             numaAddNumber(na1, (l_int32)minave);
62             numaAddNumber(na3, (l_int32)maxave);
63             if (rp->display)
64                 fprintf(stderr, "y = %d: minave = %d, maxave = %d\n",
65                         y1, (l_int32)minave, (l_int32)maxave);
66         }
67     }
68 
69         /* Find averages along about 120 vertical lines.  We've rotated
70          * the image by 90 degrees, so the results should be nearly
71          * identical to the first set.  Also generate a single-sided
72          * scan (L_SCAN_NEGATIVE) for comparison with the double-sided scans. */
73     pix2 = pixRotateOrth(pix1, 3);
74     pixDisplayWithTitle(pix2, 600, 600, NULL, rp->display);
75     na2 = numaCreate(0);
76     na4 = numaCreate(0);
77     na5 = numaCreate(0);
78     for (x1 = 40; x1 < 575; x1 += 5) {
79         ret = pixMinMaxNearLine(pix2, x1, 20, x1, 400, 5, L_SCAN_BOTH,
80                                 NULL, NULL, &minave, &maxave);
81         pixMinMaxNearLine(pix2, x1, 20, x1, 400, 5, L_SCAN_NEGATIVE,
82                           NULL, NULL, &minave2, NULL);
83         if (!ret) {
84             numaAddNumber(na2, (l_int32)minave);
85             numaAddNumber(na4, (l_int32)maxave);
86             numaAddNumber(na5, (l_int32)minave2);
87             if (rp->display)
88                 fprintf(stderr,
89                         "x = %d: minave = %d, minave2 = %d, maxave = %d\n",
90                         x1, (l_int32)minave, (l_int32)minave2, (l_int32)maxave);
91         }
92     }
93 
94     numaSimilar(na1, na2, 3.0, &similar);  /* should be TRUE */
95     regTestCompareValues(rp, similar, 1, 0);  /* 0 */
96     numaSimilar(na3, na4, 1.0, &similar);  /* should be TRUE */
97     regTestCompareValues(rp, similar, 1, 0);  /* 1 */
98     numaWrite("/tmp/lept/regout/na1.na", na1);
99     numaWrite("/tmp/lept/regout/na2.na", na2);
100     numaWrite("/tmp/lept/regout/na3.na", na3);
101     numaWrite("/tmp/lept/regout/na4.na", na4);
102     numaWrite("/tmp/lept/regout/na5.na", na5);
103     regTestCheckFile(rp, "/tmp/lept/regout/na1.na");  /* 2 */
104     regTestCheckFile(rp, "/tmp/lept/regout/na2.na");  /* 3 */
105     regTestCheckFile(rp, "/tmp/lept/regout/na3.na");  /* 4 */
106     regTestCheckFile(rp, "/tmp/lept/regout/na4.na");  /* 5 */
107     regTestCheckFile(rp, "/tmp/lept/regout/na5.na");  /* 6 */
108 
109         /* Plot the average minimums for the 3 cases */
110     naa = numaaCreate(3);
111     numaaAddNuma(naa, na1, L_INSERT);  /* portrait, double-sided */
112     numaaAddNuma(naa, na2, L_INSERT);  /* landscape, double-sided */
113     numaaAddNuma(naa, na5, L_INSERT);  /* landscape, single-sided */
114     gplotSimpleN(naa, GPLOT_PNG, "/tmp/lept/regout/nearline",
115                  "Average minimums along lines");
116     pix3 = pixRead("/tmp/lept/regout/nearline.png");
117     regTestWritePixAndCheck(rp, pix3, IFF_PNG);  /* 7 */
118     pixDisplayWithTitle(pix3, 100, 100, NULL, rp->display);
119 
120     if (rp->display) {
121         n = numaGetCount(na3);
122         for (i = 0; i < n; i++) {
123             numaGetIValue(na1, i, &val1);
124             numaGetIValue(na2, i, &val2);
125             numaGetIValue(na3, i, &val3);
126             numaGetIValue(na4, i, &val4);
127             fprintf(stderr, "val1 = %d, val2 = %d, diff = %d; "
128                             "val3 = %d, val4 = %d, diff = %d\n",
129                             val1, val2, L_ABS(val1 - val2),
130                             val3, val4, L_ABS(val3 - val4));
131         }
132     }
133 
134     numaaDestroy(&naa);
135     numaDestroy(&na3);
136     numaDestroy(&na4);
137 
138         /* Plot minima along a single line, with different distances */
139     pixMinMaxNearLine(pix1, 20, 200, 400, 200, 2, L_SCAN_BOTH,
140                       &na1, NULL, NULL, NULL);
141     pixMinMaxNearLine(pix1, 20, 200, 400, 200, 5, L_SCAN_BOTH,
142                       &na2, NULL, NULL, NULL);
143     pixMinMaxNearLine(pix1, 20, 200, 400, 200, 15, L_SCAN_BOTH,
144                       &na3, NULL, NULL, NULL);
145     numaWrite("/tmp/lept/regout/na6.na", na1);
146     regTestCheckFile(rp, "/tmp/lept/regout/na6.na");  /* 8 */
147     n = numaGetCount(na1);
148     fract = 100.0 / n;
149     na4 = numaTransform(na1, 0.0, fract);
150     na5 = numaTransform(na2, 0.0, fract);
151     na6 = numaTransform(na3, 0.0, fract);
152     numaDestroy(&na1);
153     numaDestroy(&na2);
154     numaDestroy(&na3);
155     na1 = numaUniformSampling(na4, 100);
156     na2 = numaUniformSampling(na5, 100);
157     na3 = numaUniformSampling(na6, 100);
158     naa = numaaCreate(3);
159     numaaAddNuma(naa, na1, L_INSERT);
160     numaaAddNuma(naa, na2, L_INSERT);
161     numaaAddNuma(naa, na3, L_INSERT);
162     gplotSimpleN(naa, GPLOT_PNG, "/tmp/lept/regout/nearline2",
163                  "Min along line");
164     pix4 = pixRead("/tmp/lept/regout/nearline2.png");
165     regTestWritePixAndCheck(rp, pix4, IFF_PNG);  /* 9 */
166     pixDisplayWithTitle(pix4, 800, 100, NULL, rp->display);
167     numaaDestroy(&naa);
168     numaDestroy(&na4);
169     numaDestroy(&na5);
170     numaDestroy(&na6);
171 
172     pixDestroy(&pix1);
173     pixDestroy(&pix2);
174     pixDestroy(&pix3);
175     pixDestroy(&pix4);
176     pixDestroy(&pixs);
177     return regTestCleanup(rp);
178 }
179 
180