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