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  *  percolatetest.c
29  *
30  *  This tests the code that keeps track of connected components as
31  *  pixels are added (randomly, here) to a pix.
32  */
33 
34 #include "allheaders.h"
35 
36 static PIX *PixDisplayWithColormap(PIX *pixs, l_int32 repl);
37 
38 
main(int argc,char ** argv)39 l_int32 main(int    argc,
40              char **argv)
41 {
42 l_int32  i, x, y, ncc, npta;
43 NUMA    *na1;
44 PIX     *pixs, *pix1, *pix2, *pix3;
45 PIXA    *pixa;
46 PTAA    *ptaa;
47 
48     if (argc != 1) {
49         fprintf(stderr, " Syntax: percolatetest\n");
50         return 1;
51     }
52 
53     setLeptDebugOK(1);
54     lept_mkdir("lept/perc");
55 
56         /* Fill in a tiny pix; 4 connected */
57     pixa = pixaCreate(0);
58     pixs = pixCreate(5, 5, 1);
59     pixConnCompIncrInit(pixs, 4, &pix1, &ptaa, &ncc);
60     fprintf(stderr, "ncc = %d, npta = %d\n", ncc, ptaaGetCount(ptaa));
61     srand(26);
62     for (i = 0; i < 50; i++) {
63         pixGetRandomPixel(pix1, NULL, &x, &y);
64         pixConnCompIncrAdd(pix1, ptaa, &ncc, x, y, 2);
65         npta = ptaaGetCount(ptaa);
66         fprintf(stderr,
67                 "x,y = (%d,%d), num c.c. = %d, num pta = %d\n",
68                 x, y, ncc, npta);
69         pix2 = PixDisplayWithColormap(pix1, 20);
70         pixaAddPix(pixa, pix2, L_INSERT);
71     }
72     pix3 = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2);
73     pixDisplay(pix3, 0, 0);
74     pixWrite("/tmp/lept/perc/file1.png", pix3, IFF_PNG);
75     pixDestroy(&pixs);
76     pixDestroy(&pix1);
77     pixDestroy(&pix3);
78     pixaDestroy(&pixa);
79     ptaaDestroy(&ptaa);
80 
81         /* Fill in a tiny pix; 8 connected */
82     pixa = pixaCreate(0);
83     pixs = pixCreate(5, 5, 1);
84     pixConnCompIncrInit(pixs, 8, &pix1, &ptaa, &ncc);
85     fprintf(stderr, "ncc = %d, npta = %d\n", ncc, ptaaGetCount(ptaa));
86     srand(26);
87     for (i = 0; i < 50; i++) {
88         pixGetRandomPixel(pix1, NULL, &x, &y);
89         pixConnCompIncrAdd(pix1, ptaa, &ncc, x, y, 2);
90         npta = ptaaGetCount(ptaa);
91         fprintf(stderr,
92                 "x,y = (%d,%d), num c.c. = %d, num pta = %d\n",
93                 x, y, ncc, npta);
94         pix2 = PixDisplayWithColormap(pix1, 20);
95         pixaAddPix(pixa, pix2, L_INSERT);
96     }
97     pix3 = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2);
98     pixDisplay(pix3, 0, 560);
99     pixWrite("/tmp/lept/perc/file2.png", pix3, IFF_PNG);
100     pixDestroy(&pixs);
101     pixDestroy(&pix1);
102     pixDestroy(&pix3);
103     pixaDestroy(&pixa);
104     ptaaDestroy(&ptaa);
105 
106         /* Fill in a small pix; 4 connected */
107     na1 = numaCreate(700);
108     pixa = pixaCreate(0);
109     pixs = pixCreate(20, 20, 1);
110     pixConnCompIncrInit(pixs, 4, &pix1, &ptaa, &ncc);
111     fprintf(stderr, "ncc = %d, npta = %d\n", ncc, ptaaGetCount(ptaa));
112     srand(26);
113     for (i = 0; i < 700; i++) {
114         pixGetRandomPixel(pix1, NULL, &x, &y);
115         pixConnCompIncrAdd(pix1, ptaa, &ncc, x, y, 2);
116         numaAddNumber(na1, ncc);
117         npta = ptaaGetCount(ptaa);
118         if (i < 100) {
119             fprintf(stderr,
120                     "x,y = (%d,%d), num c.c. = %d, num pta = %d\n",
121                     x, y, ncc, npta);
122         }
123         if (i % 30 == 1) {
124             pix2 = PixDisplayWithColormap(pix1, 5);
125             pixaAddPix(pixa, pix2, L_INSERT);
126         }
127     }
128     pix3 = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2);
129     pixDisplay(pix3, 0, 0);
130     pixWrite("/tmp/lept/perc/file3.png", pix3, IFF_PNG);
131     gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/plot1",
132                  "Number of components: 4 cc");
133     pixDestroy(&pixs);
134     pixDestroy(&pix1);
135     pixDestroy(&pix3);
136     pixaDestroy(&pixa);
137     ptaaDestroy(&ptaa);
138     numaDestroy(&na1);
139 
140         /* Fill in a small pix; 8 connected */
141     na1 = numaCreate(700);
142     pixa = pixaCreate(0);
143     pixs = pixCreate(20, 20, 1);
144     pixConnCompIncrInit(pixs, 8, &pix1, &ptaa, &ncc);
145     fprintf(stderr, "ncc = %d, npta = %d\n", ncc, ptaaGetCount(ptaa));
146     srand(26);
147     for (i = 0; i < 700; i++) {
148         pixGetRandomPixel(pix1, NULL, &x, &y);
149         pixConnCompIncrAdd(pix1, ptaa, &ncc, x, y, 2);
150         numaAddNumber(na1, ncc);
151         npta = ptaaGetCount(ptaa);
152         if (i < 100) {
153              fprintf(stderr,
154                      "x,y = (%d,%d), num c.c. = %d, num pta = %d\n",
155                      x, y, ncc, npta);
156         }
157         if (i % 30 == 1) {
158             pix2 = PixDisplayWithColormap(pix1, 5);
159             pixaAddPix(pixa, pix2, L_INSERT);
160         }
161     }
162     pix3 = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2);
163     pixDisplay(pix3, 0, 360);
164     pixWrite("/tmp/lept/perc/file4.png", pix3, IFF_PNG);
165     gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/plot2",
166                  "Number of components: 8 cc");
167     pixDestroy(&pixs);
168     pixDestroy(&pix1);
169     pixDestroy(&pix3);
170     pixaDestroy(&pixa);
171     ptaaDestroy(&ptaa);
172     numaDestroy(&na1);
173 
174         /* Fill in a larger pix; 4 connected */
175     pixa = pixaCreate(0);
176     na1 = numaCreate(20000);
177     pixs = pixCreate(195, 56, 1);
178     pixConnCompIncrInit(pixs, 4, &pix1, &ptaa, &ncc);
179     fprintf(stderr, "ncc = %d, npta = %d\n", ncc, ptaaGetCount(ptaa));
180     srand(26);
181     for (i = 0; i < 20000; i++) {
182         pixGetRandomPixel(pix1, NULL, &x, &y);
183         pixConnCompIncrAdd(pix1, ptaa, &ncc, x, y, 3);
184         npta = ptaaGetCount(ptaa);
185         numaAddNumber(na1, ncc);
186         if (i % 500 == 1) {
187             pix2 = PixDisplayWithColormap(pix1, 3);
188             pixaAddPix(pixa, pix2, L_INSERT);
189             fprintf(stderr,
190                     "x,y = (%d,%d), num c.c. = %d, num pta = %d\n",
191                     x, y, ncc, npta);
192         }
193     }
194     pix3 = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2);
195     pixDisplay(pix3, 0, 0);
196     pixWrite("/tmp/lept/perc/file5.png", pix3, IFF_PNG);
197     gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/plot3",
198                  "Number of components: 4 connected");
199     pixDestroy(&pixs);
200     pixDestroy(&pix1);
201     pixDestroy(&pix3);
202     pixaDestroy(&pixa);
203     ptaaDestroy(&ptaa);
204     numaDestroy(&na1);
205 
206         /* Fill in a larger pix; 8 connected */
207     pixa = pixaCreate(0);
208     na1 = numaCreate(20000);
209     pixs = pixCreate(195, 56, 1);
210     pixConnCompIncrInit(pixs, 8, &pix1, &ptaa, &ncc);
211     srand(26);
212     fprintf(stderr, "ncc = %d, npta = %d\n", ncc, ptaaGetCount(ptaa));
213     for (i = 0; i < 20000; i++) {
214         pixGetRandomPixel(pix1, NULL, &x, &y);
215         pixConnCompIncrAdd(pix1, ptaa, &ncc, x, y, 3);
216         npta = ptaaGetCount(ptaa);
217         numaAddNumber(na1, ncc);
218         if (i % 500 == 1) {
219             pix2 = PixDisplayWithColormap(pix1, 3);
220             pixaAddPix(pixa, pix2, L_INSERT);
221             fprintf(stderr,
222                     "x,y = (%d,%d), num c.c. = %d, num pta = %d\n",
223                     x, y, ncc, npta);
224         }
225     }
226     pix3 = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2);
227     pixDisplay(pix3, 340, 0);
228     pixWrite("/tmp/lept/perc/file6.png", pix3, IFF_PNG);
229     gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/plot4",
230                  "Number of components: 8 connected");
231     pixDestroy(&pixs);
232     pixDestroy(&pix1);
233     pixDestroy(&pix3);
234     pixaDestroy(&pixa);
235     ptaaDestroy(&ptaa);
236     numaDestroy(&na1);
237 
238         /* Fill in a larger pix; 8 connected; init with feyn-word.tif */
239     pixa = pixaCreate(0);
240     na1 = numaCreate(20000);
241     pixs = pixRead("feyn-word.tif");
242     pixConnCompIncrInit(pixs, 8, &pix1, &ptaa, &ncc);
243     srand(26);
244     fprintf(stderr, "ncc = %d, npta = %d\n", ncc, ptaaGetCount(ptaa));
245     for (i = 0; i < 20000; i++) {
246         pixGetRandomPixel(pix1, NULL, &x, &y);
247         pixConnCompIncrAdd(pix1, ptaa, &ncc, x, y, 3);
248         npta = ptaaGetCount(ptaa);
249         numaAddNumber(na1, ncc);
250         if (i % 500 == 1) {
251             pix2 = PixDisplayWithColormap(pix1, 3);
252             pixaAddPix(pixa, pix2, L_INSERT);
253             fprintf(stderr,
254                     "x,y = (%d,%d), num c.c. = %d, num pta = %d\n",
255                     x, y, ncc, npta);
256         }
257     }
258     pix3 = pixaDisplayTiledInRows(pixa, 32, 1500, 1.0, 0, 30, 2);
259     pixDisplay(pix3, 0, 0);
260     pixWrite("/tmp/lept/perc/file7.png", pix3, IFF_PNG);
261     gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/plot5",
262                  "Number of components: 8 connected");
263     pixDestroy(&pixs);
264     pixDestroy(&pix1);
265     pixDestroy(&pix3);
266     pixaDestroy(&pixa);
267     ptaaDestroy(&ptaa);
268     numaDestroy(&na1);
269 
270         /* Do 10M pixel adds on an 8M pixel image!
271          * This gets it down to about 385 8-connected components.
272          * With 18.3M pixel adds, you finally arrive at 1 component.
273          * Speed: this does about 1.3M pixel adds/sec.  Most of the time
274          * is used to write the 280MB plot data file and then generate
275          * the plot (percolate-4cc.png, percolate-8cc.png). */
276 #if 0
277     pixs = pixRead("feyn.tif");
278 //    pixs = pixCreate(2500, 3200, 1);
279     na1 = numaCreate(10000000);
280     pixConnCompIncrInit(pixs, 4, &pix1, &ptaa, &ncc);
281     pix2 = PixDisplayWithColormap(pix1, 1);
282     pixDisplay(pix2, 0, 0);
283     pixDestroy(&pix2);
284     fprintf(stderr, "ncc = %d, npta = %d\n", ncc, ptaaGetCount(ptaa));
285     fprintf(stderr, "Now add 10M points: this takes about 7 seconds!\n");
286     for (i = 0; i < 10000000; i++) {
287         pixGetRandomPixel(pix1, NULL, &x, &y);
288         pixConnCompIncrAdd(pix1, ptaa, &ncc, x, y, 0);
289         numaAddNumber(na1, ncc);
290     }
291 
292     fprintf(stderr, "Plot the 10M points: this takes about 20 seconds\n");
293     gplotSimple1(na1, GPLOT_PNG, "/tmp/lept/plot6",
294                  "Number of components: 4 connected, 8 million pixels");
295     pix3 = pixRead("/tmp/lept/plot6.png");
296     pixDisplay(pix3, 500, 0);
297     pixDestroy(&pixs);
298     pixDestroy(&pix1);
299     pixDestroy(&pix3);
300     pixaDestroy(&pixa);
301     ptaaDestroy(&ptaa);
302     numaDestroy(&na1);
303 #endif
304     return 0;
305 }
306 
307 
308     /* This displays a pix where the pixel values are 32 bit labels
309      * using a random colormap whose index is the LSB of each pixel value,
310      * and where white is at index 0. */
311 PIX *
PixDisplayWithColormap(PIX * pixs,l_int32 repl)312 PixDisplayWithColormap(PIX *pixs, l_int32 repl)
313 {
314 PIX      *pix1, *pixd;
315 PIXCMAP  *cmap;
316 
317    cmap = pixcmapCreateRandom(8, 0, 0);
318    pixcmapResetColor(cmap, 0, 255, 255, 255);
319    pix1 = pixConvert32To8(pixs, L_LS_TWO_BYTES, L_LS_BYTE);
320    pixd = pixExpandReplicate(pix1, repl);
321    pixSetColormap(pixd, cmap);
322    pixDestroy(&pix1);
323    return pixd;
324 }
325 
326