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  * scaletest2.c
29  *
30  *   Tests scale-to-gray, unsharp masking, smoothing, and color scaling
31  */
32 
33 #include "allheaders.h"
34 
35 #define   DISPLAY      0    /* set to 1 to see the results */
36 
main(int argc,char ** argv)37 int main(int    argc,
38          char **argv)
39 {
40 PIX         *pixs;
41 l_int32      d;
42 static char  mainName[] = "scaletest2";
43 
44     if (argc != 2)
45         return ERROR_INT(" Syntax:  scaletest2 filein", mainName, 1);
46 
47     setLeptDebugOK(1);
48     lept_mkdir("lept/scale");
49 
50     if ((pixs = pixRead(argv[1])) == NULL)
51        	return ERROR_INT("pixs not made", mainName, 1);
52     d = pixGetDepth(pixs);
53 
54 #if 1
55         /* Integer scale-to-gray functions */
56     if (d == 1) {
57         PIX  *pixd;
58 
59         pixd = pixScaleToGray2(pixs);
60         pixWrite("/tmp/lept/scale/s2g_2x", pixd, IFF_PNG);
61         pixDestroy(&pixd);
62         pixd = pixScaleToGray3(pixs);
63         pixWrite("/tmp/lept/scale/s2g_3x", pixd, IFF_PNG);
64         pixDestroy(&pixd);
65         pixd = pixScaleToGray4(pixs);
66         pixWrite("/tmp/lept/scale/s2g_4x", pixd, IFF_PNG);
67         pixDestroy(&pixd);
68         pixd = pixScaleToGray6(pixs);
69         pixWrite("/tmp/lept/scale/s2g_6x", pixd, IFF_PNG);
70         pixDestroy(&pixd);
71         pixd = pixScaleToGray8(pixs);
72         pixWrite("/tmp/lept/scale/s2g_8x", pixd, IFF_PNG);
73         pixDestroy(&pixd);
74         pixd = pixScaleToGray16(pixs);
75         pixWrite("/tmp/lept/scale/s2g_16x", pixd, IFF_PNG);
76         pixDestroy(&pixd);
77     }
78 #endif
79 
80 #if 1
81         /* Various non-integer scale-to-gray, compared with
82 	 * with different ways of getting similar results */
83     if (d == 1) {
84         PIX  *pixt, *pixd;
85 
86         pixd = pixScaleToGray8(pixs);
87         pixWrite("/tmp/lept/scale/s2g_8.png", pixd, IFF_PNG);
88         pixDestroy(&pixd);
89 
90         pixd = pixScaleToGray(pixs, 0.124);
91         pixWrite("/tmp/lept/scale/s2g_124.png", pixd, IFF_PNG);
92         pixDestroy(&pixd);
93 
94         pixd = pixScaleToGray(pixs, 0.284);
95         pixWrite("/tmp/lept/scale/s2g_284.png", pixd, IFF_PNG);
96         pixDestroy(&pixd);
97 
98         pixt = pixScaleToGray4(pixs);
99         pixd = pixScaleBySampling(pixt, 284./250., 284./250.);
100         pixWrite("/tmp/lept/scale/s2g_284.2.png", pixd, IFF_PNG);
101         pixDestroy(&pixt);
102         pixDestroy(&pixd);
103 
104         pixt = pixScaleToGray4(pixs);
105         pixd = pixScaleGrayLI(pixt, 284./250., 284./250.);
106         pixWrite("/tmp/lept/scale/s2g_284.3.png", pixd, IFF_PNG);
107         pixDestroy(&pixt);
108         pixDestroy(&pixd);
109 
110         pixt = pixScaleBinary(pixs, 284./250., 284./250.);
111         pixd = pixScaleToGray4(pixt);
112         pixWrite("/tmp/lept/scale/s2g_284.4.png", pixd, IFF_PNG);
113         pixDestroy(&pixt);
114         pixDestroy(&pixd);
115 
116         pixt = pixScaleToGray4(pixs);
117         pixd = pixScaleGrayLI(pixt, 0.49, 0.49);
118         pixWrite("/tmp/lept/scale/s2g_42.png", pixd, IFF_PNG);
119         pixDestroy(&pixt);
120         pixDestroy(&pixd);
121 
122         pixt = pixScaleToGray4(pixs);
123         pixd = pixScaleSmooth(pixt, 0.49, 0.49);
124         pixWrite("/tmp/lept/scale/s2g_4sm.png", pixd, IFF_PNG);
125         pixDestroy(&pixt);
126         pixDestroy(&pixd);
127 
128         pixt = pixScaleBinary(pixs, .16/.125, .16/.125);
129         pixd = pixScaleToGray8(pixt);
130         pixWrite("/tmp/lept/scale/s2g_16.png", pixd, IFF_PNG);
131         pixDestroy(&pixt);
132         pixDestroy(&pixd);
133 
134         pixd = pixScaleToGray(pixs, .16);
135         pixWrite("/tmp/lept/scale/s2g_16.2.png", pixd, IFF_PNG);
136         pixDestroy(&pixd);
137     }
138 #endif
139 
140 #if 1
141         /* Antialiased (smoothed) reduction, along with sharpening */
142     if (d != 1) {
143         PIX *pixt1, *pixt2;
144 
145         startTimer();
146         pixt1 = pixScaleSmooth(pixs, 0.154, 0.154);
147         fprintf(stderr, "fast scale: %5.3f sec\n", stopTimer());
148         pixDisplayWithTitle(pixt1, 0, 0, "smooth scaling", DISPLAY);
149         pixWrite("/tmp/lept/scale/smooth1.png", pixt1, IFF_PNG);
150         pixt2 = pixUnsharpMasking(pixt1, 1, 0.3);
151         pixWrite("/tmp/lept/scale/smooth2.png", pixt2, IFF_PNG);
152         pixDisplayWithTitle(pixt2, 200, 0, "sharp scaling", DISPLAY);
153         pixDestroy(&pixt1);
154         pixDestroy(&pixt2);
155     }
156 #endif
157 
158 
159 #if 1
160         /* Test a large range of scale-to-gray reductions */
161     if (d == 1) {
162         l_int32    i;
163         l_float32  scale;
164         PIX       *pixd;
165 
166         for (i = 2; i < 15; i++) {
167             scale = 1. / (l_float32)i;
168             startTimer();
169             pixd = pixScaleToGray(pixs, scale);
170             fprintf(stderr, "Time for scale %7.3f: %7.3f sec\n",
171             scale, stopTimer());
172             pixDisplayWithTitle(pixd, 75 * i, 100, "scaletogray", DISPLAY);
173             pixDestroy(&pixd);
174         }
175         for (i = 8; i < 14; i++) {
176             scale = 1. / (l_float32)(2 * i);
177             startTimer();
178             pixd = pixScaleToGray(pixs, scale);
179             fprintf(stderr, "Time for scale %7.3f: %7.3f sec\n",
180             scale, stopTimer());
181             pixDisplayWithTitle(pixd, 100 * i, 600, "scaletogray", DISPLAY);
182             pixDestroy(&pixd);
183         }
184     }
185 #endif
186 
187 
188 #if 1
189         /* Test the same range of scale-to-gray mipmap reductions */
190     if (d == 1) {
191         l_int32    i;
192         l_float32  scale;
193         PIX       *pixd;
194 
195         for (i = 2; i < 15; i++) {
196             scale = 1. / (l_float32)i;
197             startTimer();
198             pixd = pixScaleToGrayMipmap(pixs, scale);
199             fprintf(stderr, "Time for scale %7.3f: %7.3f sec\n",
200             scale, stopTimer());
201             pixDisplayWithTitle(pixd, 75 * i, 100, "scale mipmap", DISPLAY);
202             pixDestroy(&pixd);
203         }
204         for (i = 8; i < 12; i++) {
205             scale = 1. / (l_float32)(2 * i);
206             startTimer();
207             pixd = pixScaleToGrayMipmap(pixs, scale);
208             fprintf(stderr, "Time for scale %7.3f: %7.3f sec\n",
209             scale, stopTimer());
210             pixDisplayWithTitle(pixd, 100 * i, 600, "scale mipmap", DISPLAY);
211             pixDestroy(&pixd);
212         }
213     }
214 #endif
215 
216 #if 1
217         /* Test several methods for antialiased reduction,
218          * along with sharpening */
219     if (d != 1) {
220         PIX *pixt1, *pixt2, *pixt3, *pixt4, *pixt5, *pixt6, *pixt7;
221         l_float32 SCALING = 0.27;
222         l_int32   SIZE = 7;
223         l_int32   smooth;
224         l_float32 FRACT = 1.0;
225 
226         smooth = SIZE / 2;
227 
228         startTimer();
229         pixt1 = pixScaleSmooth(pixs, SCALING, SCALING);
230         fprintf(stderr, "fast scale: %5.3f sec\n", stopTimer());
231         pixDisplayWithTitle(pixt1, 0, 0, "smooth scaling", DISPLAY);
232         pixWrite("/tmp/lept/scale/sm_1.png", pixt1, IFF_PNG);
233         pixt2 = pixUnsharpMasking(pixt1, 1, 0.3);
234         pixDisplayWithTitle(pixt2, 150, 0, "sharpened scaling", DISPLAY);
235 
236         startTimer();
237         pixt3 = pixBlockconv(pixs, smooth, smooth);
238         pixt4 = pixScaleBySampling(pixt3, SCALING, SCALING);
239         fprintf(stderr, "slow scale: %5.3f sec\n", stopTimer());
240         pixDisplayWithTitle(pixt4, 200, 200, "sampled scaling", DISPLAY);
241         pixWrite("/tmp/lept/scale/sm_2.png", pixt4, IFF_PNG);
242 
243         startTimer();
244         pixt5 = pixUnsharpMasking(pixs, smooth, FRACT);
245         pixt6 = pixBlockconv(pixt5, smooth, smooth);
246         pixt7 = pixScaleBySampling(pixt6, SCALING, SCALING);
247         fprintf(stderr, "very slow scale + sharp: %5.3f sec\n", stopTimer());
248         pixDisplayWithTitle(pixt7, 500, 200, "sampled scaling", DISPLAY);
249         pixWrite("/tmp/lept/scale/sm_3.jpg", pixt7, IFF_JFIF_JPEG);
250 
251         pixDestroy(&pixt1);
252         pixDestroy(&pixt2);
253         pixDestroy(&pixt3);
254         pixDestroy(&pixt4);
255         pixDestroy(&pixt5);
256         pixDestroy(&pixt6);
257         pixDestroy(&pixt7);
258     }
259 #endif
260 
261 
262 #if 1
263         /* Test the color scaling function, comparing the
264          * special case of scaling factor 2.0 with the
265          * general case. */
266     if (d == 32) {
267         PIX    *pix1, *pix2, *pixd;
268         NUMA   *nar, *nag, *nab, *naseq;
269         GPLOT  *gplot;
270 
271         startTimer();
272         pix1 = pixScaleColorLI(pixs, 2.00001, 2.0);
273         fprintf(stderr, " Time with regular LI: %7.3f\n", stopTimer());
274         pixWrite("/tmp/lept/scale/color1.jpg", pix1, IFF_JFIF_JPEG);
275         startTimer();
276         pix2 = pixScaleColorLI(pixs, 2.0, 2.0);
277         fprintf(stderr, " Time with 2x LI: %7.3f\n", stopTimer());
278         pixWrite("/tmp/lept/scale/color2.jpg", pix2, IFF_JFIF_JPEG);
279 
280         pixd = pixAbsDifference(pix1, pix2);
281         pixGetColorHistogram(pixd, 1, &nar, &nag, &nab);
282         naseq = numaMakeSequence(0., 1., 256);
283         gplot = gplotCreate("/tmp/lept/scale/c_absdiff", GPLOT_PNG,
284                             "Number vs diff", "diff", "number");
285         gplotSetScaling(gplot, GPLOT_LOG_SCALE_Y);
286         gplotAddPlot(gplot, naseq, nar, GPLOT_POINTS, "red");
287         gplotAddPlot(gplot, naseq, nag, GPLOT_POINTS, "green");
288         gplotAddPlot(gplot, naseq, nab, GPLOT_POINTS, "blue");
289         gplotMakeOutput(gplot);
290         l_fileDisplay("/tmp/lept/scale/c_absdiff.png", 0, 100, 1.0);
291         pixDestroy(&pix1);
292         pixDestroy(&pix2);
293         pixDestroy(&pixd);
294         numaDestroy(&naseq);
295         numaDestroy(&nar);
296         numaDestroy(&nag);
297         numaDestroy(&nab);
298         gplotDestroy(&gplot);
299     }
300 #endif
301 
302 
303 #if 1
304         /* Test the gray LI scaling function, comparing the
305          * special cases of scaling factor 2.0 and 4.0 with the
306          * general case */
307     if (d == 8 || d == 32) {
308         PIX    *pixt, *pix0, *pix1, *pix2, *pixd;
309         NUMA   *nagray, *naseq;
310         GPLOT  *gplot;
311 
312         if (d == 8)
313             pixt = pixClone(pixs);
314         else
315             pixt = pixConvertRGBToGray(pixs, 0.33, 0.34, 0.33);
316         pix0 = pixScaleGrayLI(pixt, 0.5, 0.5);
317 
318 #if 1
319         startTimer();
320         pix1 = pixScaleGrayLI(pix0, 2.00001, 2.0);
321         fprintf(stderr, " Time with regular LI 2x: %7.3f\n", stopTimer());
322         startTimer();
323         pix2 = pixScaleGrayLI(pix0, 2.0, 2.0);
324         fprintf(stderr, " Time with 2x LI: %7.3f\n", stopTimer());
325 #else
326         startTimer();
327         pix1 = pixScaleGrayLI(pix0, 4.00001, 4.0);
328         fprintf(stderr, " Time with regular LI 4x: %7.3f\n", stopTimer());
329         startTimer();
330         pix2 = pixScaleGrayLI(pix0, 4.0, 4.0);
331         fprintf(stderr, " Time with 2x LI: %7.3f\n", stopTimer());
332 #endif
333         pixWrite("/tmp/lept/scale/gray1", pix1, IFF_JFIF_JPEG);
334         pixWrite("/tmp/lept/scale/gray2", pix2, IFF_JFIF_JPEG);
335 
336         pixd = pixAbsDifference(pix1, pix2);
337         nagray = pixGetGrayHistogram(pixd, 1);
338         naseq = numaMakeSequence(0., 1., 256);
339         gplot = gplotCreate("/tmp/lept/scale/g_absdiff", GPLOT_PNG,
340                             "Number vs diff", "diff", "number");
341         gplotSetScaling(gplot, GPLOT_LOG_SCALE_Y);
342         gplotAddPlot(gplot, naseq, nagray, GPLOT_POINTS, "gray");
343         gplotMakeOutput(gplot);
344         l_fileDisplay("/tmp/lept/scale/g_absdiff.png", 750, 100, 1.0);
345         pixDestroy(&pixt);
346         pixDestroy(&pix0);
347         pixDestroy(&pix1);
348         pixDestroy(&pix2);
349         pixDestroy(&pixd);
350         numaDestroy(&naseq);
351         numaDestroy(&nagray);
352         gplotDestroy(&gplot);
353     }
354 #endif
355 
356     pixDestroy(&pixs);
357     return 0;
358 }
359 
360